import { create } from "zustand";
import { persist } from "zustand/middleware";
import { PRODUCTS, type Product } from "./catalog";

export type CartItem = { id: string; qty: number };

export type PlacedOrder = {
  id: string;
  at: string;
  name: string;
  email: string;
  note: string;
  items: CartItem[];
  totalCents: number;
};

type CartState = {
  items: CartItem[];
  add: (id: string, qty?: number) => void;
  setQty: (id: string, qty: number) => void;
  remove: (id: string) => void;
  clear: () => void;
  lastOrder: PlacedOrder | null;
  placeOrder: (input: { name: string; email: string; note: string }) => PlacedOrder;
};

export function cartLines(items: CartItem[]): { product: Product; qty: number; lineCents: number }[] {
  return items
    .map((item) => {
      const product = PRODUCTS.find((p) => p.id === item.id);
      if (!product) return null;
      return { product, qty: item.qty, lineCents: product.priceCents * item.qty };
    })
    .filter((row): row is { product: Product; qty: number; lineCents: number } => row !== null);
}

export function cartTotalCents(items: CartItem[]): number {
  return cartLines(items).reduce((sum, row) => sum + row.lineCents, 0);
}

export function cartCount(items: CartItem[]): number {
  return items.reduce((sum, item) => sum + item.qty, 0);
}

export const useCart = create<CartState>()(
  persist(
    (set, get) => ({
      items: [],
      lastOrder: null,
      add: (id, qty = 1) => {
        const items = [...get().items];
        const existing = items.find((item) => item.id === id);
        if (existing) existing.qty += qty;
        else items.push({ id, qty });
        set({ items });
      },
      setQty: (id, qty) => {
        if (qty <= 0) {
          set({ items: get().items.filter((item) => item.id !== id) });
          return;
        }
        set({
          items: get().items.map((item) => (item.id === id ? { ...item, qty } : item)),
        });
      },
      remove: (id) => set({ items: get().items.filter((item) => item.id !== id) }),
      clear: () => set({ items: [] }),
      placeOrder: ({ name, email, note }) => {
        const items = get().items;
        const order: PlacedOrder = {
          id: `ST-${Date.now().toString(36).toUpperCase()}`,
          at: new Date().toISOString(),
          name,
          email,
          note,
          items,
          totalCents: cartTotalCents(items),
        };
        set({ items: [], lastOrder: order });
        return order;
      },
    }),
    { name: "strata-cart-v1" },
  ),
);
