import style from './cart.module.css';

import React, { useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import { Button, Checkbox, Spinner, Tooltip } from '@chakra-ui/react';
import { toast } from 'react-hot-toast';
import { useRouter } from 'next/router';
import { getAuth } from '~/libs/auth';
import { useCartStore } from '~/modules/cart/stores/useCartStore';

import CartItemModule from '~/modules/cart/components/Item';
import CartSummary from '~/modules/cart/components/Summary';
import clsxm from '~/libs/clsxm';
import useDevice from '@/core/hooks/useDevice';
import CartSummaryMobile from '~/modules/cart/components/CartSummaryMobile';
import Image from '~/components/ui/image';
import { deleteUserCart, upsertUserCart } from '~/services/cart';
import { Trash2Icon } from 'lucide-react';
import { useProductCartContext } from '@/contexts/ProductCartContext';
import {
  getSelectedItemsFromCookie,
  syncSelectedItemsWithCookie,
  setAllSelectedInCookie,
  removeSelectedItemsFromCookie,
  removeCartItemsFromCookie,
  checkboxUpdateState,
  quantityUpdateState,
} from '~/utils/cart';

const SELECT_ALL_ID = 'select_all_checkbox';

const CartPage: React.FC = () => {
  const router = useRouter();
  const auth = getAuth();
  const [isStepApproval, setIsStepApproval] = useState<boolean>(false);
  const [isLoadDelete, setIsLoadDelete] = useState<boolean>(false);
  const { loadCart, cart, summary, updateCartItem } = useCartStore();
  const device = useDevice();
  const { setRefreshCart } = useProductCartContext();
  const [isTop, setIsTop] = useState<boolean>(true);
  const [isUpdating, setIsUpdating] = useState<boolean>(false);
  const [isAnyCheckboxUpdating, setIsAnyCheckboxUpdating] =
    useState<boolean>(false);
  const [isAnyQuantityUpdating, setIsAnyQuantityUpdating] =
    useState<boolean>(false);

  // Subscribe to update state changes
  useEffect(() => {
    const handleCheckboxUpdate = (isUpdating: boolean): void =>
      setIsAnyCheckboxUpdating(isUpdating);
    const handleQuantityUpdate = (isUpdating: boolean): void =>
      setIsAnyQuantityUpdating(isUpdating);

    checkboxUpdateState.addListener(handleCheckboxUpdate);
    quantityUpdateState.addListener(handleQuantityUpdate);

    return () => {
      checkboxUpdateState.removeListener(handleCheckboxUpdate);
      quantityUpdateState.removeListener(handleQuantityUpdate);
    };
  }, []);

  // Handle scroll for sticky header styling
  useEffect(() => {
    const handleScroll = (): void => setIsTop(window.scrollY < 200);

    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  // Initialize cart and sync with cookies
  useEffect(() => {
    const initializeCart = async (): Promise<void> => {
      if (typeof auth === 'object' && !cart) {
        await loadCart(auth.id);
        setIsStepApproval(auth?.feature?.soApproval);
      }
    };

    initializeCart();
  }, [auth, cart, loadCart]);

  // Separate effect to sync with cookies after cart is loaded
  useEffect(() => {
    if (cart?.products) {
      const { items, needsUpdate } = syncSelectedItemsWithCookie(cart.products);
      const typedItems = items as Record<number, boolean>;

      if (needsUpdate) {
        const updatedCart = {
          ...cart,
          products: cart.products.map((item) => ({
            ...item,
            selected:
              typedItems[item.id] !== undefined
                ? typedItems[item.id]
                : item.selected,
          })),
        };
        updateCartItem(updatedCart);
      }
    }
  }, [cart, updateCartItem]);

  // Computed values
  const hasSelectedPromo = useMemo((): boolean => {
    return (
      cart?.products?.some(
        (item) => item.cart_type === 'promotion' && item.selected
      ) || false
    );
  }, [cart]);

  const hasSelected = useMemo((): boolean => {
    return cart?.products?.some((item) => item.selected) || false;
  }, [cart]);

  const hasSelectNoPrice = useMemo((): boolean => {
    return (
      cart?.products?.some(
        (item) => item.selected && item.price.price_discount === 0
      ) || false
    );
  }, [cart]);

  const hasSelectedAll = useMemo((): boolean => {
    if (!cart?.products?.length) return false;
    return cart.products.every((item) => item.selected);
  }, [cart]);

  // Button states
  const areButtonsDisabled: boolean =
    isUpdating ||
    isLoadDelete ||
    isAnyCheckboxUpdating ||
    isAnyQuantityUpdating;
  const isSelectAllDisabled: boolean =
    isUpdating || checkboxUpdateState.isCheckboxUpdating();

  // Handlers
  const handleCheckout = (): void => {
    if (areButtonsDisabled) {
      toast.error('Harap tunggu pembaruan selesai');
      return;
    }
    router.push('/shop/checkout');
  };

  const handleQuotation = (): void => {
    if (areButtonsDisabled) {
      toast.error('Harap tunggu pembaruan selesai');
      return;
    }
    if (hasSelectedPromo || !hasSelected) {
      toast.error('Maaf, Barang promo tidak dapat dibuat quotation');
    } else {
      router.push('/shop/quotation');
    }
  };

  const handleSelectAll = async (
    e: React.ChangeEvent<HTMLInputElement>
  ): Promise<void> => {
    if (!cart || isUpdating || typeof auth !== 'object') return;

    const newSelectedState = !hasSelectedAll;
    setIsUpdating(true);
    checkboxUpdateState.startUpdate();

    try {
      // Update UI immediately
      const updatedCart = {
        ...cart,
        products: cart.products.map((item) => ({
          ...item,
          selected: newSelectedState,
        })),
      };
      updateCartItem(updatedCart);

      // Update cookies
      const productIds = cart.products.map((item) => item.id);
      setAllSelectedInCookie(productIds, newSelectedState, false);

      // Update server
      const updatePromises = cart.products.map((item) =>
        upsertUserCart({
          userId: auth.id,
          type: item.cart_type,
          id: item.id,
          qty: item.quantity,
          selected: newSelectedState,
        })
      );

      await Promise.all(updatePromises);
      await loadCart(auth.id);
    } catch (error) {
      console.error('Error updating select all:', error);
      toast.error('Gagal memperbarui pilihan');

      // Revert on error
      const revertedCart = {
        ...cart,
        products: cart.products.map((item) => ({
          ...item,
          selected: !newSelectedState,
        })),
      };
      updateCartItem(revertedCart);
      setAllSelectedInCookie(
        cart.products.map((item) => item.id),
        !newSelectedState,
        false
      );
    } finally {
      setIsUpdating(false);
      checkboxUpdateState.endUpdate();
    }
  };

  const handleDelete = async (): Promise<void> => {
    if (typeof auth !== 'object' || !cart) return;

    setIsLoadDelete(true);
    checkboxUpdateState.startUpdate();

    try {
      const itemsToDelete = cart.products.filter((item) => item.selected);
      const itemIdsToDelete = itemsToDelete.map((item) => item.id);
      const cartIdsToDelete = itemsToDelete.map((item) => item.cart_id);

      // Delete from server
      for (const item of itemsToDelete) {
        await deleteUserCart(auth.id, [item.cart_id]);
      }

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

      // Clean up cookies
      removeSelectedItemsFromCookie(itemIdsToDelete);
      removeCartItemsFromCookie(cartIdsToDelete.map(String));

      // Reload from server
      loadCart(auth.id).catch((error) =>
        console.error('Error reloading cart:', error)
      );

      setRefreshCart(true);
      toast.success('Item berhasil dihapus');
    } catch (error) {
      console.error('Failed to delete cart items:', error);
      toast.error('Gagal menghapus item');
      loadCart(auth.id);
    } finally {
      setIsLoadDelete(false);
      checkboxUpdateState.endUpdate();
    }
  };

  // Tooltip messages
  const getTooltipMessage = (): string => {
    if (isAnyQuantityUpdating) return 'Harap tunggu update quantity selesai';
    if (isAnyCheckboxUpdating) return 'Harap tunggu pembaruan checkbox selesai';
    if (isLoadDelete) return 'Harap tunggu penghapusan selesai';
    if (isUpdating) return 'Harap tunggu pembaruan selesai';
    return '';
  };

  const getQuotationTooltip = (): string => {
    const baseMessage = getTooltipMessage();
    if (baseMessage) return baseMessage;
    if (hasSelectedPromo) return 'Barang promo tidak dapat dibuat quotation';
    if (!hasSelected) return 'Tidak ada item yang dipilih';
    return '';
  };

  const getCheckoutTooltip = (): string => {
    const baseMessage = getTooltipMessage();
    if (baseMessage) return baseMessage;
    if (!hasSelected) return 'Tidak ada item yang dipilih';
    if (hasSelectNoPrice) return 'Terdapat item yang tidak ada harga';
    return '';
  };

  const getDeleteTooltip = (): string => {
    const baseMessage = getTooltipMessage();
    if (baseMessage) return baseMessage;
    if (!hasSelected) return 'Tidak ada item yang dipilih';
    return '';
  };

  return (
    <>
      {/* Sticky Header */}
      <div
        className={`${
          isTop ? 'border-b-[0px]' : 'border-b-[1px]'
        } sticky md:top-[157px] flex-col bg-white py-4 border-gray-300 z-50 sm:w-full md:w-3/4`}
      >
        <div className='flex items-center justify-between mb-2'>
          <h1 className={style.title}>Keranjang Belanja</h1>
        </div>

        <div className='h-2' />
        <div className='flex items-center object-center justify-between flex-wrap gap-2'>
          <div className='flex items-center object-center'>
            <Checkbox
              borderColor='gray.600'
              colorScheme='red'
              size='lg'
              isChecked={hasSelectedAll}
              onChange={handleSelectAll}
              isDisabled={isSelectAllDisabled}
              opacity={isSelectAllDisabled ? 0.5 : 1}
              cursor={isSelectAllDisabled ? 'not-allowed' : 'pointer'}
              _disabled={{
                opacity: 0.5,
                cursor: 'not-allowed',
                backgroundColor: 'gray.100',
              }}
            />
            <p className='p-2 text-caption-2'>
              {hasSelectedAll ? 'Uncheck all' : 'Select all'}
            </p>
          </div>

          <div className='flex items-center object-center'>
            <Tooltip label={getDeleteTooltip()}>
              <Button
                bg='#fadede'
                variant='outline'
                colorScheme='red'
                w='auto'
                size={device.isMobile ? 'sm' : 'md'}
                isDisabled={!hasSelected || areButtonsDisabled}
                onClick={handleDelete}
              >
                {isLoadDelete && <Spinner size='xs' />}
                {!isLoadDelete && <Trash2Icon size={16} />}
                <p className='text-sm ml-2'>Hapus Barang</p>
              </Button>
            </Tooltip>
          </div>
        </div>
      </div>

      {/* Main Content */}
      <div className={style.content}>
        <div className={style['item-wrapper']}>
          <div className={style['item-skeleton']}>
            {!cart && <CartItemModule.Skeleton count={5} height='120px' />}
          </div>

          <div className={style.items}>
            {cart?.products?.map((item) => (
              <CartItemModule key={item.id} item={item} />
            ))}

            {cart?.products?.length === 0 && (
              <div className='flex flex-col items-center p-4'>
                <Image
                  src='/images/empty_cart.svg'
                  alt='Empty Cart'
                  width={450}
                  height={450}
                />
                <div className='text-title-sm md:text-title-lg text-center font-semibold'>
                  Keranjangnya masih kosong nih
                </div>
                <div className='text-body-2 md:text-body-1 text-center mt-3'>
                  Yuk, tambahin barang-barang yang kamu mau ke keranjang
                  sekarang!
                  <br />
                  Ada banyak potongan belanjanya pakai kode voucher
                </div>
                <Link
                  href='/'
                  className='btn-solid-red rounded-full text-body-1 mt-6'
                >
                  Mulai Belanja
                </Link>
              </div>
            )}
          </div>
        </div>

        {/* Cart Summary */}
        <div
          className={`${style['summary-wrapper']} ${
            device.isMobile && (!cart || cart?.product_total === 0)
              ? 'hidden'
              : ''
          }`}
        >
          <div className={style.summary}>
            {device.isMobile ? (
              <CartSummaryMobile {...summary} isLoaded={!!cart} />
            ) : (
              <CartSummary {...summary} isLoaded={!!cart} />
            )}

            <div
              className={
                isStepApproval
                  ? style['summary-buttons-step-approval']
                  : style['summary-buttons']
              }
            >
              <Tooltip label={getQuotationTooltip()}>
                <Button
                  colorScheme='yellow'
                  w='full'
                  isDisabled={
                    hasSelectedPromo || !hasSelected || areButtonsDisabled
                  }
                  onClick={handleQuotation}
                >
                  {areButtonsDisabled && <Spinner size='sm' mr={2} />}
                  Quotation
                </Button>
              </Tooltip>

              {!isStepApproval && (
                <Tooltip label={getCheckoutTooltip()}>
                  <Button
                    colorScheme='red'
                    w='full'
                    isDisabled={
                      !hasSelected || hasSelectNoPrice || areButtonsDisabled
                    }
                    onClick={handleCheckout}
                  >
                    {areButtonsDisabled && <Spinner size='sm' mr={2} />}
                    Checkout
                  </Button>
                </Tooltip>
              )}
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default CartPage;
