"use client";

import { useEffect, useMemo, useState, type ReactNode } from "react";
import { useParams } from "next/navigation";
import api from "@/lib/api";
import ProductCard from "@/components/ProductCard";
import {
  ChevronDown,
  ChevronRight,
  Filter,
  Search,
  SlidersHorizontal,
  X,
  Sparkles,
  RotateCcw,
} from "lucide-react";

interface Product {
  id: number;
  name: string;
  slug: string;
  price: string;
  sale_price?: string | null;
  image?: string | null;
  stock_quantity?: number;
  stock_status?: string;
  is_featured?: boolean;
  category?: {
    id: number;
    name: string;
    slug: string;
  } | null;
  brand?: {
    id: number;
    name: string;
    slug: string;
  } | null;
  unit_type?: string;
  unit_value?: string;
}

interface Category {
  id: number;
  parent_id?: number | string | null;
  name: string;
  slug?: string;
}

const PRICE_MIN = 0;
const PRICE_MAX = 10000;
const PRICE_STEP = 1;

export default function ProductsPage() {
  const params = useParams();

  const categorySlug =
    typeof params?.slug === "string" ? params.slug : undefined;

  const [ignoreRouteCategory, setIgnoreRouteCategory] = useState(false);

  const [products, setProducts] = useState<Product[]>([]);
  const [categories, setCategories] = useState<Category[]>([]);

  const [search, setSearch] = useState("");
  const [selectedCategory, setSelectedCategory] = useState("");
  const [openCategoryIds, setOpenCategoryIds] = useState<number[]>([]);

  const [minPrice, setMinPrice] = useState(PRICE_MIN);
  const [maxPrice, setMaxPrice] = useState(PRICE_MAX);

  const [appliedMinPrice, setAppliedMinPrice] = useState(PRICE_MIN);
  const [appliedMaxPrice, setAppliedMaxPrice] = useState(PRICE_MAX);

  const [initialLoading, setInitialLoading] = useState(true);

  const [sort, setSort] = useState("");
  const [loading, setLoading] = useState(true);
  const [mobileFilterOpen, setMobileFilterOpen] = useState(false);

  useEffect(() => {
    fetchCategories();
  }, []);

  useEffect(() => {
    const timer = setTimeout(() => {
      setAppliedMinPrice(minPrice);
      setAppliedMaxPrice(maxPrice);
    }, 400);

    return () => clearTimeout(timer);
  }, [minPrice, maxPrice]);

  useEffect(() => {
    fetchProducts();
  }, [
    categorySlug,
    selectedCategory,
    ignoreRouteCategory,
    search,
    appliedMinPrice,
    appliedMaxPrice,
    sort,
  ]);

  const activeFilterCategory = ignoreRouteCategory
    ? ""
    : selectedCategory || categorySlug || "";

  const fetchProducts = async () => {
    try {
      if (initialLoading) {
        setLoading(true);
      }

      const res = await api.get("/products", {
        params: {
          category: activeFilterCategory,
          search,
          min_price: appliedMinPrice,
          max_price: appliedMaxPrice,
          sort,
        },
      });

      setProducts(res.data.data || []);
    } catch (error) {
      console.error(error);
    } finally {
      setLoading(false);
      setInitialLoading(false);
    }
  };

  const fetchCategories = async () => {
    try {
      const res = await api.get("/categories");
      setCategories(res.data.data || []);
    } catch (error) {
      console.error(error);
    }
  };

  const activeCategory = useMemo(() => {
    if (!activeFilterCategory) return null;

    return categories.find(
      (item) => String(item.slug || item.id) === String(activeFilterCategory)
    );
  }, [categories, activeFilterCategory]);

  const pageTitle = activeCategory
    ? `${activeCategory.name} Products`
    : "All Products";

  const pageSubtitle = activeCategory
    ? `Explore fresh and quality products from ${activeCategory.name}.`
    : "Discover fresh groceries, daily essentials, and premium products.";

  const parentCategories = useMemo(() => {
    return categories.filter(
      (item) =>
        item.parent_id === null ||
        item.parent_id === undefined ||
        item.parent_id === "" ||
        Number(item.parent_id) === 0
    );
  }, [categories]);

  const getChildren = (parentId: number) => {
    return categories.filter((item) => Number(item.parent_id) === parentId);
  };

  const toggleCategoryOpen = (id: number) => {
    setOpenCategoryIds((prev) =>
      prev.includes(id)
        ? prev.filter((item) => item !== id)
        : [...prev, id]
    );
  };

  const clearFilters = () => {
    setSearch("");
    setSelectedCategory("");
    setOpenCategoryIds([]);
    setIgnoreRouteCategory(true);

    setMinPrice(PRICE_MIN);
    setMaxPrice(PRICE_MAX);

    setAppliedMinPrice(PRICE_MIN);
    setAppliedMaxPrice(PRICE_MAX);

    setSort("");
  };

  const selectedRangeLeft = (minPrice / PRICE_MAX) * 100;
  const selectedRangeRight = 100 - (maxPrice / PRICE_MAX) * 100;

  const CategoryFilterItem = ({
    category,
    level = 0,
  }: {
    category: Category;
    level?: number;
  }) => {
    const children = getChildren(category.id);
    const hasChildren = children.length > 0;
    const isOpen = openCategoryIds.includes(category.id);

    const value = String(category.slug || category.id);

    const isActive =
      !ignoreRouteCategory &&
      (selectedCategory === value ||
        (!selectedCategory && categorySlug === value));

    return (
      <div>
        <div
          className={`group flex items-center gap-2 rounded-2xl px-3 py-2.5 transition ${
            isActive
              ? "bg-gradient-to-r from-green-600 to-emerald-500 text-white shadow-lg shadow-green-200"
              : "text-slate-700 hover:bg-green-50"
          }`}
          style={{ paddingLeft: `${12 + level * 16}px` }}
        >
          {hasChildren ? (
            <button
              type="button"
              onClick={() => toggleCategoryOpen(category.id)}
              className={`flex h-7 w-7 shrink-0 items-center justify-center rounded-full transition ${
                isActive
                  ? "bg-white/20"
                  : "bg-white text-slate-500 shadow-sm group-hover:text-green-600"
              }`}
            >
              {isOpen ? <ChevronDown size={15} /> : <ChevronRight size={15} />}
            </button>
          ) : (
            <span className="h-7 w-7 shrink-0" />
          )}

          <button
            type="button"
            onClick={() => {
              setSelectedCategory(value);
              setIgnoreRouteCategory(false);
            }}
            className="flex-1 text-left text-sm font-black line-clamp-1"
          >
            {category.name}
          </button>
        </div>

        {hasChildren && isOpen && (
          <div className="mt-1 space-y-1">
            {children.map((child) => (
              <CategoryFilterItem
                key={child.id}
                category={child}
                level={level + 1}
              />
            ))}
          </div>
        )}
      </div>
    );
  };

  const FilterContent = () => {
    return (
      <div className="space-y-6">
        <div className="rounded-[26px] border border-slate-100 bg-white p-4 shadow-sm">
          <Label>Search Products</Label>

          <div className="relative">
            <Search
              size={18}
              className="absolute left-4 top-1/2 -translate-y-1/2 text-slate-400"
            />

            <input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search products..."
              className="h-12 w-full rounded-2xl border border-slate-200 bg-slate-50 pl-11 pr-4 text-sm font-bold text-slate-800 outline-none transition focus:border-green-500 focus:bg-white focus:ring-4 focus:ring-green-100"
            />
          </div>
        </div>

        <div className="rounded-[26px] border border-slate-100 bg-white p-4 shadow-sm">
          <Label>Categories</Label>

          <div className="max-h-[330px] space-y-1 overflow-y-auto rounded-3xl bg-slate-50 p-2">
            <button
              type="button"
              onClick={() => {
                setSelectedCategory("");
                setOpenCategoryIds([]);
                setIgnoreRouteCategory(true);
              }}
              className={`mb-2 flex w-full items-center justify-between rounded-2xl px-4 py-3 text-left text-sm font-black transition ${
                ignoreRouteCategory || (!selectedCategory && !categorySlug)
                  ? "bg-gradient-to-r from-green-600 to-emerald-500 text-white shadow-lg shadow-green-200"
                  : "bg-white text-slate-700 hover:bg-green-50"
              }`}
            >
              All Categories
              <Sparkles size={15} />
            </button>

            {parentCategories.map((category) => (
              <CategoryFilterItem key={category.id} category={category} />
            ))}
          </div>
        </div>

        <div className="rounded-[26px] border border-slate-100 bg-white p-4 shadow-sm">
          <Label>Price Range</Label>

          <div className="rounded-[24px] bg-gradient-to-br from-slate-50 to-green-50 p-4">
            <div className="relative h-9">
              <div className="pointer-events-none absolute left-0 right-0 top-1/2 h-2 -translate-y-1/2 rounded-full bg-slate-200">
                <div
                  className="absolute h-2 rounded-full bg-gradient-to-r from-green-600 to-emerald-400"
                  style={{
                    left: `${selectedRangeLeft}%`,
                    right: `${selectedRangeRight}%`,
                  }}
                />
              </div>

              <input
                type="range"
                min={PRICE_MIN}
                max={PRICE_MAX}
                step={1}
                value={minPrice}
                onChange={(e) => {
                  const value = Number(e.target.value);
                  setMinPrice(Math.min(value, maxPrice));
                }}
                className="range-thumb absolute top-0 z-20 h-9 w-full appearance-none bg-transparent"
              />

              <input
                type="range"
                min={PRICE_MIN}
                max={PRICE_MAX}
                step={1}
                value={maxPrice}
                onChange={(e) => {
                  const value = Number(e.target.value);
                  setMaxPrice(Math.max(value, minPrice));
                }}
                className="range-thumb absolute top-0 z-30 h-9 w-full appearance-none bg-transparent"
              />
            </div>

            <div className="mt-6 grid grid-cols-[1fr_auto_1fr] items-center gap-3">
              <PriceBox label="Min Price" value={minPrice} />
              <span className="mt-6 text-slate-300">—</span>
              <PriceBox label="Max Price" value={maxPrice} />
            </div>
          </div>
        </div>

        <div className="rounded-[26px] border border-slate-100 bg-white p-4 shadow-sm">
          <Label>Sort By</Label>

          <select
            value={sort}
            onChange={(e) => setSort(e.target.value)}
            className="h-12 w-full rounded-2xl border border-slate-200 bg-slate-50 px-4 text-sm font-bold text-slate-800 outline-none transition focus:border-green-500 focus:bg-white focus:ring-4 focus:ring-green-100"
          >
            <option value="">Newest First</option>
            <option value="oldest">Oldest First</option>
            <option value="price_low_high">Price: Low to High</option>
            <option value="price_high_low">Price: High to Low</option>
          </select>
        </div>

        <button
          type="button"
          onClick={clearFilters}
          className="flex h-12 w-full items-center justify-center gap-2 rounded-2xl bg-slate-950 text-sm font-black text-white shadow-xl shadow-slate-200 transition hover:bg-green-600"
        >
          <RotateCcw size={17} />
          Clear Filters
        </button>
      </div>
    );
  };

  return (
    <main className="min-h-screen bg-slate-50 pb-20 md:pb-0">
      <section className="relative overflow-hidden border-b border-green-100 bg-gradient-to-br from-white via-green-50 to-emerald-100">
        <div className="absolute -right-24 -top-24 h-72 w-72 rounded-full bg-green-300/30 blur-3xl" />
        <div className="absolute -left-24 bottom-0 h-72 w-72 rounded-full bg-emerald-200/40 blur-3xl" />

        <div className="relative mx-auto max-w-7xl px-4 py-14 md:py-20">
          <div className="flex flex-col gap-6 md:flex-row md:items-end md:justify-between">
            <div>
              <p className="mb-4 inline-flex rounded-full border border-green-200 bg-white/80 px-5 py-2 text-xs font-black uppercase tracking-[0.22em] text-green-700 shadow-sm">
                Premium Grocery Collection
              </p>

              <h1 className="max-w-3xl text-4xl font-black tracking-tight text-slate-950 md:text-6xl">
                {pageTitle}
              </h1>

              <p className="mt-4 max-w-2xl text-base font-semibold leading-7 text-slate-500">
                {pageSubtitle}
              </p>

              <p className="mt-3 text-sm font-black text-green-700">
                {products.length} products found
              </p>
            </div>

            <button
              type="button"
              onClick={() => setMobileFilterOpen(true)}
              className="flex h-12 items-center justify-center gap-2 rounded-2xl bg-slate-950 px-5 text-sm font-black text-white shadow-xl shadow-slate-300/50 transition hover:bg-green-600 lg:hidden"
            >
              <Filter size={18} />
              Filter Products
            </button>
          </div>
        </div>
      </section>

      <section className="mx-auto max-w-7xl px-4 py-10">
        <div className="grid gap-7 lg:grid-cols-[340px_1fr]">
          <aside className="hidden h-fit rounded-[34px] border border-green-100 bg-white/90 p-5 shadow-2xl shadow-green-100/50 backdrop-blur lg:sticky lg:top-28 lg:block">
            <div className="mb-6 flex items-center gap-3 rounded-[26px] bg-gradient-to-r from-green-600 to-emerald-500 p-4 text-white shadow-xl shadow-green-200">
              <div className="flex h-12 w-12 items-center justify-center rounded-2xl bg-white/20">
                <SlidersHorizontal size={22} />
              </div>

              <div>
                <h2 className="text-xl font-black">Smart Filters</h2>
                <p className="text-xs font-semibold text-white/80">
                  Refine your shopping
                </p>
              </div>
            </div>

            <FilterContent />
          </aside>

          <div>
            {loading ? (
              <div className="grid grid-cols-2 gap-5 md:grid-cols-3 xl:grid-cols-4">
                {[...Array(8)].map((_, index) => (
                  <div
                    key={index}
                    className="h-80 animate-pulse rounded-[28px] bg-white shadow-sm"
                  />
                ))}
              </div>
            ) : products.length > 0 ? (
              <div className="grid grid-cols-2 gap-5 md:grid-cols-3 xl:grid-cols-4">
                {products.map((product) => (
                  <ProductCard key={product.id} product={product} />
                ))}
              </div>
            ) : (
              <div className="flex min-h-[420px] flex-col items-center justify-center rounded-[34px] border border-dashed border-green-200 bg-white text-center shadow-sm">
                <Search size={44} className="text-green-600" />

                <h3 className="mt-4 text-2xl font-black text-slate-900">
                  No products found
                </h3>

                <p className="mt-2 text-slate-500">
                  Try changing your category or price filter.
                </p>

                <button
                  type="button"
                  onClick={clearFilters}
                  className="mt-6 rounded-full bg-green-600 px-7 py-3 text-sm font-black text-white transition hover:bg-green-700"
                >
                  Clear Filters
                </button>
              </div>
            )}
          </div>
        </div>
      </section>

      {mobileFilterOpen && (
        <div className="fixed inset-0 z-[999] bg-black/50 lg:hidden">
          <button
            type="button"
            onClick={() => setMobileFilterOpen(false)}
            className="absolute inset-0 h-full w-full"
            aria-label="Close filter overlay"
          />

          <div className="absolute bottom-[76px] left-0 right-0 max-h-[78vh] overflow-y-auto rounded-t-[36px] bg-slate-50 p-5 shadow-2xl">
            <div className="mb-5 flex items-center justify-between rounded-[26px] bg-gradient-to-r from-green-600 to-emerald-500 p-4 text-white">
              <div>
                <h2 className="text-2xl font-black">Smart Filters</h2>
                <p className="text-sm font-semibold text-white/80">
                  Refine your products
                </p>
              </div>

              <button
                type="button"
                onClick={() => setMobileFilterOpen(false)}
                className="flex h-11 w-11 items-center justify-center rounded-full bg-white/20 text-white"
              >
                <X size={21} />
              </button>
            </div>

            <FilterContent />

            <button
              type="button"
              onClick={() => setMobileFilterOpen(false)}
              className="mt-5 h-12 w-full rounded-2xl bg-green-600 text-sm font-black text-white shadow-xl shadow-green-200 transition hover:bg-green-700"
            >
              Apply Filter
            </button>
          </div>
        </div>
      )}
    </main>
  );
}

function Label({ children }: { children: ReactNode }) {
  return (
    <label className="mb-3 block text-sm font-black tracking-tight text-slate-800">
      {children}
    </label>
  );
}

function PriceBox({ label, value }: { label: string; value: number }) {
  return (
    <div>
      <p className="text-[10px] font-black uppercase tracking-widest text-slate-400">
        {label}
      </p>

      <div className="mt-2 rounded-2xl border border-slate-100 bg-white px-4 py-3 text-sm font-black text-slate-800 shadow-sm">
        ৳ {value}
      </div>
    </div>
  );
}