import React, {
  createContext,
  useContext,
  useState,
  useEffect,
  useCallback,
  useMemo,
} from "react";
import axios from "axios";
import { useAuth } from "./AuthContext";

const CartContext = createContext(null);

const API = `${process.env.REACT_APP_BACKEND_URL}/api`;

export const CartProvider = ({ children }) => {
  const [cartItems, setCartItems] = useState([]);
  const [loading, setLoading] = useState(false);
  const { token, isAuthenticated } = useAuth();

  const fetchCart = useCallback(async () => {
    if (!isAuthenticated) {
      setCartItems([]);
      return;
    }

    setLoading(true);
    try {
      const response = await axios.get(`${API}/cart`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      setCartItems(response.data);
    } catch (error) {
      console.error("Failed to fetch cart:", error);
    } finally {
      setLoading(false);
    }
  }, [isAuthenticated, token]);

  useEffect(() => {
    fetchCart();
  }, [fetchCart]);

  const addToCart = useCallback(
    async (productId, quantity = 1) => {
      if (!isAuthenticated) {
        throw new Error("Please login to add items to cart");
      }

      try {
        await axios.post(
          `${API}/cart/add`,
          { product_id: productId, quantity },
          { headers: { Authorization: `Bearer ${token}` } }
        );
        await fetchCart();
      } catch (error) {
        throw error;
      }
    },
    [isAuthenticated, token, fetchCart]
  );

  const updateQuantity = useCallback(
    async (itemId, quantity) => {
      try {
        await axios.put(
          `${API}/cart/${itemId}?quantity=${quantity}`,
          {},
          {
            headers: { Authorization: `Bearer ${token}` },
          }
        );
        await fetchCart();
      } catch (error) {
        throw error;
      }
    },
    [token, fetchCart]
  );

  const removeFromCart = useCallback(
    async (itemId) => {
      try {
        await axios.delete(`${API}/cart/${itemId}`, {
          headers: { Authorization: `Bearer ${token}` },
        });
        await fetchCart();
      } catch (error) {
        throw error;
      }
    },
    [token, fetchCart]
  );

  const clearCart = useCallback(async () => {
    try {
      await axios.delete(`${API}/cart`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      setCartItems([]);
    } catch (error) {
      throw error;
    }
  }, [token]);

  const cartTotal = useMemo(
    () =>
      cartItems.reduce((total, item) => {
        return total + (item.product?.price || 0) * item.quantity;
      }, 0),
    [cartItems]
  );

  const cartCount = useMemo(
    () => cartItems.reduce((count, item) => count + item.quantity, 0),
    [cartItems]
  );

  const value = useMemo(
    () => ({
      cartItems,
      loading,
      addToCart,
      updateQuantity,
      removeFromCart,
      clearCart,
      cartTotal,
      cartCount,
      fetchCart,
    }),
    [
      cartItems,
      loading,
      addToCart,
      updateQuantity,
      removeFromCart,
      clearCart,
      cartTotal,
      cartCount,
      fetchCart,
    ]
  );

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

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