"use client";

import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
import type { ReactNode } from "react";
import { storefrontHref } from "@/lib/storefront-path";

interface CartState {
  items: Record<string, number>;
  hydrated: boolean;
  count: number;
  addItem: (sku: string) => void;
  setQuantity: (sku: string, quantity: number) => void;
  removeItem: (sku: string) => void;
  clearCart: () => void;
  href: (path?: string) => string;
}

const StoreContext = createContext<CartState | null>(null);
const storageKey = "smart-cod-store-cart";

export function StoreProvider({ basePath, children }: { basePath: string; children: ReactNode }) {
  const [items, setItems] = useState<Record<string, number>>({});
  const [hydrated, setHydrated] = useState(false);

  useEffect(() => {
    try {
      const stored = window.localStorage.getItem(storageKey);
      if (stored) {
        const parsed = JSON.parse(stored) as Record<string, unknown>;
        setItems(Object.fromEntries(
          Object.entries(parsed).filter(([, quantity]) => Number.isInteger(quantity) && Number(quantity) > 0 && Number(quantity) <= 20),
        ) as Record<string, number>);
      }
    } catch {
      window.localStorage.removeItem(storageKey);
    } finally {
      setHydrated(true);
    }
  }, []);

  useEffect(() => {
    if (hydrated) window.localStorage.setItem(storageKey, JSON.stringify(items));
  }, [hydrated, items]);

  const setQuantity = useCallback((sku: string, quantity: number) => {
    setItems((current) => {
      const next = { ...current };
      const safeQuantity = Math.max(0, Math.min(20, Math.trunc(quantity)));
      if (safeQuantity === 0) delete next[sku];
      else next[sku] = safeQuantity;
      return next;
    });
  }, []);

  const value = useMemo<CartState>(() => ({
    items,
    hydrated,
    count: Object.values(items).reduce((total, quantity) => total + quantity, 0),
    addItem: (sku) => setItems((current) => ({ ...current, [sku]: Math.min(20, (current[sku] ?? 0) + 1) })),
    setQuantity,
    removeItem: (sku) => setQuantity(sku, 0),
    clearCart: () => setItems({}),
    href: (path = "/") => storefrontHref(basePath, path),
  }), [basePath, hydrated, items, setQuantity]);

  return <StoreContext.Provider value={value}>{children}</StoreContext.Provider>;
}

export function useStore() {
  const context = useContext(StoreContext);
  if (!context) throw new Error("useStore must be used within StoreProvider");
  return context;
}
