import { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from "react";

export type CartItem = {
  listingId: string;
  title: string;
  price: number;
  image: string | null;
  quantity: number;
  stock: number;
};

type CartValue = {
  items: CartItem[];
  count: number;
  subtotal: number;
  add: (item: Omit<CartItem, "quantity">, quantity?: number) => void;
  setQuantity: (listingId: string, quantity: number) => void;
  remove: (listingId: string) => void;
  clear: () => void;
  has: (listingId: string) => boolean;
};

const CartContext = createContext<CartValue | null>(null);
const KEY = "kuya:cart";

export function CartProvider({ children }: { children: ReactNode }) {
  const [items, setItems] = useState<CartItem[]>([]);
  const [hydrated, setHydrated] = useState(false);

  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(KEY);
      if (raw) setItems(JSON.parse(raw) as CartItem[]);
    } catch {
      /* ignore corrupted cart */
    }
    setHydrated(true);
  }, []);

  useEffect(() => {
    if (hydrated) window.localStorage.setItem(KEY, JSON.stringify(items));
  }, [items, hydrated]);

  const value = useMemo<CartValue>(() => {
    return {
      items,
      count: items.reduce((sum, i) => sum + i.quantity, 0),
      subtotal: items.reduce((sum, i) => sum + i.price * i.quantity, 0),
      has: (listingId) => items.some((i) => i.listingId === listingId),
      add: (item, quantity = 1) =>
        setItems((prev) => {
          const found = prev.find((i) => i.listingId === item.listingId);
          if (found) {
            return prev.map((i) =>
              i.listingId === item.listingId
                ? { ...i, quantity: Math.min(i.stock, i.quantity + quantity) }
                : i,
            );
          }
          return [...prev, { ...item, quantity: Math.min(item.stock, quantity) }];
        }),
      setQuantity: (listingId, quantity) =>
        setItems((prev) =>
          prev.map((i) =>
            i.listingId === listingId
              ? { ...i, quantity: Math.max(1, Math.min(i.stock, quantity)) }
              : i,
          ),
        ),
      remove: (listingId) => setItems((prev) => prev.filter((i) => i.listingId !== listingId)),
      clear: () => setItems([]),
    };
  }, [items]);

  return <CartContext.Provider value={value}>{children}</CartContext.Provider>;
}

export function useCart(): CartValue {
  const ctx = useContext(CartContext);
  if (!ctx) throw new Error("useCart must be used inside CartProvider");
  return ctx;
}
