"use client";

import {
  createContext,
  ReactNode,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";

export type CartItem = {
  productId: string;
  productSlug: string;
  productName: string;

  variantId: string | null;
  variantName: string | null;

  unitPrice: number;
  quantity: number;

  imageUrl: string | null;
};

type AddCartItem = CartItem;

type CartContextType = {
  items: CartItem[];

  ready: boolean;

  totalItems: number;

  subtotal: number;

  addItem: (item: AddCartItem) => void;

  updateQuantity: (
    productId: string,
    variantId: string | null,
    quantity: number
  ) => void;

  removeItem: (
    productId: string,
    variantId: string | null
  ) => void;

  clearCart: () => void;
};

const CartContext =
  createContext<CartContextType | undefined>(
    undefined
  );

const STORAGE_KEY =
  "pelcy-cart";


export function CartProvider({
  children,
}: {
  children: ReactNode;
}) {
  const [items, setItems] =
    useState<CartItem[]>([]);

  const [ready, setReady] =
    useState(false);


  // =============================================
  // LOAD CART
  // =============================================

  useEffect(() => {
    try {
      const savedCart =
        window.localStorage.getItem(
          STORAGE_KEY
        );

      if (savedCart) {
        const parsed =
          JSON.parse(savedCart);

        if (Array.isArray(parsed)) {
          setItems(parsed);
        }
      }
    } catch (error) {
      console.error(
        "Could not load PELCY cart:",
        error
      );
    } finally {
      setReady(true);
    }
  }, []);


  // =============================================
  // SAVE CART
  // =============================================

  useEffect(() => {
    if (!ready) {
      return;
    }

    try {
      window.localStorage.setItem(
        STORAGE_KEY,
        JSON.stringify(items)
      );
    } catch (error) {
      console.error(
        "Could not save PELCY cart:",
        error
      );
    }
  }, [
    items,
    ready,
  ]);


  // =============================================
  // ADD TO CART
  // =============================================

  const addItem =
    useCallback(
      (
        newItem: AddCartItem
      ) => {
        const cleanQuantity =
          Math.max(
            1,
            Math.floor(
              Number(
                newItem.quantity
              )
            )
          );

        setItems(
          (
            currentItems
          ) => {
            const existingIndex =
              currentItems.findIndex(
                (item) =>
                  item.productId ===
                    newItem.productId &&
                  item.variantId ===
                    newItem.variantId
              );

            if (
              existingIndex ===
              -1
            ) {
              return [
                ...currentItems,
                {
                  ...newItem,
                  quantity:
                    cleanQuantity,
                },
              ];
            }

            return currentItems.map(
              (
                item,
                index
              ) =>
                index ===
                existingIndex
                  ? {
                      ...item,
                      quantity:
                        item.quantity +
                        cleanQuantity,
                    }
                  : item
            );
          }
        );
      },
      []
    );


  // =============================================
  // UPDATE QUANTITY
  // =============================================

  const updateQuantity =
    useCallback(
      (
        productId: string,
        variantId:
          | string
          | null,
        quantity: number
      ) => {
        const cleanQuantity =
          Math.max(
            1,
            Math.floor(
              Number(
                quantity
              )
            )
          );

        setItems(
          (
            currentItems
          ) =>
            currentItems.map(
              (item) =>
                item.productId ===
                  productId &&
                item.variantId ===
                  variantId
                  ? {
                      ...item,
                      quantity:
                        cleanQuantity,
                    }
                  : item
            )
        );
      },
      []
    );


  // =============================================
  // REMOVE ITEM
  // =============================================

  const removeItem =
    useCallback(
      (
        productId: string,
        variantId:
          | string
          | null
      ) => {
        setItems(
          (
            currentItems
          ) =>
            currentItems.filter(
              (item) =>
                !(
                  item.productId ===
                    productId &&
                  item.variantId ===
                    variantId
                )
            )
        );
      },
      []
    );


  // =============================================
  // CLEAR CART
  // =============================================
  //
  // IMPORTANT:
  // useCallback keeps this function stable between
  // renders. This prevents PaymentSuccessClient's
  // useEffect from repeatedly firing.
  // =============================================

  const clearCart =
    useCallback(
      () => {
        setItems(
          (
            currentItems
          ) => {
            if (
              currentItems.length ===
              0
            ) {
              return currentItems;
            }

            return [];
          }
        );

        try {
          window.localStorage.removeItem(
            STORAGE_KEY
          );
        } catch (error) {
          console.error(
            "Could not clear PELCY cart storage:",
            error
          );
        }
      },
      []
    );


  // =============================================
  // TOTAL ITEMS
  // =============================================

  const totalItems =
    useMemo(
      () =>
        items.reduce(
          (
            total,
            item
          ) =>
            total +
            item.quantity,
          0
        ),
      [
        items,
      ]
    );


  // =============================================
  // SUBTOTAL
  // =============================================

  const subtotal =
    useMemo(
      () =>
        items.reduce(
          (
            total,
            item
          ) =>
            total +
            item.unitPrice *
              item.quantity,
          0
        ),
      [
        items,
      ]
    );


  // =============================================
  // STABLE CONTEXT VALUE
  // =============================================

  const contextValue =
    useMemo<CartContextType>(
      () => ({
        items,
        ready,
        totalItems,
        subtotal,
        addItem,
        updateQuantity,
        removeItem,
        clearCart,
      }),
      [
        items,
        ready,
        totalItems,
        subtotal,
        addItem,
        updateQuantity,
        removeItem,
        clearCart,
      ]
    );


  return (
    <CartContext.Provider
      value={
        contextValue
      }
    >
      {children}
    </CartContext.Provider>
  );
}


export function useCart() {
  const context =
    useContext(
      CartContext
    );

  if (!context) {
    throw new Error(
      "useCart must be used inside CartProvider."
    );
  }

  return context;
}