import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react';
import type { CartItem, EquipmentItem } from '../types';

const STORAGE_KEY = 'hms-cart';

interface CartContextType {
  items: CartItem[];
  totalCount: number;
  isEmpty: boolean;
  hasItems: boolean;
  apiItems: { equipment_id: number; quantity: number }[];
  addItem: (equipment: EquipmentItem) => void;
  addItemByFields: (item: { equipment_id: number; name: string; rental_price: number | null; image_url: string | null }) => void;
  removeItem: (equipmentId: number) => void;
  updateQuantity: (equipmentId: number, quantity: number) => void;
  incrementQuantity: (equipmentId: number) => void;
  decrementQuantity: (equipmentId: number) => void;
  clearCart: () => void;
}

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

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

  // Hydrate from localStorage
  useEffect(() => {
    try {
      const stored = localStorage.getItem(STORAGE_KEY);
      if (stored) {
        const parsed = JSON.parse(stored);
        if (parsed && Array.isArray(parsed.items)) {
          setItems(parsed.items);
        }
      }
    } catch (e) {
      console.warn('Failed to hydrate cart from localStorage:', e);
    }
  }, []);

  // Persist to localStorage on changes
  useEffect(() => {
    try {
      localStorage.setItem(STORAGE_KEY, JSON.stringify({ items }));
    } catch (e) {
      console.warn('Failed to persist cart to localStorage:', e);
    }
  }, [items]);

  const addItem = useCallback((equipment: EquipmentItem) => {
    setItems(prev => {
      const existing = prev.find(i => i.equipment_id === equipment.id);
      if (existing) {
        return prev.map(i => i.equipment_id === equipment.id ? { ...i, quantity: i.quantity + 1 } : i);
      }
      return [...prev, { equipment_id: equipment.id, name: equipment.name, quantity: 1, rental_price: equipment.rental_price, image_url: equipment.image_url }];
    });
  }, []);

  const addItemByFields = useCallback((item: { equipment_id: number; name: string; rental_price: number | null; image_url: string | null }) => {
    setItems(prev => {
      const existing = prev.find(i => i.equipment_id === item.equipment_id);
      if (existing) {
        return prev.map(i => i.equipment_id === item.equipment_id ? { ...i, quantity: i.quantity + 1 } : i);
      }
      return [...prev, { equipment_id: item.equipment_id, name: item.name, quantity: 1, rental_price: item.rental_price, image_url: item.image_url }];
    });
  }, []);

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

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

  const incrementQuantity = useCallback((equipmentId: number) => {
    setItems(prev => prev.map(i => i.equipment_id === equipmentId ? { ...i, quantity: i.quantity + 1 } : i));
  }, []);

  const decrementQuantity = useCallback((equipmentId: number) => {
    setItems(prev => {
      const item = prev.find(i => i.equipment_id === equipmentId);
      if (!item) return prev;
      if (item.quantity <= 1) {
        return prev.filter(i => i.equipment_id !== equipmentId);
      }
      return prev.map(i => i.equipment_id === equipmentId ? { ...i, quantity: i.quantity - 1 } : i);
    });
  }, []);

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

  const totalCount = items.reduce((sum, item) => sum + item.quantity, 0);
  const isEmpty = items.length === 0;
  const hasItems = items.length > 0;
  const apiItems = items.map(item => ({ equipment_id: item.equipment_id, quantity: item.quantity }));

  return (
    <CartContext.Provider value={{ items, totalCount, isEmpty, hasItems, apiItems, addItem, addItemByFields, removeItem, updateQuantity, incrementQuantity, decrementQuantity, clearCart }}>
      {children}
    </CartContext.Provider>
  );
}

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