"use client";

import Image from "next/image";
import React, { useCallback, useEffect, useState } from "react";
import axios from "axios";
import { useRouter } from "next/navigation";
import { Heart, Star, Filter } from "lucide-react";
import { useDispatch } from "react-redux";
import { AppDispatch } from "@/redux/store";
import { useSession } from "next-auth/react";
import {
  addItemToBackendCart,
  addItemToCart,
} from "@/redux/slices/cartSlice";
import { toast } from "react-toastify";
import {
  addWishlistItemToBackend,
  fetchWishlistFromBackend,
} from "@/redux/slices/wishlistSlice";
import PriceDisplay from "@/components/ui/formattedPrice";


const Page = ({ params }: { params: { categoryName: string } }) => {
  const router = useRouter();
  const dispatch = useDispatch<AppDispatch>();
  const { data: session } = useSession();

  // Products & pagination
  const [variants, setVariants] = useState<ProductVariant[] | []>([]);
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(10);
  const [total, setTotal] = useState(0);
  const [sort, setSort] = useState("default");

  // Category / filtering meta
  const [categoryCoupons, setCategoryCoupons] = useState<any[]>([]);
  const [commonSpecs, setCommonSpecs] = useState<any[]>([]);
  const [filterSpecs2, setFilterSpecs] = useState<any>();
  const [category, setCategory] = useState<CategoryType | null>(null);

  const [selectedFilters, setSelectedFilters] = useState<{ [key: string]: string[] }>({});
  const [openSections, setOpenSections] = useState<{ [key: string]: boolean }>({});

  const [priceRange, setPriceRange] = useState<[number, number]>([0, 0]);

  const [stockFilter, setStockFilter] = useState<string[]>([]);

  const [minPrice, setMinPrice] = useState(0);
  const [maxPrice, setMaxPrice] = useState(0);


  const [mobileFilterOpen, setMobileFilterOpen] = useState(false);

  const handleCheckbox = (specKey: string, specValue: string) => {
    setSelectedFilters((prev) => {
      const current = prev[specKey] || [];
      if (current.includes(specValue)) {
        const next = current.filter((v) => v !== specValue);
        if (next.length === 0) {
          const { [specKey]: _, ...rest } = prev;
          return { ...rest };
        }
        return { ...prev, [specKey]: next };
      }
      return { ...prev, [specKey]: [...current, specValue] };
    });
  };

  const toggleSection = (key: string) => {
    setOpenSections((prev) => ({
      ...prev,
      [key]: !prev[key],
    }));
  };

  const handleStockCheckbox = (value: string) => {
    setStockFilter((prev) => (prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value]));
  };

  const handlePriceMinChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const val = Number(e.target.value) || 0;
    setPriceRange((prev) => ([prev[0], Math.max(0, Math.min(val, prev[1]))]));
  };

  const handlePriceMaxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const val = Number(e.target.value) || 0;
    setPriceRange((prev) => ([prev[0], Math.max(prev[0], val)]));
  };

  const clearAllFilters = () => {
    setSelectedFilters({});
    setStockFilter([]);
    setPriceRange([minPrice, maxPrice]);
  };


  /**
   * FIXED: fetchProducts no longer updates priceRange every time.
   * It only sets initial based on backend once.
   */
  const fetchProducts = useCallback(async () => {
    try {
      const url = `/api/variants/category/${params.categoryName}?page=${page}&limit=${limit}&sort=${sort}`;

      const payload = {
        filters: {
          ...selectedFilters,
          price: priceRange,
          stock: stockFilter,
        },
      };

      console.log("FETCH PRODUCTS -> payload", payload);

      const response = await axios.post(url, payload)

      if (response.status === 200) {
        setVariants(response.data.mssg?.flat() || []);
        setTotal(response.data.total || 0);

        setCategoryCoupons(response.data.categoryCoupons || []);
        setCommonSpecs(response.data.commonSpecs || []);
        setCategory(response.data.category || null);

        setMinPrice(response.data.minPrice || 0);
        setMaxPrice(response.data.maxPrice || 0);

        // FIX: Only initialize priceRange ONCE.
        setPriceRange((prev) => {
          if (prev[0] === 0 && prev[1] === 0) {
            return [response.data.minPrice, response.data.maxPrice];
          }
          return prev;
        });

        setFilterSpecs(response.data.category?.filters || {});
      }
    } catch (err) {
      console.error("Failed to fetch products", err);
    }
  }, [
    params.categoryName,
    page,
    limit,
    sort,
    priceRange,
    selectedFilters,
    stockFilter
  ]);

  // auto-fetch when dependencies change
  useEffect(() => {
    fetchProducts();
  }, [fetchProducts]);

  // fetch wishlist ONCE only
  useEffect(() => {
    dispatch(fetchWishlistFromBackend());
  }, [dispatch]);

  // initialize filter sections panel
  useEffect(() => {
    if (!filterSpecs2) return;
    const keys = Object.keys(filterSpecs2);
    const initial: { [key: string]: boolean } = {};
    keys.forEach((k) => (initial[k] = true));
    setOpenSections((prev) => ({ ...initial, ...prev }));
  }, [filterSpecs2]);


  const addToCart = (variant: ProductVariant) => {
    if (session?.user.uuid) {
      dispatch(addItemToBackendCart(parseInt(variant.id)));
    } else {
      dispatch(addItemToCart(variant));
    }
    toast.success("Item has been added to cart");
  };

  const addToWishList = async (uuid: string) => {
    if (!session?.user.uuid) {
      toast.error("Please login to add items to wishlist");
      return;
    }
    dispatch(addWishlistItemToBackend(uuid));
  };

  const navigateProductDetailsPage = (uuid: string) => {
    router.push(`/products/${uuid}`);
  };

  const renderStars = useCallback((rating: number) => {
    return Array(5)
      .fill(0)
      .map((_, i) => (
        <Star
          key={i}
          className="h-4 w-4 text-yellow-400"
          fill={i < Math.floor(rating) ? "currentColor" : "none"}
        />
      ));
  }, []);

  const totalPages = Math.ceil(total / limit);


  useEffect(() => {
    const handleResize = () => {
      if (window.innerWidth >= 1050) {
        setMobileFilterOpen(false);
      }
    };

    window.addEventListener("resize", handleResize);

    handleResize();

    return () => window.removeEventListener("resize", handleResize);
  }, []);


  return (
    <div className="flex w-full p-4 bg-gray-50 min-h-screen">

      {/* SIDEBAR */}
      <div
        className={`${mobileFilterOpen ? "flex fixed top-13 left-2 z-50 w-[350px]" : "hidden"} min-[1050px]:flex min-[1050px]:static min-[1050px]:w-1/5 bg-white border rounded-2xl shadow-md p-5 space-y-6 flex-col`}>
        <div className="flex items-center justify-between">
          <h3 className="text-xl font-semibold flex items-center gap-2">
            <Filter className="w-5 h-5 text-primary" />
            Product Filter
          </h3>
          <button
            onClick={clearAllFilters}
            className="text-sm text-gray-500 hover:text-primary"
          >
            Clear
          </button>

          <button
            onClick={() => setMobileFilterOpen(false)}
            className="block max-[1050px]:block min-[1051px]:hidden border p-2 rounded w-[40px] h-[40px]"
          >
            X
          </button>
        </div>

        {/* PRICE RANGE */}
        <div className="w-full flex flex-col pb-4 border-b">
          <h3 className="font-semibold text-gray-800 mb-3 text-sm uppercase">Price Range</h3>

          <div className="flex items-center gap-2">
            <input
              type="number"
              min={0}
              value={priceRange[0]}
              onChange={handlePriceMinChange}
              className="w-1/2 border rounded px-2 py-1 text-sm"
            />
            <span className="text-gray-500">to</span>
            <input
              type="number"
              min={0}
              value={priceRange[1]}
              onChange={handlePriceMaxChange}
              className="w-1/2 border rounded px-2 py-1 text-sm"
            />
          </div>

          <input
            type="range"
            min={0}
            max={maxPrice}
            value={priceRange[1]}
            onChange={(e) => setPriceRange((prev) => [prev[0], Number(e.target.value)])}
            className="accent-primary mt-3 cursor-pointer"
          />

          <div className="flex justify-between mt-2 text-gray-600 text-sm">
            <span>Min: {priceRange[0]} tk</span>
            <span>Max: {priceRange[1]} tk</span>
          </div>
        </div>

        {/* AVAILABILITY */}
        <div className="w-full flex flex-col pb-4 border-b space-y-2">
          <h3 className="font-semibold text-gray-800 mb-1 text-sm uppercase">Availability</h3>

          {[
            { label: "In Stock", value: "in_stock" },
            { label: "Pre Order", value: "pre_order" },
            { label: "Upcoming", value: "upcoming" },
          ].map((item, idx) => (
            <label key={idx} className="flex items-center gap-2 text-gray-700 cursor-pointer">
              <input
                type="checkbox"
                className="accent-primary"
                checked={stockFilter.includes(item.value)}
                onChange={() => handleStockCheckbox(item.value)}
              />
              <span>{item.label}</span>
            </label>
          ))}
        </div>

        {/* DYNAMIC FILTERS */}
        {filterSpecs2 &&
          Object.keys(filterSpecs2).map((specKey: string) => (
            <div key={specKey} className="w-full flex flex-col pb-4 border-b">
              <div
                onClick={() => toggleSection(specKey)}
                className="flex justify-between items-center cursor-pointer mb-2"
              >
                <h3 className="font-semibold text-gray-800 text-sm uppercase">
                  {specKey.split("-")[1]}
                </h3>

                <span className="text-gray-500 text-lg">{openSections[specKey] ? "−" : "+"}</span>
              </div>

              {openSections[specKey] && (
                <div className="space-y-2">
                  {Array.isArray(filterSpecs2[specKey]) &&
                    filterSpecs2[specKey].map((specValue: string, idx: number) => (
                      <label key={idx} className="flex items-center gap-2 text-gray-700 cursor-pointer">
                        <input
                          type="checkbox"
                          className="accent-primary"
                          checked={selectedFilters[specKey]?.includes(specValue) || false}
                          onChange={() => handleCheckbox(specKey, specValue)}
                        />
                        <span>{specValue}</span>
                      </label>
                    ))}
                </div>
              )}
            </div>
          ))}
      </div>

      {/* PRODUCTS SIDE */}
      <div className="flex flex-col flex-1 sm:px-4">

        <div
          className="border rounded-xl bg-white p-3 mb-2 shadow-sm w-full flex flex-row 
          justify-between
           sm:justify-between sm:items-center gap-3">
          {/* Title */}
          <h3 className="sm:text-xl font-semibold text-center sm:text-left">
            Products
          </h3>

          {/* Sort + Total */}
          <div className="flex flex-row sm:flex-row items-center text-sm gap-2 sm:gap-5">

            {/* Sort dropdown */}
            <div className="flex items-center gap-2">
              <span className="text-sm" >Sort by:</span>
              <select
                onChange={(e) => setSort(e.target.value)}
                value={sort}
                className="border rounded-lg px-2 py-1 text-sm shadow-sm w-full sm:w-auto"
              >
                <option value="default">Default</option>
                <option value="lowToHigh">Price (low to high)</option>
                <option value="highToLow">Price (high to low)</option>
              </select>
            </div>

            <div className="block max-[1050px]:block min-[1051px]:hidden">
              <button
                onClick={() => { setMobileFilterOpen(!mobileFilterOpen) }}
                className="
                  flex items-center gap-2
                  px-4 py-2
                  rounded-md
                  bg-gradient-to-r from-amber-500 to-rose-500
                  text-white font-medium
                  shadow-sm
                  border border-white/10
                  active:scale-95
                  transition-all duration-200
                "
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  fill="none"
                  viewBox="0 0 24 24"
                  strokeWidth={1.8}
                  stroke="currentColor"
                  className="w-4 h-4"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M3 4.5h18M6 9.75h12M10 15h4M13 19.5h-2"
                  />
                </svg>

                Filter
              </button>
            </div>



          </div>
        </div>


        {/* PRODUCT GRID */}
        <div className="flex flex-wrap justify-start gap-4">
          {variants &&
            variants.map((variant) => (
              <div
                key={variant.uuid}
                className="relative group border rounded-xl shadow-md bg-white p-3 
             w-full
             md:w-[280px] h-[440px] 
             flex flex-col transition-all hover:shadow-xl hover:-translate-y-1"
              >
                <div
                  onClick={() => navigateProductDetailsPage(variant.uuid)}
                  className="flex h-[200px] cursor-pointer items-center justify-center overflow-hidden rounded-lg bg-gray-100"
                >
                  <Image
                    src={variant?.variant_images?.[0]?.file_url}
                    width={200}
                    height={200}
                    alt="product"
                    className="object-contain h-full transition-transform duration-300 group-hover:scale-105"
                  />
                </div>

                <div className="flex flex-col justify-end flex-1 mt-3">
                  <div className="flex justify-between items-center">
                    <span className="rounded bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-700">
                      {categoryCoupons.length === 0 && "0 coupons available"}
                      {categoryCoupons?.map((coupon) => coupon.code + " ")}
                    </span>

                    <button
                      onClick={() => addToWishList(variant.uuid)}
                      className="rounded-full p-2 text-gray-500 hover:bg-red-100 hover:text-red-500 transition"
                    >
                      <Heart className="h-5 w-5" />
                    </button>
                  </div>

                  <h4
                    onClick={() => navigateProductDetailsPage(variant.uuid)}
                    className="font-semibold mt-2 text-gray-900 hover:text-blue-600 cursor-pointer line-clamp-1"
                  >
                    {variant.name}
                  </h4>

                  <div className="mt-1">
                    <p className="text-sm">
                      Special Price:
                      <span className="text-red-500 font-semibold ml-1">
                        <PriceDisplay price={variant.special_price} />
                      </span>
                    </p>

                    <p className="text-xs text-gray-500 line-through">
                      <PriceDisplay price={variant.regular_price} />
                    </p>
                  </div>

                  <div className="mt-2 flex items-center gap-2">
                    {renderStars(variant.averageRating || 0)}
                    <p className="text-xs text-gray-500">({variant._count?.Review} reviews)</p>
                  </div>

                  {variant.quantity > 0 ? (
                    <button
                      onClick={() => addToCart(variant)}
                      className="mt-auto w-full py-2 px-4 text-white rounded-lg bg-gradient-to-r from-pink-500 to-orange-400 hover:opacity-90 transition font-medium text-sm"
                    >
                      Add to cart
                    </button>
                  ) : (
                    <button
                      disabled
                      className="mt-auto w-full py-2 px-4 text-white bg-gray-400 cursor-not-allowed rounded-lg text-sm"
                    >
                      Out of Stock
                    </button>
                  )}
                </div>
              </div>

            ))}

          {variants.length === 0 && (
            <div className="flex flex-col items-center justify-center w-full mt-20">
              <p className="text-gray-500">No products found in this category.</p>
            </div>
          )}
        </div>

        {/* PAGINATION */}
        {total > 0 && totalPages > 1 && (
          <div className="flex justify-center items-center mt-8 space-x-2">
            <button
              onClick={() => setPage((p) => Math.max(1, p - 1))}
              disabled={page === 1}
              className="px-4 py-2 bg-gray-200 rounded-lg disabled:opacity-50"
            >
              Previous
            </button>

            {Array.from({ length: totalPages }, (_, i) => i + 1).map((num) => (
              <button
                key={num}
                onClick={() => setPage(num)}
                className={`px-4 py-2 rounded-lg text-sm ${page === num ? "bg-blue-500 text-white shadow-md" : "bg-gray-100 hover:bg-gray-200"
                  }`}
              >
                {num}
              </button>
            ))}

            <button
              onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
              disabled={page === totalPages}
              className="px-4 py-2 bg-gray-200 rounded-lg disabled:opacity-50"
            >
              Next
            </button>
          </div>
        )}
      </div>
    </div>
  );
};

export default Page;
