"use client";

import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
import type { Product } from "@/lib/headless/types";

export interface CartItem {
  product: Product;
  quantity: number;
  variantId?: string;
}

interface CartState {
  items: CartItem[];
  isOpen: boolean;
  hasHydrated: boolean;
  openCart: () => void;
  closeCart: () => void;
  setHasHydrated: (value: boolean) => void;
  addItem: (product: Product, variantId?: string) => void;
  removeItem: (productId: string) => void;
  updateQuantity: (productId: string, quantity: number) => void;
  clearCart: () => void;
}

export const useCartStore = create<CartState>()(
  persist(
    (set) => ({
      items: [],
      isOpen: false,
      hasHydrated: false,
      openCart: () => set({ isOpen: true }),
      closeCart: () => set({ isOpen: false }),
      setHasHydrated: (value) => set({ hasHydrated: value }),
      addItem: (product, variantId) => set((state) => {
        const existing = state.items.find(
          (item) => item.product.id === product.id && item.variantId === variantId,
        );
        const items = existing
          ? state.items.map((item) => item === existing ? { ...item, quantity: item.quantity + 1 } : item)
          : [...state.items, { product, quantity: 1, variantId }];
        return { items, isOpen: true };
      }),
      removeItem: (productId) => set((state) => ({
        items: state.items.filter((item) => item.product.id !== productId),
      })),
      updateQuantity: (productId, quantity) => set((state) => ({
        items: quantity <= 0
          ? state.items.filter((item) => item.product.id !== productId)
          : state.items.map((item) => item.product.id === productId ? { ...item, quantity } : item),
      })),
      clearCart: () => set({ items: [] }),
    }),
    {
      name: "ari-shopping-cart-v4",
      storage: createJSONStorage(() => localStorage),
      partialize: (state) => ({ items: state.items }),
      onRehydrateStorage: () => (state) => state?.setHasHydrated(true),
    },
  ),
);
