"use client";

import { useQuery } from "convex/react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useCallback, useMemo, useState } from "react";
import { api } from "../../../../../convex/_generated/api";
import { ShopBreadcrumbBar } from "@/components/shop/ShopBreadcrumbBar";
import { ShopFilterModal } from "@/components/shop/ShopFilterModal";
import { ShopFilterSidebar } from "@/components/shop/ShopFilterSidebar";
import { ShopPageBanner } from "@/components/shop/ShopPageBanner";
import { ShopProductGrid } from "@/components/shop/ShopProductGrid";
import { ShopToolbar, type SortOption } from "@/components/shop/ShopToolbar";
import { ShopEmptyState } from "@/components/shop/state/ShopEmptyState";
import { ShopErrorState } from "@/components/shop/state/ShopErrorState";
import { ShopProductGridSkeleton } from "@/components/shop/state/ShopProductGridSkeleton";
import { TrustAndCredibilitySection } from "@/components/sections/TrustAndCredibility";
import {
  filterStateFromSearchParams,
  mergeFilterStateIntoSearchParams,
  shopFilterStateToApiArgs,
} from "@/lib/shop/filterState";
import {
  enrichedProductToCardProps,
  type EnrichedProduct,
} from "@/lib/shop/productMapper";

type TagShopPageProps = {
  tag: string;
  title: string;
  subtitle: string;
  breadcrumbLabel: string;
};

const SORT_OPTIONS: SortOption[] = [
  { value: "newest", label: "Newest" },
  { value: "price-asc", label: "Price: Low to High" },
  { value: "price-desc", label: "Price: High to Low" },
];

export function TagShopPage({
  tag,
  title,
  subtitle,
  breadcrumbLabel,
}: TagShopPageProps) {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();

  const filterState = useMemo(
    () => filterStateFromSearchParams(searchParams),
    [searchParams],
  );
  const filterArgs = useMemo(
    () => shopFilterStateToApiArgs(filterState),
    [filterState],
  );

  const [sort, setSort] = useState<string>("newest");
  const [filterModalOpen, setFilterModalOpen] = useState(false);

  const filterOptions = useQuery(api.products.getFilterOptions, { tag });
  const products = useQuery(api.products.listByTag, { tag, ...filterArgs });

  const setFilterStateToUrl = useCallback(
    (state: typeof filterState) => {
      const next = mergeFilterStateIntoSearchParams(
        new URLSearchParams(searchParams.toString()),
        state,
      );
      const q = next.toString();
      router.replace(q ? `${pathname}?${q}` : pathname);
    },
    [pathname, router, searchParams],
  );

  const handleApplyFiltersFromModal = useCallback(
    (state: typeof filterState) => {
      const next = mergeFilterStateIntoSearchParams(
        new URLSearchParams(searchParams.toString()),
        state,
      );
      const q = next.toString();
      router.replace(q ? `${pathname}?${q}` : pathname);
      setFilterModalOpen(false);
    },
    [pathname, router, searchParams],
  );

  const handleApplyFilter = useCallback(() => {
    const next = mergeFilterStateIntoSearchParams(
      new URLSearchParams(searchParams.toString()),
      filterState,
    );
    const q = next.toString();
    router.push(q ? `${pathname}?${q}` : pathname);
    setFilterModalOpen(false);
  }, [router, pathname, searchParams, filterState]);

  const sortedProducts = useMemo(() => {
    if (!products || !Array.isArray(products)) return [];
    const list = [...products] as EnrichedProduct[];
    if (sort === "newest") {
      list.sort((a, b) => (b.createdAt ?? 0) - (a.createdAt ?? 0));
    } else if (sort === "price-asc") {
      list.sort((a, b) => (a.variants?.[0]?.price ?? 0) - (b.variants?.[0]?.price ?? 0));
    } else if (sort === "price-desc") {
      list.sort((a, b) => (b.variants?.[0]?.price ?? 0) - (a.variants?.[0]?.price ?? 0));
    }
    return list;
  }, [products, sort]);

  const handleRetry = useCallback(() => {
    window.location.reload();
  }, []);

  const isLoading = products === undefined;
  const hasError = products === null;
  const isEmpty = Array.isArray(products) && products.length === 0;

  return (
    <main className="mx-auto w-full max-w-7xl min-w-0 px-4 py-6 md:px-6 md:py-8">
      <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
        <ShopBreadcrumbBar
          items={[
            { label: "Home", href: "/" },
            { label: "Shop", href: "/shop" },
            { label: breadcrumbLabel },
          ]}
        />
        <ShopToolbar
          sortOptions={SORT_OPTIONS}
          currentSort={sort}
          onSortChange={setSort}
          onOpenFilter={() => setFilterModalOpen(true)}
          resultCount={Array.isArray(products) ? products.length : undefined}
        />
      </div>

      <ShopPageBanner title={title} subtitle={subtitle} />

      <div className="mt-6 flex flex-col gap-6 lg:flex-row lg:items-start">
        <ShopFilterSidebar
          filterOptions={filterOptions ?? null}
          filterState={filterState}
          onFilterChange={setFilterStateToUrl}
          filterOptionsLoading={filterOptions === undefined}
        />

        <div className="min-w-0 flex-1">
          <div className="mt-6">
            {isLoading ? (
              <ShopProductGridSkeleton />
            ) : hasError ? (
              <ShopErrorState
                message="Failed to load products."
                onRetry={handleRetry}
              />
            ) : isEmpty ? (
              <ShopEmptyState
                title={`No ${title.toLowerCase()} right now`}
                description="Check back soon for new arrivals."
              />
            ) : (
              <ShopProductGrid
                products={sortedProducts.map((p) => ({
                  ...enrichedProductToCardProps(p as EnrichedProduct),
                  id: (p as { _id: string })._id,
                }))}
              />
            )}
            <div className="mt-8">
              <TrustAndCredibilitySection />
            </div>
          </div>
        </div>
      </div>

      <ShopFilterModal
        isOpen={filterModalOpen}
        onClose={() => setFilterModalOpen(false)}
        onApply={handleApplyFilter}
        filterOptions={filterOptions ?? null}
        filterState={filterState}
        onApplyFilters={handleApplyFiltersFromModal}
        filterOptionsLoading={filterOptions === undefined}
      />
    </main>
  );
}
