import { createContext, useContext, useState, useCallback, type ReactNode } from "react";
import { toast } from "sonner";
import { PRODUCTS } from "@/data/products";

export interface CartItem {
  cartId: number;
  productId: string;
  name: string;
  slug: string;
  image: string | null;
  badge: string | null;
  category: string | null;
  plan: string | null;
  quantity: number;
  priceAtAdd: number;
}

interface CartContextType {
  items: CartItem[];
  isOpen: boolean;
  setIsOpen: (v: boolean) => void;
  addItem: (productId: string, plan?: string) => void;
  removeItem: (cartItemId: number) => void;
  updateQuantity: (cartItemId: number, quantity: number) => void;
  clearCart: () => void;
  refetch: () => void;
  itemCount: number;
}

const CartContext = createContext<CartContextType | null>(null);

let nextCartId = 1;

function getStoredCart(): CartItem[] {
  try {
    const stored = localStorage.getItem("cart");
    if (stored) {
      const parsed = JSON.parse(stored) as CartItem[];
      // Restore nextCartId
      const maxId = parsed.reduce((max, item) => Math.max(max, item.cartId), 0);
      nextCartId = maxId + 1;
      return parsed;
    }
  } catch { /* ignore */ }
  return [];
}

function saveCart(items: CartItem[]) {
  localStorage.setItem("cart", JSON.stringify(items));
}

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

  const addItem = useCallback(
    (productId: string, plan?: string) => {
      const product = PRODUCTS.find(p => p.id === productId);
      if (!product) {
        toast.error("Product not found");
        return;
      }
      const newItem: CartItem = {
        cartId: nextCartId++,
        productId: product.id,
        name: product.name,
        slug: product.slug,
        image: `/prod-${product.category}.jpg`,
        badge: product.badge ?? null,
        category: product.category,
        plan: plan || null,
        quantity: 1,
        priceAtAdd: product.price,
      };
      setItems(prev => {
        const updated = [...prev, newItem];
        saveCart(updated);
        return updated;
      });
      toast.success("Added to cart!");
    },
    []
  );

  const removeItem = useCallback(
    (cartItemId: number) => {
      setItems(prev => {
        const updated = prev.filter(item => item.cartId !== cartItemId);
        saveCart(updated);
        return updated;
      });
    },
    []
  );

  const updateQuantity = useCallback(
    (cartItemId: number, quantity: number) => {
      if (quantity < 1) {
        removeItem(cartItemId);
        return;
      }
      setItems(prev => {
        const updated = prev.map(item =>
          item.cartId === cartItemId ? { ...item, quantity } : item
        );
        saveCart(updated);
        return updated;
      });
    },
    [removeItem]
  );

  const clearCart = useCallback(() => {
    setItems([]);
    saveCart([]);
  }, []);

  const refetch = useCallback(() => {
    setItems(getStoredCart());
  }, []);

  const itemCount = items.reduce((sum, i) => sum + i.quantity, 0);

  return (
    <CartContext.Provider
      value={{ items, isOpen, setIsOpen, addItem, removeItem, updateQuantity, clearCart, refetch, itemCount }}
    >
      {children}
    </CartContext.Provider>
  );
}

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