"use client";

import { Suspense, useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import ContactHero from "@/components/ContactHero";
import Footer from "@/components/Footer";
import PageLoading from "@/components/PageLoading";
import ProductListing, { type ProductListingPageSize } from "@/components/ProductListing";
import { getStoredLocale, getStoredLocaleRaw, LOCALE_CHANGE_EVENT } from "@/i18n/localeSwitcher";

function toMarketplacePathSegment(value: unknown): string {
  const raw = String(value ?? "")
    .trim()
    .toLowerCase()
    .replace(/&/g, " and ")
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
  return raw;
}

function isRealCategorySegment(value: string): boolean {
  const t = String(value ?? "").trim();
  return t.length > 0 && t !== "undefined" && t !== "uncategorized";
}

function collectCategoryTreePathSlugs(tree: unknown): string[] {
  const slugs: string[] = [];
  let node: unknown = tree;
  while (node && typeof node === "object" && !Array.isArray(node)) {
    const rec = node as Record<string, unknown>;
    const slug = toMarketplacePathSegment(rec.slug);
    if (isRealCategorySegment(slug)) slugs.push(slug);
    node = rec.sub_category ?? rec.subcategory ?? null;
  }
  return slugs;
}

function marketplaceProductUrlPartsFromApiItem(item: Record<string, unknown>): {
  marketplace_path_segments: string[];
  category_slug: string;
  subcategory_slug: string;
  product_slug: string;
} | null {
  const product_slug = toMarketplacePathSegment(item?.handle ?? item?.slug ?? "");
  if (!product_slug) return null;

  const treeSegments = collectCategoryTreePathSlugs(item?.category_tree);
  if (treeSegments.length > 0) {
    return {
      marketplace_path_segments: treeSegments,
      category_slug: treeSegments[0]!,
      subcategory_slug: treeSegments[1] ?? "",
      product_slug,
    };
  }

  const categoryObj = (item?.category ?? null) as Record<string, unknown> | null;
  const nestedSubcategory = (categoryObj?.subcategory ?? null) as Record<string, unknown> | null;
  const categoryRaw =
    item?.category_slug ??
    item?.category_handle ??
    item?.category_name ??
    item?.category_label ??
    (typeof item?.category === "string" ? item.category : null) ??
    categoryObj?.slug ??
    categoryObj?.handle ??
    categoryObj?.name;
  const subcategoryRaw =
    item?.subcategory_slug ??
    item?.subcategory_handle ??
    item?.subcategory_name ??
    item?.subcategory_label ??
    nestedSubcategory?.slug ??
    nestedSubcategory?.handle ??
    nestedSubcategory?.name;
  const flatSegments = [toMarketplacePathSegment(categoryRaw), toMarketplacePathSegment(subcategoryRaw)].filter(
    isRealCategorySegment,
  );
  if (flatSegments.length > 0) {
    return {
      marketplace_path_segments: flatSegments,
      category_slug: flatSegments[0]!,
      subcategory_slug: flatSegments[1] ?? "",
      product_slug,
    };
  }

  return {
    marketplace_path_segments: [],
    category_slug: "",
    subcategory_slug: "",
    product_slug,
  };
}

type SortOption = { value: string; label: string };

function mapProductCardsSortOptions(data: unknown): SortOption[] {
  const raw = Array.isArray((data as { sort_options?: unknown })?.sort_options)
    ? (data as { sort_options: { type?: string; display_name?: string }[] }).sort_options
    : [];
  return raw
    .map((o) => ({
      value: String(o?.type ?? "").trim(),
      label: String(o?.display_name ?? o?.type ?? "").trim(),
    }))
    .filter((o) => o.value);
}

function SearchContent() {
  const searchParams = useSearchParams();
  const q = searchParams.get("q") ?? "";
  const sortParam = searchParams.get("sort") ?? "";
  const [pageSize, setPageSize] = useState<ProductListingPageSize>(8);
  const [products, setProducts] = useState<any[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [pageData, setPageData] = useState<any>(null);
  const [totalPages, setTotalPages] = useState(1);
  const [currentPage, setCurrentPage] = useState(1);
  const [productsFetchDone, setProductsFetchDone] = useState(false);
  const [cmsLoaded, setCmsLoaded] = useState(false);
  const [sortOptions, setSortOptions] = useState<SortOption[] | undefined>(undefined);

  useEffect(() => {
    let isMounted = true;

    const loadServicesPage = async () => {
      try {
        const xMedusaLocale = (getStoredLocaleRaw() ?? getStoredLocale()).trim();
        const res = await fetch(`${process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL}/store/pages/marketplace`, {
          method: "GET",
          headers: {
            "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_API_KEY || "",
            "x-medusa-locale": xMedusaLocale,
          },
          cache: "no-store",
        });

        if (isMounted && res.ok) {
          setPageData(await res.json());
        }
      } catch {
      } finally {
        if (isMounted) setCmsLoaded(true);
      }
    };

    loadServicesPage();

    const onLocaleChange = () => {
      void loadServicesPage();
    };
    if (typeof window !== "undefined") {
      window.addEventListener(LOCALE_CHANGE_EVENT, onLocaleChange);
    }
    return () => {
      isMounted = false;
      if (typeof window !== "undefined") {
        window.removeEventListener(LOCALE_CHANGE_EVENT, onLocaleChange);
      }
    };
  }, []);
  const sections = pageData?.page?.sections ?? [];
  const findSectionData = (...keys: string[]) => {
    const section = sections.find((s: any) =>
      keys.some((k) => String(s?.key ?? "").toLowerCase().includes(k.toLowerCase()))
    );
    const data = section?.components?.[0]?.instance?.data;
    return data?.items?.[0] ?? data ?? null;
  };

  const bannerData = findSectionData("banner-section");

  const heroTitle = bannerData?.title ?? "";
  const heroDescription = bannerData?.description ?? "";
  const heroBg = bannerData?.bg_image?.items?.[0] ?? {};
  const heroBgMobile =
    heroBg?.image_mobile ?? "";
  const heroBgDesktop =
    heroBg?.image_desktop ?? "";
  const heroBgMobileAlt =
    heroBg?.mobile_image_alt_tag ?? "";
  const heroBgDesktopAlt =
    heroBg?.desktop_image_alt_tag ?? "";

  useEffect(() => {
    let isMounted = true;
    setProductsFetchDone(false);

    const loadProducts = async () => {
      try {
        const base = process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL;
        if (!base) {
          if (isMounted) {
            setProducts([]);
            setTotalCount(0);
            setSortOptions(undefined);
          }
          return;
        }
        const query = new URLSearchParams();
        if (q.trim()) query.set("q", q.trim());
        const sortTrimmed = sortParam.trim();
        if (sortTrimmed) query.set("sort", sortTrimmed);
        const pageForApi = q.trim() ? currentPage : 1;
        query.set("page", String(pageForApi));
        if (pageSize === "all") {
          query.set("limit", "all");
        } else if (pageSize === 16 || pageSize === 32) {
          query.set("limit", String(pageSize));
        } else {
          query.set("limit", "8");
        }
        const res = await fetch(`${base}/store/product-cards?${query.toString()}`, {
          method: "GET",
          headers: {
            "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_API_KEY || "",
          },
          cache: "no-store",
        });
        if (!res.ok) {
          if (isMounted) {
            setProducts([]);
            setTotalCount(0);
            setSortOptions(undefined);
          }
          return;
        }
        const data = await res.json();
        const items = Array.isArray(data?.products) ? data.products : [];
        const total = Number(data?.total ?? 0);
        const limit = Number(data?.limit ?? data?.per_page ?? data?.page_size ?? items.length ?? 0);
        const apiTotalPages = Number(data?.total_pages ?? data?.pages ?? 0);
        const computedTotalPages = limit > 0 ? Math.ceil(total / limit) : 0;
        const resolvedTotalPages = apiTotalPages > 0 ? apiTotalPages : computedTotalPages;
        const shouldShowPagination = limit > 0 ? total > limit : resolvedTotalPages > 1;
        const mapped = items
          .map((item: any) => {
            const parts = marketplaceProductUrlPartsFromApiItem(item as Record<string, unknown>);
            if (!parts) return null;
            return {
              id: item.id ?? item._id ?? item.product_id ?? item.slug ?? "",
              handle: item.handle ?? "",
              marketplace_path_segments: parts.marketplace_path_segments,
              category_slug: parts.category_slug,
              subcategory_slug: parts.subcategory_slug,
              product_slug: parts.product_slug,
              image: item.image ?? "",
              subtitle: item.subtitle ?? "",
              title: item.name ?? "",
              category: item.category_label ?? "",
              location: item.location ?? "",
              available_quantity: item.available_quantity ?? "",
              code: item.code ?? "",
              price_amount: String(item.price_amount ?? ""),
              currency_symbol: item.currency_symbol ?? "",
              inStock: item.availability,
              unit: item.unit ?? "",
            };
          })
          .filter(Boolean);
        if (!isMounted) return;
        setProducts(mapped);
        setTotalCount(total);
        const effectiveTotalPages = shouldShowPagination ? Math.max(1, resolvedTotalPages) : 1;
        setTotalPages(shouldShowPagination ? effectiveTotalPages : 0);
        setCurrentPage(
          shouldShowPagination ? Math.max(1, Math.min(pageForApi, effectiveTotalPages)) : 1
        );
        const nextSort = mapProductCardsSortOptions(data);
        setSortOptions(nextSort.length > 0 ? nextSort : undefined);
      } catch {
        if (!isMounted) return;
        setProducts([]);
        setTotalCount(0);
        setTotalPages(1);
        setSortOptions(undefined);
      } finally {
        if (isMounted) setProductsFetchDone(true);
      }
    };

    loadProducts();
    return () => {
      isMounted = false;
    };
  }, [q, currentPage, sortParam, pageSize]);

  useEffect(() => {
    const parsed = parseInt(searchParams.get("page") ?? "1", 10);
    const page = Number.isFinite(parsed) && parsed >= 1 ? parsed : 1;
    setCurrentPage(q.trim() ? page : 1);
  }, [q, searchParams]);

  if (!cmsLoaded || !productsFetchDone) {
    return <PageLoading />;
  }

  return (
    <div className="relative mx-5 pb-10 sm:mx-10 md:mb-10">
      <ContactHero
        headline={
          <h1 className="font-lexend font-extralight text-[#ffffff] max-w-[782px]">
            {(() => {
              const words = heroTitle.trim().split(/\s+/);
              return (
                <>
                  {words.slice(0, 2).join(" ")}{" "}
                  {words.length > 2 ? (
                    <span className="font-medium">{words.slice(2).join(" ")}</span>
                  ) : null}
                </>
              );
            })()}
          </h1>
        }
        description={heroDescription}
        showSearch
        backgroundImageMobile={heroBgMobile || undefined}
        backgroundImageDesktop={heroBgDesktop || undefined}
        backgroundImageMobileAlt={heroBgMobileAlt || undefined}
        backgroundImageDesktopAlt={heroBgDesktopAlt || undefined}
      />
      <ProductListing
        products={products}
        totalCount={totalCount}
        currentPage={currentPage}
        totalPages={totalPages}
        onPageChange={setCurrentPage}
        pageSize={pageSize}
        onPageSizeChange={setPageSize}
        sortOptions={sortOptions}
        emptyGridMessage={
          productsFetchDone && products.length === 0 ? "No product found" : undefined
        }
        activeSearchQuery={q.trim() || undefined}
      />
      <Footer />
    </div>
  );
}

export default function SearchPage() {
  return (
    <Suspense fallback={<PageLoading />}>
      <SearchContent />
    </Suspense>
  );
}
