"use client";

import { useQuery } from "convex/react";
import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useMemo, useState } from "react";
import { api } from "../../../../../convex/_generated/api";
import { ShopBreadcrumbBar } from "@/components/shop/ShopBreadcrumbBar";
import { ShopCategoryStrip } from "@/components/shop/ShopCategoryStrip";
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 {
  PET_CATEGORY_SLUGS,
  TOP_CATEGORY_SLUGS,
  type PetCategorySlug,
  type TopCategorySlug,
} from "@/lib/shop/constants";
import {
  filterStateFromSearchParams,
  mergeFilterStateIntoSearchParams,
  shopFilterStateToApiArgs,
} from "@/lib/shop/filterState";
import {
  enrichedProductToCardProps,
  type EnrichedProduct,
} from "@/lib/shop/productMapper";

const DEFAULT_PET: PetCategorySlug = "dogs";

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

function formatTopCategoryLabel(slug: string): string {
  return slug.charAt(0).toUpperCase() + slug.slice(1);
}

function formatPetLabel(slug: string): string {
  if (slug === "other-pets") return "Other Pets";
  return slug.charAt(0).toUpperCase() + slug.slice(1);
}

function parsePetFromSearchParams(searchParams: URLSearchParams): PetCategorySlug {
  const pet = searchParams.get("pet");
  if (pet && (PET_CATEGORY_SLUGS as readonly string[]).includes(pet)) {
    return pet as PetCategorySlug;
  }
  return DEFAULT_PET;
}

export function TopCategoryPage({ slug }: { slug: TopCategorySlug }) {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const pet = parsePetFromSearchParams(searchParams);

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

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

  useEffect(() => {
    if (filterModalOpen) setPendingPet(pet);
  }, [filterModalOpen, pet]);

  const filterOptions = useQuery(api.products.getFilterOptions, {
    topCategorySlug: slug,
    petCategorySlug: pet,
  });
  const products = useQuery(api.products.listByTopCategory, {
    topCategorySlug: slug,
    petCategorySlug: pet,
    ...filterArgs,
  });

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

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

  const stripLinks = useMemo(() => {
    return TOP_CATEGORY_SLUGS.filter((s) => s !== slug).map((s) => ({
      label: formatTopCategoryLabel(s),
      href: `/shop/${s}`,
    }));
  }, [slug]);

  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) => {
        const pa = a.variants?.[0]?.price ?? 0;
        const pb = b.variants?.[0]?.price ?? 0;
        return pa - pb;
      });
    } else if (sort === "price-desc") {
      list.sort((a, b) => {
        const pa = a.variants?.[0]?.price ?? 0;
        const pb = b.variants?.[0]?.price ?? 0;
        return pb - pa;
      });
    }
    return list;
  }, [products, sort]);

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

  const currentPath = `/shop/${slug}`;
  const isLoading = products === undefined;
  const hasError = products === null;
  const isEmpty = Array.isArray(products) && products.length === 0;

  const renderSidebarPetFilter = () => (
    <>
      <p className="text-sm font-medium text-[var(--foreground)]">Filter by pet</p>
      <ul className="mt-2 space-y-1">
        {PET_CATEGORY_SLUGS.map((petSlug) => {
          const params = new URLSearchParams(searchParams.toString());
          params.set("pet", petSlug);
          const href = `${currentPath}?${params.toString()}`;
          const isActive = petSlug === pet;
          return (
            <li key={petSlug}>
              <Link
                href={href}
                className={`block rounded py-1 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--accent)] ${
                  isActive
                    ? "font-medium text-[var(--foreground)]"
                    : "text-[var(--muted)] hover:text-[var(--foreground)]"
                }`}
              >
                {formatPetLabel(petSlug)}
              </Link>
            </li>
          );
        })}
      </ul>
    </>
  );

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

  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: formatTopCategoryLabel(slug) },
          ]}
        />
        <ShopToolbar
          sortOptions={SORT_OPTIONS}
          currentSort={sort}
          onSortChange={setSort}
          onOpenFilter={() => setFilterModalOpen(true)}
          resultCount={Array.isArray(products) ? products.length : undefined}
        />
      </div>

      <ShopPageBanner
        title={formatTopCategoryLabel(slug)}
        subtitle={`Shop ${formatTopCategoryLabel(slug).toLowerCase()} for your pet`}
      />

      <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}
        >
          {renderSidebarPetFilter()}
        </ShopFilterSidebar>

        <div className="min-w-0 flex-1">
          {stripLinks.length > 0 && <ShopCategoryStrip links={stripLinks} />}

          <div className="mt-6">
            {isLoading ? (
              <ShopProductGridSkeleton />
            ) : hasError ? (
              <ShopErrorState
                message="Failed to load products."
                onRetry={handleRetry}
              />
            ) : isEmpty ? (
              <ShopEmptyState
                title="No products in this category"
                description={`No ${formatTopCategoryLabel(slug).toLowerCase()} found for ${formatPetLabel(pet)}. Try another pet filter.`}
              />
            ) : (
              <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}
      >
        <p className="text-sm font-medium text-[var(--foreground)]">Filter by pet</p>
        <ul className="mt-2 space-y-1" role="listbox" aria-label="Pet">
          {PET_CATEGORY_SLUGS.map((petSlug) => {
            const isActive = petSlug === pendingPet;
            return (
              <li key={petSlug}>
                <button
                  type="button"
                  role="option"
                  aria-selected={isActive}
                  className={`block w-full rounded py-2 text-left text-sm focus:outline-none focus:ring-2 focus:ring-[var(--accent)] ${
                    isActive
                      ? "font-medium text-[var(--foreground)]"
                      : "text-[var(--muted)] hover:text-[var(--foreground)]"
                  }`}
                  onClick={() => setPendingPet(petSlug as PetCategorySlug)}
                >
                  {formatPetLabel(petSlug)}
                </button>
              </li>
            );
          })}
        </ul>
      </ShopFilterModal>
    </main>
  );
}
