"use client";

import { createContext, useContext, useState, useEffect, useCallback } from "react";
import { useAuth } from "@/context/AuthContext";
import {
  fetchCart,
  apiAddToCart,
  apiUpdateCartItem,
  apiRemoveCartItem,
  apiClearCart,
  apiApplyCoupon,
  apiRemoveCoupon,
  apiApplyPoints,
  apiCheckout,
  apiCancelCheckout,
} from "@/lib/cartApi";

const CartContext = createContext(null);

const STORE_KEY = "selected_store_id";

export function CartProvider({ children }) {
  const { user, token } = useAuth();
  const [cart, setCart] = useState(null);
  const [selectedStoreId, setSelectedStoreIdState] = useState(null);
  const [cartLoading, setCartLoading] = useState(false);
  const [cartError, setCartError] = useState(null);

  const setStoreId = useCallback((id) => {
    const parsed = id ? Number(id) : null;
    setSelectedStoreIdState(parsed);
    if (parsed) {
      localStorage.setItem(STORE_KEY, String(parsed));
    } 
    
    else {
      localStorage.removeItem(STORE_KEY);
    }
  }, []);

  useEffect(() => {
    const stored = localStorage.getItem(STORE_KEY);
    if (stored) {
      setSelectedStoreIdState(Number(stored));
    }
  }, []);

  useEffect(() => {
    if (user?.storeId && !localStorage.getItem(STORE_KEY)) {
      setStoreId(user.storeId);
    }
  }, [user, setStoreId]);

  const refreshCart = useCallback(async () => {
    if (!token || !selectedStoreId) {
      setCart(null);
      return;
    }
    setCartLoading(true);
    setCartError(null);
    try {
      const data = await fetchCart(token, selectedStoreId);
      setCart(data);
    } 
    
    catch (err) {
      setCartError(err.message);
    } 
    
    finally {
      setCartLoading(false);
    }
  }, [token, selectedStoreId]);

  useEffect(() => {
    if (user && selectedStoreId) {
      refreshCart();
    } 
    
    else {
      setCart(null);
    }
  }, [user, selectedStoreId, refreshCart]);

  const addItem = useCallback(
    async (prodId, quantity = 1) => {
      if (!token || !selectedStoreId) throw new Error("Select a store first");
      const updated = await apiAddToCart(token, { prodId, storeId: selectedStoreId, quantity });
      setCart(updated);

      return updated;
    },
    [token, selectedStoreId]
  );

  const updateItem = useCallback(
    async (cartItemId, quantity) => {
      if (!token) return;
      const updated = await apiUpdateCartItem(token, { cartItemId, quantity });
      setCart(updated);

      return updated;
    },
    [token]
  );

  const removeItem = useCallback(
    async (cartItemId) => {
      if (!token) return;
      const updated = await apiRemoveCartItem(token, cartItemId);
      setCart(updated);

      return updated;
    },
    [token]
  );

  const clearCart = useCallback(async () => {
    if (!token || !selectedStoreId) return;
    await apiClearCart(token, selectedStoreId);
    setCart(null);
  }, [token, selectedStoreId]);

  const applyCoupon = useCallback(
    async (couponCode) => {
      if (!token || !selectedStoreId) throw new Error("Select a store first");
      const updated = await apiApplyCoupon(token, selectedStoreId, couponCode);
      setCart(updated);

      return updated;
    },
    [token, selectedStoreId]
  );

  const applyPoints = useCallback(
    async (useLoyaltyPoints) => {
      if (!token || !selectedStoreId) throw new Error("Select a store first");
      const updated = await apiApplyPoints(token, selectedStoreId, useLoyaltyPoints);
      setCart(updated);

      return updated;
    },
    [token, selectedStoreId]
  );

  const removeCoupon = useCallback(
    async () => {
      if (!token || !selectedStoreId) throw new Error("Select a store first");
      const updated = await apiRemoveCoupon(token, selectedStoreId);
      setCart(updated);

      return updated;
    },
    [token, selectedStoreId]
  );

  const checkout = useCallback(
    async () => {
      if (!token || !selectedStoreId) throw new Error("Select a store first");
      const result = await apiCheckout(token, { storeId: selectedStoreId });

      return result;
    },
    [token, selectedStoreId]
  );

  const cancelCheckout = useCallback(
    async () => {
      if (!token || !selectedStoreId) return;
      await apiCancelCheckout(token, selectedStoreId);
      await refreshCart();
    },
    [token, selectedStoreId, refreshCart]
  );

  const itemCount = cart?.items?.reduce((sum, i) => sum + i.quantity, 0) ?? 0;

  return (
    <CartContext.Provider
      value={{
        cart,
        cartLoading,
        cartError,
        itemCount,
        selectedStoreId,
        setStoreId,
        addItem,
        updateItem,
        removeItem,
        clearCart,
        applyCoupon,
        applyPoints,
        removeCoupon,
        checkout,
        cancelCheckout,
        refreshCart,
      }}
    >
      {children}
    </CartContext.Provider>
  );
}

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