import style from '../styles/item-action.module.css';

import React, { useEffect, useState } from 'react';

import { Spinner, Tooltip } from '@chakra-ui/react';
import { MinusIcon, PlusIcon, Trash2Icon } from 'lucide-react';

import { CartItem } from '~/types/cart';
import { getAuth } from '~/libs/auth';
import { deleteUserCart, upsertUserCart } from '~/services/cart';

import { useDebounce } from 'usehooks-ts';
import { useCartStore } from '../stores/useCartStore';
import { useProductCartContext } from '@/contexts/ProductCartContext';
import {
  removeSelectedItemsFromCookie,
  removeCartItemsFromCookie,
  quantityUpdateState,
  getCartDataFromCookie,
  setCartDataToCookie,
} from '~/utils/cart';

import { toast } from 'react-hot-toast';

type Props = {
  item: CartItem;
};

const CartItemAction = ({ item }: Props) => {
  const auth = getAuth();
  const { setRefreshCart } = useProductCartContext();
  const [isLoadDelete, setIsLoadDelete] = useState<boolean>(false);
  const [isLoadQuantity, setIsLoadQuantity] = useState<boolean>(false);

  const [quantity, setQuantity] = useState<number>(item.quantity);

  const { loadCart, cart, updateCartItem } = useCartStore();

  const limitQty = item.limit_qty?.transaction || 0;

  const handleDelete = async () => {
    if (typeof auth !== 'object') return;

    setIsLoadDelete(true);

    try {
      // Delete from server
      await deleteUserCart(auth.id, [item.cart_id]);

      // Clean up cookies immediately
      removeSelectedItemsFromCookie([item.id]);
      removeCartItemsFromCookie([item.cart_id]);

      // Update local cart state optimistically
      if (cart) {
        const updatedProducts = cart.products.filter(
          (product) => product.id !== item.id
        );
        const updatedCart = {
          ...cart,
          products: updatedProducts,
          product_total: updatedProducts.length,
        };
        updateCartItem(updatedCart);
      }

      // Reload from server and refresh context
      await loadCart(auth.id);
      setRefreshCart(true);

      toast.success('Item berhasil dihapus');
    } catch (error) {
      console.error('Failed to delete cart item:', error);
      toast.error('Gagal menghapus item');

      // Reload on error
      await loadCart(auth.id);
    } finally {
      setIsLoadDelete(false);
    }
  };

  const updateQuantityInCookie = (productId, cartId, newQuantity) => {
    try {
      const cartData = getCartDataFromCookie();
      let itemFound = false;

      // Find item by cart_id key or search within objects
      if (cartData[cartId]) {
        cartData[cartId].quantity = newQuantity;
        itemFound = true;
      } else {
        // Search by product id or cart_id within objects
        for (const key in cartData) {
          const item = cartData[key];
          if (item.id === productId || item.cart_id === cartId) {
            item.quantity = newQuantity;
            itemFound = true;
            break;
          }
        }
      }

      if (itemFound) {
        setCartDataToCookie(cartData);
        return true;
      }

      return false;
    } catch (error) {
      console.error('Error updating quantity in cookie:', error);
      return false;
    }
  };

  const decreaseQty = () => {
    setQuantity((quantity) => (quantity -= 1));
  };

  const increaseQty = () => {
    setQuantity((quantity) => (quantity += 1));
  };

  const debounceQty = useDebounce(quantity, 1000);

  useEffect(() => {
    if (isNaN(debounceQty)) setQuantity(1);
    if (limitQty > 0 && debounceQty > limitQty) setQuantity(limitQty);
  }, [debounceQty, limitQty]);

  useEffect(() => {
    const updateCart = async () => {
      if (typeof auth !== 'object' || isNaN(debounceQty)) return;
      if (debounceQty === item.quantity) return;

      quantityUpdateState.startUpdate(item.id);
      setIsLoadQuantity(true);

      try {
        // Update cookie immediately for responsive UI
        updateQuantityInCookie(item.id, item.cart_id, debounceQty);

        // Update local cart state optimistically
        if (cart) {
          const updatedProducts = cart.products.map((product) =>
            product.id === item.id
              ? { ...product, quantity: debounceQty }
              : product
          );
          const updatedCart = {
            ...cart,
            products: updatedProducts,
          };
          updateCartItem(updatedCart);
        }

        // Send update to server
        await upsertUserCart({
          userId: auth.id,
          type: item.cart_type,
          id: item.id,
          qty: debounceQty,
          selected: item.selected,
        });

        // Reload from server to ensure consistency
        await loadCart(auth.id);

        // Re-update cookie if server reload overwrote it
        const currentCookieData = getCartDataFromCookie();
        let needsReUpdate = false;

        for (const key in currentCookieData) {
          const cookieItem = currentCookieData[key];
          if (
            (cookieItem.id === item.id ||
              cookieItem.cart_id === item.cart_id) &&
            cookieItem.quantity !== debounceQty
          ) {
            needsReUpdate = true;
            break;
          }
        }

        if (needsReUpdate) {
          updateQuantityInCookie(item.id, item.cart_id, debounceQty);
        }
      } catch (error) {
        console.error('Error updating quantity:', error);
        toast.error('Gagal mengupdate quantity');

        // Revert changes on error
        updateQuantityInCookie(item.id, item.cart_id, item.quantity);
        loadCart(auth.id);
      } finally {
        setIsLoadQuantity(false);
        quantityUpdateState.endUpdate(item.id);
      }
    };

    updateCart();
    //eslint-disable-next-line react-hooks/exhaustive-deps
  }, [debounceQty]);

  return (
    <div className={style.actionSection}>
      <button
        className={style.deleteButton}
        onClick={handleDelete}
        disabled={isLoadDelete}
      >
        {isLoadDelete && <Spinner size='xs' />}
        {!isLoadDelete && <Trash2Icon size={16} />}
      </button>

      <div className={style.quantitySection}>
        {isLoadQuantity && (
          <div className={style.quantityLoading}>
            <Spinner size='sm' />
          </div>
        )}

        <button
          className={style.quantityControl}
          onClick={decreaseQty}
          disabled={quantity <= 1}
        >
          <MinusIcon size={16} />
        </button>

        <input
          type='number'
          className={style.quantity.toString()}
          onChange={(e) => setQuantity(parseInt(e.target.value))}
          value={quantity}
        />

        <Tooltip label={limitQty > 0 ? `Max. ${limitQty}` : ''}>
          <button
            className={style.quantityControl}
            onClick={increaseQty}
            disabled={limitQty > 0 && quantity >= limitQty}
          >
            <PlusIcon size={16} />
          </button>
        </Tooltip>
      </div>
    </div>
  );
};

export default CartItemAction;