import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';

export type CartItem = {
    productId: number;
    productName: string;
    variantId: number;
    variantName: string;
    priceType: 'retail' | 'wholesale';
    price: number;
    quantity: number;
    imageUrl: string;
};

type CartContextType = {
    items: CartItem[];
    addItem: (item: Omit<CartItem, 'quantity'> & { quantity?: number }) => void;
    removeItem: (variantId: number) => void;
    updateQuantity: (variantId: number, quantity: number) => void;
    clearCart: () => void;
    totalItems: number;
    totalPrice: number;
};

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

const STORAGE_KEY = 'dst_cart';
const VISITOR_KEY = 'dst_visitor_id';

function getVisitorId(): string {
    let id = localStorage.getItem(VISITOR_KEY);
    if (!id) {
        id = crypto.randomUUID();
        localStorage.setItem(VISITOR_KEY, id);
    }
    return id;
}

function loadCart(): CartItem[] {
    try {
        const raw = localStorage.getItem(`${STORAGE_KEY}_${getVisitorId()}`);
        return raw ? JSON.parse(raw) : [];
    } catch {
        return [];
    }
}

function saveCart(items: CartItem[]): void {
    localStorage.setItem(`${STORAGE_KEY}_${getVisitorId()}`, JSON.stringify(items));
}

export function CartProvider({ children }: { children: React.ReactNode }) {
    const [items, setItems] = useState<CartItem[]>(loadCart);

    useEffect(() => {
        saveCart(items);
    }, [items]);

    const addItem = useCallback((item: Omit<CartItem, 'quantity'> & { quantity?: number }) => {
        setItems((prev) => {
            const existing = prev.find((i) => i.variantId === item.variantId);
            if (existing) {
                return prev.map((i) =>
                    i.variantId === item.variantId
                        ? { ...i, quantity: i.quantity + (item.quantity ?? 1) }
                        : i,
                );
            }
            return [...prev, { ...item, quantity: item.quantity ?? 1 }];
        });
    }, []);

    const removeItem = useCallback((variantId: number) => {
        setItems((prev) => prev.filter((i) => i.variantId !== variantId));
    }, []);

    const updateQuantity = useCallback((variantId: number, quantity: number) => {
        if (quantity <= 0) {
            setItems((prev) => prev.filter((i) => i.variantId !== variantId));
            return;
        }
        setItems((prev) => prev.map((i) => (i.variantId === variantId ? { ...i, quantity } : i)));
    }, []);

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

    const totalItems = useMemo(() => items.reduce((sum, i) => sum + i.quantity, 0), [items]);
    const totalPrice = useMemo(() => items.reduce((sum, i) => sum + i.price * i.quantity, 0), [items]);

    return (
        <CartContext.Provider value={{ items, addItem, removeItem, updateQuantity, clearCart, totalItems, totalPrice }}>
            {children}
        </CartContext.Provider>
    );
}

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