"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import Newsletter from "@/components/frontend-pages/home/Newsletter";
import { apiCall } from "@/utils/callApi";

import ProductFilter from "./ProductFilter";
import ProductListCard, { ProductListItem } from "./ProductListCard";
import FilterTopBar from "./FilterTopBar";
import SkeletonLoader from "@/components/frontend-pages/home/SkeletonLoader";
import useAuth from "@/hooks/useAuth";
import { toast } from "sonner";
import { useDebounce } from "@/hooks/useDebounce";

export default function ProductsPage() {
  const { clienttotken } = useAuth();
  const [products, setProducts] = useState<ProductListItem[]>([]);
  const [wishListItems, setWishListItems] = useState<ProductListItem[]>([]);
  const [wishlistingId, setWishlistingId] = useState("");
  const [count, setCount] = useState<number>(0);
  const { clientttoken } = useAuth();
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const pageRef = useRef(1);
  const isFetchingRef = useRef(false);
  const loadingRef = useRef<HTMLDivElement | null>(null);
  const [hasMore, setHasMore] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);

  const [loading, setLoading] = useState(true);
  const [filtersLoading, setFiltersLoading] = useState(true);

  const [filters, setFilters] = useState<any>(null);
  const searchParams = useSearchParams();
  const [selectedFilters, setSelectedFilters] = useState({
    category: "" as string,
    subcategory: [] as string[],
    size: [] as string[],
    color: [] as string[],
    ratings: [] as number[],
    price: {
      min: 0,
      max: 0,
    },
    sortBy: "createdAt",
    sortOrder: "desc",
  });
  const priceKey = `${selectedFilters.price.min}-${selectedFilters.price.max}`;
  const debouncedPriceKey = useDebounce(priceKey, 400);
  const [settings, setSettings] = useState(null);

  useEffect(() => {
    setSelectedFilters((prev) => ({
      ...prev,

      category: searchParams.get("category") || "",

      subcategory:
        searchParams.get("subcategory")?.split(",").filter(Boolean) || [],
    }));
  }, [searchParams]);
  const normalizeProduct = (p: any): ProductListItem => {
    const firstSku = p?.skus?.[0];

    const price = p?.price ?? 0;
    const productprice = p?.productprice ?? 0;

    const originalPrice = p?.productprice ?? 0;
    return {
      _id: p._id,
      name: p.name,
      image: p.defaultImage,
      price,
      originalPrice,
      productprice,
      discount: p.discount ?? 0,
      skus: p.skus || [],
      variants: p.variants || [],
      totalQuantity: p.totalQuantity ?? 0,
      totalReviews: p.totalReviews,
      availableColors: p.availableColors || [],
      availableSizes: p.availableSizes || [],
      slug: p.slug,
      wishlisted: false,
    };
  };

  const fetchProducts = useCallback(
    async (pageNum = 1, append = false, currentFilters = selectedFilters) => {
      if (isFetchingRef.current) return;

      isFetchingRef.current = true;

      if (pageNum === 1) setLoading(true);
      else setLoadingMore(true);

      try {
        const query = new URLSearchParams();

        query.append("page", String(pageNum));
        query.append("limit", "6");

        if (currentFilters.category.length)
          query.append("category", currentFilters.category);

        if (currentFilters.subcategory.length)
          query.append("subcategory", currentFilters.subcategory.join(","));

        if (currentFilters.size.length)
          query.append("size", currentFilters.size.join(","));

        if (currentFilters.color.length)
          query.append("color", currentFilters.color.join(","));

        if (currentFilters.ratings.length)
          query.append("ratings", currentFilters.ratings.join(","));

        query.append("minPrice", String(currentFilters.price.min));
        query.append("maxPrice", String(currentFilters.price.max));
        query.append("sortBy", currentFilters.sortBy);
        query.append("sortOrder", currentFilters.sortOrder);

        // Fetch products
        const productRes = (await apiCall(
          `/clientapi/products?${query.toString()}`,
          {
            headers: {
              Authorization: `Bearer ${clientttoken}`,
            },
          },
        )) as any;

        const normalized = productRes.data.data.map(normalizeProduct);

        // Fetch wishlist
        const customerRaw = localStorage.getItem("customer");
        const guestId = localStorage.getItem("guestId");

        const customer = customerRaw ? JSON.parse(customerRaw) : null;
        const userId = customer?.id;

        let wishlistIds = new Set<string>();

        let wishlistUrl = "/clientapi/wishlist?";

        if (userId) {
          wishlistUrl += `user_id=${userId}`;
        } else if (guestId) {
          wishlistUrl += `guest_id=${guestId}`;
        }

        if (userId || guestId) {
          const wishlistRes = await apiCall<any>(wishlistUrl, {
            headers: {
              Authorization: `Bearer ${clientttoken}`,
            },
          });

          if (wishlistRes?.data?.success) {
            setWishListItems(wishlistRes.data.data);
            setCount(wishlistRes.data.count);

            wishlistIds = new Set(
              wishlistRes.data.data.map((item: any) => item.product_id?._id),
            );
          }
        }

        // Add wishlisted flag
        const productsWithWishlist = normalized.map((product: any) => ({
          ...product,
          wishlisted: wishlistIds.has(product._id),
        }));

        if (append) {
          setProducts((prev) => [...prev, ...productsWithWishlist]);
        } else {
          setProducts(productsWithWishlist);
        }
        // console.log('^^^^^^^^P', productsWithWishlist)
        setTotal(productRes.data.total ?? productRes.data.pagination?.total);

        const totalPages = productRes.data.pagination?.pages || 1;
        setHasMore(pageNum < totalPages);
        setPage(pageNum);
        pageRef.current = pageNum;
      } catch (error) {
        console.error(error);
      } finally {
        isFetchingRef.current = false;
        setLoading(false);
        setLoadingMore(false);        
      }
    },
    [selectedFilters, clientttoken],
  );

  const toggleWishlist = async (product: any) => {
    try {
      setWishlistingId(product._id);
      const customerRaw = localStorage.getItem("customer");
      const guestId = localStorage.getItem("guestId");

      const customer = customerRaw ? JSON.parse(customerRaw) : null;

      const payload: any = {
        product_id: product._id,
      };

      if (customer?.id) {
        payload.user_id = customer.id;
      } else if (guestId) {
        payload.guest_id = guestId;
      } else {
        console.log("No user or guest found");
        return;
      }

      const res = await apiCall<any>("/clientapi/wishlist", {
        method: product.wishlisted ? "DELETE" : "POST",
        body: payload,
        headers: {
          Authorization: `Bearer ${clienttotken}`,
        },
      });

      if (res.data?.success) {
        setProducts((prev) =>
          prev.map((p) =>
            p._id === product._id
              ? {
                  ...p,
                  wishlisted: !p.wishlisted,
                }
              : p,
          ),
        );
        toast.success(res.data?.message);
      }

      // console.log("Wishlist toggled:", res);
    } catch (error) {
      console.error("Wishlist toggle error", error);
    } finally {
      setWishlistingId("");
    }
  };

  useEffect(() => {
    const filters = (prev: any) => ({
      category: searchParams.get("category") || "",
      subcategory:
        searchParams.get("subcategory")?.split(",").filter(Boolean) || [],
      size: [],
      color: [],
      ratings: [],

      price: prev.price,
      sortBy: prev.sortBy || "createdAt",
      sortOrder: prev.sortOrder || "desc",
    });

    setSelectedFilters((prev: any) => filters(prev));
    // fetchProducts(1, false, filters); // immediate fetch no stale state
  }, [searchParams]);

  useEffect(() => {
    if (filtersLoading) return;
    pageRef.current = 1;
    setPage(1);
    setHasMore(true);

    fetchProducts(1, false, selectedFilters);
    window.scrollTo({ top: 0, behavior: "smooth" })
  }, [
    filtersLoading,
    debouncedPriceKey,
    selectedFilters.category,
    selectedFilters.subcategory,
    selectedFilters.color,
    selectedFilters.size,
    selectedFilters.sortBy,
    selectedFilters.sortOrder,
    selectedFilters.ratings,
  ]);

  const handleObserver = useCallback(
    (entries: IntersectionObserverEntry[]) => {
      const target = entries[0];

      if (target.isIntersecting && hasMore && !isFetchingRef.current) {
        fetchProducts(pageRef.current + 1, true, selectedFilters);
      }
    },
    [hasMore, fetchProducts, selectedFilters],
  );

  // Handle scrollwise fetching
  useEffect(() => {
    const el = loadingRef.current;
    if (!el) return;

    const observer = new IntersectionObserver(handleObserver, {
      root: null,
      rootMargin: "200px",
      threshold: 0,
    });

    observer.observe(el);

    return () => observer.disconnect();
  }, [handleObserver]);

  const openFilter = () => {
    if (window.innerWidth < 1024) {
      document.body.classList.add("filter-layout");
    }
  };

  const closeFilter = () => {
    document.body.classList.remove("filter-layout");
  };

  const setPrice = (min: number, max: number) => {
    setSelectedFilters((prev) => ({
      ...prev,
      price: { min, max },
    }));
  };

  // Toggle function
  const toggleArrayFilter = (key: string, value: string) => {
    setSelectedFilters((prev: any) => {
      if (key === "category") {
        // radio — deselect if same, select new
        return {
          ...prev,
          category: prev.category === value ? "" : value,
          subcategory: [], // clear subcategories when parent changes
        };
      }

      // checkbox — multi select
      const exists = prev[key].includes(value);
      return {
        ...prev,
        [key]: exists
          ? prev[key].filter((v: string) => v !== value)
          : [...prev[key], value],
      };
    });
  };

  useEffect(() => {
    const raw_data = localStorage.getItem("general-settings");
    if (raw_data) {
      setSettings(JSON.parse(raw_data));
    }

    const handleResize = () => {
      if (window.innerWidth >= 1024) {
        document.body.classList.remove("filter-layout");
      }
    };

    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);

      document.body.classList.remove("filter-layout");
    };
  }, []);

  useEffect(() => {
    const fetchFilters = async () => {
      setFiltersLoading(true);
      try {
        const { data } = await apiCall<any>("/clientapi/products/filters");

        if (data?.data) {
          setFilters(data.data);
          const { minPrice, maxPrice } = data.data || {};
          setSelectedFilters((prev) => ({
            ...prev,
            price: { min: minPrice ?? 0, max: maxPrice ?? 10000 },
          }));
        }
      } catch (err) {
        console.error(err);
      } finally {
        setFiltersLoading(false);
      }
    };

    fetchFilters();
  }, []);

  const selectedCategory = filters?.categories?.find(
    (cat: any) => cat.slug === selectedFilters.category,
  );

  const selectedSubcategories = selectedCategory
    ? (selectedFilters.subcategory || [])
        .map((slug: string) =>
          filters?.subcategories?.find((sub: any) => sub.slug === slug),
        )
        .filter(Boolean)
    : [];

  const buildCategoryLink = () => {
    if (!selectedCategory) return "/products";
    return `/products?category=${selectedCategory.slug}`;
  };

  const buildSubcategoryLink = (index: number) => {
    if (!selectedCategory) return "/products";

    const subSlugs = selectedSubcategories
      .slice(0, index + 1)
      .map((sub: any) => sub.slug)
      .join(",");

    return `/products?category=${selectedCategory.slug}&subcategory=${subSlugs}`;
  };

  return (
    <div className="font-montserrat">
      {filtersLoading ? (
        <SkeletonLoader />
      ) : (
        <main>
          {/* Breadcrumb */}

          <section className="breadcrumbcontainer">
            <div className="container px-3">
              <ol className="breadcrumb">
                <li>
                  <Link href="/">Home</Link>
                </li>

                {!selectedCategory && selectedSubcategories.length === 0 ? (
                  <li className="active">Products</li>
                ) : (
                  <li>
                    <Link href="/products">Products</Link>
                  </li>
                )}

                {selectedCategory && (
                  <li>
                    <Link href={buildCategoryLink()}>
                      {selectedCategory.name}
                    </Link>
                  </li>
                )}

                {selectedSubcategories.map((sub: any, index: number) => (
                  <li key={sub._id}>
                    <Link href={buildSubcategoryLink(index)}>{sub.name}</Link>
                  </li>
                ))}
              </ol>
            </div>
          </section>

          {/* Overlay */}

          <div className="filter-ovarlay" onClick={closeFilter} />

          {/* Product List */}

          <section className="productlistcontainer">
            <div className="productinner">
              <div className="container px-3">
                <div className="-mx-3 flex flex-wrap xl:-mx-6 2xl:-mx-12">
                  {/* FILTER COLUMN */}
                  <div className="filtercolumn xxl:w-1/4 w-full px-3 lg:w-1/4 xl:w-1/4 xl:px-6 2xl:px-12">
                    {/* Mobile Filter Button */}
                    <a
                      className="filtetbtn"
                      onClick={openFilter}
                      style={{ cursor: "pointer" }}
                    >
                      <svg
                        xmlns="http://www.w3.org/2000/svg"
                        fill="currentColor"
                        viewBox="0 0 16 16"
                      >
                        <path
                          fillRule="evenodd"
                          d="M10.5 1a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0V4H1.5a.5.5 0 0 1 0-1H10V1.5a.5.5 0 0 1 .5-.5M12 3.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5m-6.5 2A.5.5 0 0 1 6 6v1.5h8.5a.5.5 0 0 1 0 1H6V10a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5M1 8a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2A.5.5 0 0 1 1 8m9.5 2a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0V13H1.5a.5.5 0 0 1 0-1H10v-1.5a.5.5 0 0 1 .5-.5m1.5 2.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5"
                        />
                      </svg>
                    </a>

                    {/* FILTER */}

                    <ProductFilter
                      onClose={closeFilter}
                      filters={filters}
                      selectedFilters={selectedFilters}
                      onToggle={toggleArrayFilter}
                      onPriceChange={setPrice}
                    />
                  </div>

                  {/* PRODUCTS */}

                  <div className="xxl:w-3/4 w-full px-3 lg:w-3/4 xl:w-3/4 xl:px-6 2xl:px-12">
                    <FilterTopBar
                      total={total}
                      showing={products.length}
                      onSortChange={(opt: any) => {
                        setSelectedFilters((prev) => ({
                          ...prev,
                          sortBy: opt.sortBy,
                          sortOrder: opt.sortOrder,
                        }));
                      }}
                      onFilterOpen={openFilter}
                      sortOptions={filters?.sortOptions || []}
                    />

                    {loading ? (
                      <div className="-mx-1 flex flex-wrap sm:-mx-2">
                        {[1, 2, 3, 4, 5, 6].map((i) => (
                          <div
                            key={i}
                            className="mb-8 w-1/2 px-2 sm:w-1/2 md:w-1/3 xl:w-1/3"
                          >
                            <div
                              style={{
                                height: 380,
                                background:
                                  "linear-gradient(90deg,#f0f0f0 25%,#e8e8e8 50%,#f0f0f0 75%)",
                                backgroundSize: "600px 100%",
                                animation: "shimmer 1.5s infinite linear",
                                borderRadius: 8,
                              }}
                            />
                          </div>
                        ))}
                      </div>
                    ) : (
                      <div className="-mx-1 flex flex-wrap sm:-mx-2 2xl:-mx-3">
                        {products?.length > 0 && !loading ? (
                          products?.map((product) => (
                            <div
                              key={product._id}
                              className="xxl:w-1/3 mb-4 w-1/2 px-1 sm:mb-5 sm:w-1/2 sm:px-2 md:w-1/3 lg:mb-8 lg:w-1/3 xl:w-1/3 2xl:px-3"
                            >
                              <ProductListCard
                                product={product}
                                onWishListToggle={toggleWishlist}
                                wishlistingId={wishlistingId}
                              />
                            </div>
                          ))
                        ) : (
                          <div className="flex w-full items-center justify-center py-20">
                            <div className="text-center">
                              <svg
                                xmlns="http://www.w3.org/2000/svg"
                                viewBox="0 0 24 24"
                                fill="none"
                                stroke="currentColor"
                                strokeWidth="2"
                                className="mx-auto mb-3 h-12 w-12 text-gray-400"
                              >
                                <circle cx="9" cy="21" r="1" />
                                <circle cx="20" cy="21" r="1" />
                                <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6" />
                              </svg>
                              <h2 className="text-lg font-semibold text-gray-700">
                                No products found
                              </h2>
                              <p className="mt-1 text-sm text-gray-500">
                                Try changing filters
                              </p>
                            </div>
                          </div>
                        )}

                        {loadingMore &&
                          [1, 2, 3].map((i) => (
                            <div
                              key={`loading-${i}`}
                              className="xxl:w-1/3 mb-4 w-1/2 px-1 sm:mb-5 sm:w-1/2 sm:px-2 md:w-1/3 lg:mb-8 lg:w-1/3 xl:w-1/3 2xl:px-3"
                            >
                              <div className="product-skeleton" />
                            </div>
                          ))}
                      </div>
                    )}

                    {/* LOAD MORE ON SCROLL */}
                    {loadingMore && (
                      <div className="flex w-full flex-col items-center justify-center gap-1 py-0">
                        <div className="relative h-11 w-11">
                          <div className="absolute inset-0 rounded-full border-2 border-gray-200"></div>
                          <div className="absolute inset-0 animate-spin rounded-full border-2 border-b-transparent border-l-transparent border-r-transparent border-t-black"></div>
                        </div>
                        <p>Loading...</p>
                      </div>
                    )}

                    {/* Ref node for trigger scroll */}
                    <div ref={loadingRef} className="h-1 w-full" />
                  </div>
                </div>
              </div>
            </div>
          </section>

          <Newsletter settings={settings} />
        </main>
      )}
    </div>
  );
}
