"use client";

import Link from "next/link";
import { Headphones, Trash2 } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { ProductVisual } from "@/components/ProductVisual";
import { readCartItems, writeCartItems, type StoredCartItem } from "@/lib/cart-storage";
import { currency, displayPrice } from "@/lib/utils";

type Product = { id: string; name: string; slug: string; metalType?: string; productType?: string; weight: string; purity: string; brandMint?: string; mintBrand?: string; customerPrice: string; totalSalePrice: string; manualPrice: string; imageUrls?: string; images?: string };

function fetchCartProducts(stored: StoredCartItem[]) {
  const controller = new AbortController();
  const timeout = window.setTimeout(() => controller.abort(), 4000);
  return fetch(`/api/cart?ids=${stored.map((item) => item.productId).join(",")}`, { signal: controller.signal })
    .then((res) => res.ok ? res.json() : [])
    .then((data) => Array.isArray(data) ? data : [])
    .catch(() => [])
    .finally(() => window.clearTimeout(timeout));
}

export function CartClient() {
  const [items, setItems] = useState<StoredCartItem[]>([]);
  const [products, setProducts] = useState<Product[]>([]);
  const [cartChecked, setCartChecked] = useState(false);

  useEffect(() => {
    let active = true;
    const failSafe = window.setTimeout(() => {
      if (!active) return;
      setProducts([]);
      setCartChecked(true);
    }, 4500);

    async function hydrateCart() {
      try {
        const stored = readCartItems();
        if (!active) return;
        setItems(stored);

        if (!stored.length) {
          setProducts([]);
          setCartChecked(true);
          return;
        }

        const data = await fetchCartProducts(stored);
        if (!active) return;

        const validIds = new Set(data.map((product: Product) => product.id));
        const validItems = stored.filter((item) => validIds.has(item.productId));
        setItems(validItems);
        setProducts(data.filter((product: Product) => validIds.has(product.id)));

      } catch {
        if (!active) return;
        setProducts([]);
      } finally {
        window.clearTimeout(failSafe);
        if (active) setCartChecked(true);
      }
    }

    hydrateCart();

    return () => {
      active = false;
      window.clearTimeout(failSafe);
    };
  }, []);

  const rows = items.map((item) => ({ item, product: products.find((product) => product.id === item.productId) })).filter((row) => row.product);
  const subtotal = useMemo(() => rows.reduce((sum, row) => sum + displayPrice(row.product!) * row.item.quantity, 0), [rows]);

  function persist(next: StoredCartItem[]) {
    setItems(writeCartItems(next));
  }

  const empty = cartChecked && rows.length === 0;

  return (
    <section className="container-grid py-8">
      <div className="text-sm text-[#666]"><Link href="/">Home</Link> / Cart</div>
      <h1 className="mt-3 text-3xl font-black">Shopping Cart</h1>
      <div className={empty || !cartChecked ? "mt-6" : "mt-6 grid gap-6 lg:grid-cols-[1fr_360px]"}>
        <div className="rounded border border-[#E5E1D8] bg-white">
          {!cartChecked ? (
            <div className="p-6">
              <div className="h-5 w-40 rounded bg-[#E6DFD0]" />
              <div className="mt-5 grid gap-4">
                {[0, 1, 2].map((item) => (
                  <div key={item} className="flex items-center gap-4 rounded border border-[#E5E1D8] bg-[#F7F5EF] p-4">
                    <div className="h-16 w-16 rounded bg-[#E6DFD0]" />
                    <div className="grid flex-1 gap-2">
                      <div className="h-4 w-2/3 rounded bg-[#E6DFD0]" />
                      <div className="h-3 w-1/3 rounded bg-[#E6DFD0]" />
                    </div>
                    <div className="hidden h-4 w-20 rounded bg-[#E6DFD0] sm:block" />
                  </div>
                ))}
              </div>
            </div>
          ) : !empty ? (
            <div className="table-wrap">
              <table>
                <thead><tr><th>Product</th><th>Quantity</th><th>Price</th><th>Subtotal</th><th></th></tr></thead>
                <tbody>
                  {rows.map(({ item, product }) => (
                    <tr key={item.productId}>
                      <td>
                        <div className="flex min-w-[320px] items-center gap-3">
                          <div className="h-20 w-20 overflow-hidden rounded border border-[#E5E1D8] bg-[#F7F5EF]">
                            <ProductVisual product={product!} compact />
                          </div>
                          <div>
                            <Link href={`/products/${product!.slug}`} className="font-black hover:text-[#7A5310]">{product!.name}</Link>
                            <p className="mt-1 text-sm text-[#666]">{product!.weight} / {product!.purity} / {product!.brandMint || product!.mintBrand}</p>
                          </div>
                        </div>
                      </td>
                      <td><input className="w-24" type="number" min={1} value={item.quantity} onChange={(event) => persist(items.map((next) => next.productId === item.productId ? { ...next, quantity: Math.max(1, Number(event.target.value) || 1) } : next))} /></td>
                      <td>{currency(displayPrice(product!))}</td>
                      <td className="font-black">{currency(displayPrice(product!) * item.quantity)}</td>
                      <td><button className="btn btn-secondary" onClick={() => persist(items.filter((next) => next.productId !== item.productId))} aria-label="Remove"><Trash2 size={18} /></button></td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          ) : (
            <div className="p-8 text-center">
              <div className="product-media mx-auto mb-5 h-32 w-32 overflow-hidden rounded-full border border-[#E5E1D8]">
                <ProductVisual product={{ name: "Gold Coin", metalType: "GOLD", productType: "COIN" }} compact />
              </div>
              <h2 className="text-xl font-black">Your cart is empty</h2>
              <p className="mt-2 text-[#666]">Start with gold bars, silver coins, or value picks.</p>
              <div className="mt-5 flex flex-wrap justify-center gap-3">
                <Link className="btn btn-primary" href="/gold">Shop Gold</Link>
                <Link className="btn btn-secondary" href="/silver">Shop Silver</Link>
                <Link className="btn btn-secondary" href="/products">View All Products</Link>
              </div>
              <div className="mx-auto mt-6 flex max-w-md items-center justify-center gap-2 rounded border border-[#E6DFD0] bg-[#F7F5EF] p-3 text-sm text-[#666]">
                <Headphones size={18} className="text-[#B9922F]" /> Need help choosing bullion? Visit support for order assistance.
              </div>
            </div>
          )}
        </div>
        {cartChecked && !empty ? (
          <aside className="h-fit rounded border border-[#E5E1D8] bg-[#F7F5EF] p-5 lg:sticky lg:top-44">
            <h2 className="text-xl font-black">Order Summary</h2>
            <div className="mt-4 flex justify-between border-b border-[#E5E1D8] pb-3"><span>Subtotal</span><strong>{currency(subtotal)}</strong></div>
            <p className="mt-3 text-sm text-[#666]">Shipping, insurance coordination, and fulfillment are reviewed after order submission.</p>
            <Link className="btn btn-primary mt-5 w-full" href="/checkout">Proceed to Checkout</Link>
            <Link className="btn btn-secondary mt-2 w-full" href="/products">Continue Shopping</Link>
          </aside>
        ) : null}
      </div>
    </section>
  );
}
