import { createContext, useContext, useState, ReactNode, useCallback, useEffect } from "react";
import { useTenant } from "@/contexts/TenantContext";

export interface CartDelegate {
  first_name: string;
  last_name: string;
  email: string;
  phone: string;
}

export interface CartItem {
  id: string; // unique cart item id
  courseId: string;
  courseTitle: string;
  courseSlug: string;
  priceCents: number;
  days: number;
  startDate: string; // yyyy-MM-dd
  trainerId?: string;
  venueId?: string | null;
  venueName?: string;
  numDelegates: number;
  delegates: CartDelegate[];
}

interface CartContextType {
  items: CartItem[];
  addItem: (item: Omit<CartItem, "id">) => void;
  removeItem: (id: string) => void;
  updateItem: (id: string, updates: Partial<CartItem>) => void;
  updateDelegates: (id: string, delegates: CartDelegate[]) => void;
  clearCart: () => void;
  totalCents: number;
  itemCount: number;
}

const CART_STORAGE_KEY = "utc_cart_v1";

// Carts are namespaced per tenant so a buyer's main-marketplace cart and a
// tenant storefront's cart never bleed into one another (each storefront sells
// a different company's courses and routes to a different Stripe payee).
const storageKeyFor = (subdomain: string | null) =>
  subdomain ? `${CART_STORAGE_KEY}::${subdomain}` : CART_STORAGE_KEY;

const CartContext = createContext<CartContextType>({
  items: [],
  addItem: () => {},
  removeItem: () => {},
  updateItem: () => {},
  updateDelegates: () => {},
  clearCart: () => {},
  totalCents: 0,
  itemCount: 0,
});

export const useCart = () => useContext(CartContext);

const loadFromStorage = (key: string): CartItem[] => {
  if (typeof window === "undefined") return [];
  try {
    const raw = window.localStorage.getItem(key);
    if (!raw) return [];
    const parsed = JSON.parse(raw);
    return Array.isArray(parsed) ? parsed : [];
  } catch {
    return [];
  }
};

export const CartProvider = ({ children }: { children: ReactNode }) => {
  const { subdomain } = useTenant();
  const storageKey = storageKeyFor(subdomain);
  const [items, setItems] = useState<CartItem[]>(() => loadFromStorage(storageKey));

  useEffect(() => {
    try {
      window.localStorage.setItem(storageKey, JSON.stringify(items));
    } catch {
      // ignore storage errors
    }
  }, [items, storageKey]);

  const addItem = useCallback((item: Omit<CartItem, "id">) => {
    const id = crypto.randomUUID();
    setItems(prev => [...prev, { ...item, id }]);
  }, []);

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

  const updateItem = useCallback((id: string, updates: Partial<CartItem>) => {
    setItems(prev => prev.map(i => i.id === id ? { ...i, ...updates } : i));
  }, []);

  const updateDelegates = useCallback((id: string, delegates: CartDelegate[]) => {
    setItems(prev => prev.map(i =>
      i.id === id ? { ...i, delegates, numDelegates: delegates.length } : i
    ));
  }, []);

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

  const totalCents = items.reduce((sum, i) => sum + i.priceCents * i.numDelegates, 0);
  const itemCount = items.length;

  return (
    <CartContext.Provider value={{ items, addItem, removeItem, updateItem, updateDelegates, clearCart, totalCents, itemCount }}>
      {children}
    </CartContext.Provider>
  );
};
