"use client";

import React, { createContext, useContext, useEffect, useMemo, useState } from "react";
import type { Product } from "@/data/products";
import { api, mediaOrPlaceholder } from "@/lib/api";
import { useAuth } from "@/context/AuthContext";

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

interface CartContextType {
  items: CartItem[];
  addToCart: (product: Product, color: string, variantId?: number | null) => void;
  removeFromCart: (productId: string, color: string) => void;
  updateQuantity: (productId: string, color: string, quantity: number) => void;
  clearCart: () => void;
  totalItems: number;
  totalPrice: number;
  isCartOpen: boolean;
  openCart: () => void;
  closeCart: () => void;
}

const CartContext = createContext<CartContextType | undefined>(undefined);

export const CartProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const { token, user } = useAuth();
  const [items, setItems] = useState<CartItem[]>([]);
  const [isCartOpen, setIsCartOpen] = useState(false);

  const openCart = () => setIsCartOpen(true);
  const closeCart = () => setIsCartOpen(false);

  const hydrateCart = async () => {
    if (!token || !user) {
      setItems([]);
      return;
    }
    try {
      const result = await api.cart.get(token);
      const hydrated = await Promise.all(
        result.items.map(async (item) => {
          const detail = await api.catalog.productById(item.product_id);
          const images = detail.images?.length
            ? detail.images
            : await api.catalog.productImages(item.product_id).catch(() => []);
          const image = mediaOrPlaceholder(
            images.find((img) => Boolean(img.is_main))?.image || images[0]?.image,
          );

          const product: Product = {
            id: String(detail.id),
            name: detail.name,
            brand: detail.brand_name || "Brand",
            category: detail.category_name || "Category",
            price: Number(detail.sale_price || detail.selling_price),
            originalPrice: detail.sale_price ? Number(detail.selling_price) : undefined,
            description: detail.description || "",
            longDescription: detail.description || "",
            features: [`SKU: ${detail.sku}`],
            specifications: { SKU: detail.sku },
            colors: [{ name: item.selected_color || "Default", hex: "#9ca3af", image }],
            rating: 4.5,
            reviews: 0,
            badge: detail.featured ? "Featured" : undefined,
          };

          return {
            product,
            quantity: item.quantity,
            selectedColor: item.selected_color || "Default",
            variantId: item.variant_id,
          };
        }),
      );
      setItems(hydrated);
    } catch {
      setItems([]);
    }
  };

  useEffect(() => {
    void hydrateCart();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [token, user?.id]);

  const addToCart = (product: Product, color: string, variantId?: number | null) => {
    setItems((prev) => {
      const existing = prev.find((i) => i.product.id === product.id && i.selectedColor === color);
      if (existing) {
        return prev.map((i) =>
          i.product.id === product.id && i.selectedColor === color
            ? { ...i, quantity: i.quantity + 1 }
            : i,
        );
      }
      return [...prev, { product, quantity: 1, selectedColor: color, variantId: variantId ?? null }];
    });
    setIsCartOpen(true);
    if (token) {
      void api.cart.addItem(
        {
          product_id: Number(product.id),
          quantity: 1,
          selected_color: color,
          variant_id: variantId ?? null,
        },
        token,
      );
    }
  };

  const removeFromCart = (productId: string, color: string) => {
    setItems((prev) => prev.filter((i) => !(i.product.id === productId && i.selectedColor === color)));
    if (token) {
      void api.cart.get(token).then((cartData) => {
        const item = cartData.items.find(
          (cartItem) =>
            String(cartItem.product_id) === productId &&
            (cartItem.selected_color || "Default") === color,
        );
        if (item) void api.cart.deleteItem(item.id, token);
      });
    }
  };

  const updateQuantity = (productId: string, color: string, quantity: number) => {
    if (quantity <= 0) return removeFromCart(productId, color);
    setItems((prev) =>
      prev.map((i) =>
        i.product.id === productId && i.selectedColor === color ? { ...i, quantity } : i,
      ),
    );
    if (token) {
      void api.cart.get(token).then((cartData) => {
        const item = cartData.items.find(
          (cartItem) =>
            String(cartItem.product_id) === productId &&
            (cartItem.selected_color || "Default") === color,
        );
        if (item) void api.cart.updateItem(item.id, { quantity, selected_color: color }, token);
      });
    }
  };

  const clearCart = () => {
    if (token) {
      void api.cart.get(token).then((cartData) => {
        cartData.items.forEach((item) => {
          void api.cart.deleteItem(item.id, token);
        });
      });
    }
    setItems([]);
  };

  const totalItems = useMemo(() => items.reduce((sum, i) => sum + i.quantity, 0), [items]);
  const totalPrice = useMemo(
    () => items.reduce((sum, i) => sum + i.product.price * i.quantity, 0),
    [items],
  );

  return (
    <CartContext.Provider
      value={{
        items,
        addToCart,
        removeFromCart,
        updateQuantity,
        clearCart,
        totalItems,
        totalPrice,
        isCartOpen,
        openCart,
        closeCart,
      }}
    >
      {children}
    </CartContext.Provider>
  );
};

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