"use client";

import Image from "next/image";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import {
  type FormEvent,
  type MouseEvent,
  useCallback,
  useMemo,
  useState,
} from "react";
import { addProductToCartById } from "@/lib/cart-add";
import {
  shopAssets,
  shopListMeta,
  shopPagination,
  shopPriceFilter,
  shopProducts,
  shopSortOptions,
  type ShopProduct,
} from "@/data/shop";
import ShopProductCard from "@/components/shop/ShopProductCard";
import ShopSidebar from "@/components/shop/ShopSidebar";

const iconImgStyle = { width: "auto", height: "auto" } as const;

const pf = shopPriceFilter;

function orderRange(
  min: number,
  max: number,
  lo: number,
  hi: number,
): [number, number] {
  const a = Math.min(hi, Math.max(lo, min));
  const b = Math.min(hi, Math.max(lo, max));
  if (a > b) return [b, a];
  return [a, b];
}

function sortProducts(list: ShopProduct[], sort: string): ShopProduct[] {
  const out = [...list];
  switch (sort) {
    case "price-asc":
      out.sort((a, b) => a.unitPrice - b.unitPrice);
      break;
    case "price-desc":
      out.sort((a, b) => b.unitPrice - a.unitPrice);
      break;
    case "name-asc":
      out.sort((a, b) => a.title.localeCompare(b.title));
      break;
    case "name-desc":
      out.sort((a, b) => b.title.localeCompare(a.title));
      break;
    default:
      break;
  }
  return out;
}

export default function ShopBrowse() {
  const router = useRouter();

  const handleAddToCart = useCallback(
    (product: ShopProduct) => {
      addProductToCartById(product.id);
      toast.success(`${product.title} added to cart`, {
        description:
          "Your cart was updated. Adjust quantities or continue shopping.",
        action: {
          label: "View cart",
          onClick: () => router.push("/cart"),
        },
      });
    },
    [router],
  );

  const [searchInput, setSearchInput] = useState("");
  const [appliedSearch, setAppliedSearch] = useState("");
  const [sort, setSort] = useState("");
  const [categoryId, setCategoryId] = useState<string | null>(null);
  const [tagId, setTagId] = useState<string | null>(null);
  const [spotlightProductId, setSpotlightProductId] = useState<string | null>(
    null,
  );

  const [sliderMin, setSliderMin] = useState<number>(pf.minDefault);
  const [sliderMax, setSliderMax] = useState<number>(pf.maxDefault);
  const [appliedPriceMin, setAppliedPriceMin] = useState<number>(pf.rangeMin);
  const [appliedPriceMax, setAppliedPriceMax] = useState<number>(pf.rangeMax);

  const handleSearchChange = useCallback((value: string) => {
    setSearchInput(value);
    setAppliedSearch(value.trim());
    setSpotlightProductId(null);
  }, []);

  const onSearchSubmit = useCallback((e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setAppliedSearch(searchInput.trim());
    setSpotlightProductId(null);
  }, [searchInput]);

  const onPriceSliderMinChange = useCallback((value: number) => {
    const [a, b] = orderRange(value, sliderMax, pf.rangeMin, pf.rangeMax);
    setSliderMin(a);
    setSliderMax(b);
  }, [sliderMax]);

  const onPriceSliderMaxChange = useCallback((value: number) => {
    const [a, b] = orderRange(sliderMin, value, pf.rangeMin, pf.rangeMax);
    setSliderMin(a);
    setSliderMax(b);
  }, [sliderMin]);

  const onApplyPriceFilter = useCallback(
    (e: MouseEvent<HTMLAnchorElement>) => {
      e.preventDefault();
      const [lo, hi] = orderRange(
        sliderMin,
        sliderMax,
        pf.rangeMin,
        pf.rangeMax,
      );
      setAppliedPriceMin(lo);
      setAppliedPriceMax(hi);
      setSpotlightProductId(null);
    },
    [sliderMin, sliderMax],
  );

  const onResetFilters = useCallback((e: MouseEvent<HTMLAnchorElement>) => {
    e.preventDefault();
    setSearchInput("");
    setAppliedSearch("");
    setSort("");
    setCategoryId(null);
    setTagId(null);
    setSpotlightProductId(null);
    setSliderMin(pf.minDefault);
    setSliderMax(pf.maxDefault);
    setAppliedPriceMin(pf.rangeMin);
    setAppliedPriceMax(pf.rangeMax);
  }, []);

  const onCategoryClick = useCallback(
    (id: string, e: MouseEvent<HTMLAnchorElement>) => {
      e.preventDefault();
      setCategoryId((c) => (c === id ? null : id));
      setSpotlightProductId(null);
    },
    [],
  );

  const onTagClick = useCallback(
    (id: string, e: MouseEvent<HTMLAnchorElement>) => {
      e.preventDefault();
      setTagId((t) => (t === id ? null : id));
      setSpotlightProductId(null);
    },
    [],
  );

  const onTopRatedProductClick = useCallback(
    (shopProductId: string, e: MouseEvent<HTMLAnchorElement>) => {
      e.preventDefault();
      setSpotlightProductId((s) =>
        s === shopProductId ? null : shopProductId,
      );
      setCategoryId(null);
      setTagId(null);
    },
    [],
  );

  const filtered = useMemo(() => {
    const q = appliedSearch.toLowerCase();
    const list = shopProducts.filter((p) => {
      if (q && !p.title.toLowerCase().includes(q)) return false;
      if (categoryId && !p.categoryIds.includes(categoryId)) return false;
      if (tagId && !p.tagIds.includes(tagId)) return false;
      if (spotlightProductId && p.id !== spotlightProductId) return false;
      if (p.unitPrice < appliedPriceMin || p.unitPrice > appliedPriceMax) {
        return false;
      }
      return true;
    });
    return sortProducts(list, sort);
  }, [
    appliedSearch,
    appliedPriceMin,
    appliedPriceMax,
    categoryId,
    tagId,
    spotlightProductId,
    sort,
  ]);

  const totalCatalog = shopListMeta.totalResults;
  const visible = filtered.length;
  const showingLabel =
    visible === 0
      ? `Showing 0 of ${totalCatalog} results`
      : `Showing 1–${visible} of ${totalCatalog} results`;

  const displayPriceMin = Math.round(sliderMin);
  const displayPriceMax = Math.round(sliderMax);

  return (
    <div className="row">
      <div className="col-xl-9 col-lg-8">
        <div
          className="shop-area"
          data-aos="fade-up"
          data-aos-duration={900}
          data-aos-delay={200}
        >
          <div className="row">
            <div className="col-lg-6 col-md-6">
              <h2 className="title2">{showingLabel}</h2>
            </div>
            <div className="col-lg-6 col-md-6">
              <form className="shop-form">
                <select
                  className="form-select"
                  value={sort}
                  onChange={(e) => setSort(e.target.value)}
                >
                  {shopSortOptions.map((opt) => (
                    <option key={opt.value || "default"} value={opt.value}>
                      {opt.label}
                    </option>
                  ))}
                </select>
              </form>
            </div>
          </div>
        </div>
        <div className="row">
          {visible === 0 ? (
            <div className="col-12">
              <p className="title2 mb-0">No products match your filters.</p>
            </div>
          ) : (
            filtered.map((product) => (
              <ShopProductCard
                key={product.id}
                product={product}
                onAddToCart={() => handleAddToCart(product)}
              />
            ))
          )}
        </div>
        <nav
          aria-label="Page navigation example"
          data-aos="fade-up"
          data-aos-duration={900}
          data-aos-delay={300}
        >
          <ul className="pagination blog-pagination">
            {shopPagination.map((item, index) => {
              if (item.kind === "prev") {
                return (
                  <li className="page-item" key={`pagination-${index}`}>
                    <a
                      className="page-link"
                      href={item.href}
                      aria-label={item.ariaLabel}
                      onClick={(e) => e.preventDefault()}
                    >
                      <span aria-hidden="true">
                        <Image
                          src={shopAssets.pagiPrev}
                          alt={shopAssets.pagiPrevAlt}
                          width={24}
                          height={24}
                          style={iconImgStyle}
                        />
                      </span>
                    </a>
                  </li>
                );
              }
              if (item.kind === "next") {
                return (
                  <li className="page-item" key={`pagination-${index}`}>
                    <a
                      className="page-link"
                      href={item.href}
                      aria-label={item.ariaLabel}
                      onClick={(e) => e.preventDefault()}
                    >
                      <span aria-hidden="true">
                        <Image
                          src={shopAssets.pagiNext}
                          alt={shopAssets.pagiNextAlt}
                          width={24}
                          height={24}
                          style={iconImgStyle}
                        />
                      </span>
                    </a>
                  </li>
                );
              }
              return (
                <li className="page-item" key={`pagination-${index}`}>
                  <a
                    className="page-link"
                    href={item.href}
                    onClick={(e) => e.preventDefault()}
                  >
                    {item.label}
                  </a>
                </li>
              );
            })}
          </ul>
        </nav>
      </div>
      <ShopSidebar
        searchValue={searchInput}
        onSearchChange={handleSearchChange}
        onSearchSubmit={onSearchSubmit}
        priceSliderMin={sliderMin}
        priceSliderMax={sliderMax}
        onPriceSliderMinChange={onPriceSliderMinChange}
        onPriceSliderMaxChange={onPriceSliderMaxChange}
        displayPriceMin={displayPriceMin}
        displayPriceMax={displayPriceMax}
        onApplyPriceFilter={onApplyPriceFilter}
        onResetFilters={onResetFilters}
        onCategoryClick={onCategoryClick}
        onTagClick={onTagClick}
        onTopRatedProductClick={onTopRatedProductClick}
      />
    </div>
  );
}
