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

import React, { useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import {
  Button,
  Checkbox,
  Spinner,
  Tooltip,
  Text,
  Box,
  Flex,
} 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,
  setSelectedItemsToCookie,
  syncSelectedItemsWithCookie,
  setAllSelectedInCookie,
  removeSelectedItemsFromCookie,
  forceResetAllSelectedItems,
  checkboxUpdateState,
} from '~/utils/cart';

// Special ID for the "select all" checkbox
const SELECT_ALL_ID = 'select_all_checkbox';

const CartPage = () => {
  const router = useRouter();
  const auth = getAuth();
  const [isStepApproval, setIsStepApproval] = useState(false);
  const [isLoad, setIsLoad] = 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(true);
  const [isUpdating, setIsUpdating] = useState(false);
  const [isStateMismatch, setIsStateMismatch] = useState(false);
  const [isAnyCheckboxUpdating, setIsAnyCheckboxUpdating] = useState(false);

  // Subscribe to checkbox update state changes
  useEffect(() => {
    const handleUpdateStateChange = (isUpdating) => {
      setIsAnyCheckboxUpdating(isUpdating);
    };

    // Add listener for checkbox update state changes
    checkboxUpdateState.addListener(handleUpdateStateChange);

    // Cleanup listener on component unmount
    return () => {
      checkboxUpdateState.removeListener(handleUpdateStateChange);
    };
  }, []);

  // Function to check if cart state is inconsistent
  const checkCartStateMismatch = () => {
    if (!cart || !cart.products || isUpdating) return false;

    try {
      // Ambil status selected dari cookie
      const selectedItems = getSelectedItemsFromCookie();

      // Periksa ketidaksesuaian antara UI dan cookie
      // 1. Periksa item yang selected di UI tapi tidak di cookie
      for (const product of cart.products) {
        const cookieState = selectedItems[product.id];

        // Jika ada di cookie tapi tidak sama dengan UI
        if (cookieState !== undefined && cookieState !== product.selected) {
          return true;
        }

        // Jika tidak ada di cookie tapi selected di UI
        if (cookieState === undefined && product.selected) {
          return true;
        }
      }

      // 2. Periksa item yang selected di cookie tapi tidak ada di cart
      for (const productId in selectedItems) {
        const isSelected = selectedItems[productId];
        if (isSelected) {
          // Cek apakah product id ini ada di cart
          const productExists = cart.products.some(
            (p) => p.id.toString() === productId.toString()
          );
          if (!productExists) {
            // Ada item selected di cookie yang tidak ada di cart
            return true;
          }
        }
      }

      return false;
    } catch (error) {
      console.error('Error checking cart state mismatch:', error);
      return false;
    }
  };

  // Function to reset all selected items when state is inconsistent
  const handleResetSelections = () => {
    if (!cart) return;

    setIsUpdating(true);

    try {
      // Use the forceResetSelection function from the store
      useCartStore.getState().forceResetSelection();

      // Set state back to normal
      setIsStateMismatch(false);

      // Give visual feedback
      toast.success('Semua pilihan telah direset');

      // Optional: Sync with server if needed
      if (typeof auth === 'object') {
        const updatePromises = cart.products.map((item) =>
          upsertUserCart({
            userId: auth.id,
            type: item.cart_type,
            id: item.id,
            qty: item.quantity,
            selected: false,
            purchase_tax_id: item.purchase_tax_id || null, // Fix integer field issue
          })
        );

        Promise.all(updatePromises)
          .then(() => loadCart(auth.id))
          .catch((error) => {
            console.error('Error updating selections to server:', error);
          })
          .finally(() => {
            setIsUpdating(false);
          });
      } else {
        setIsUpdating(false);
      }
    } catch (error) {
      console.error('Error resetting selections:', error);
      setIsUpdating(false);
      toast.error('Gagal mereset pilihan');
    }
  };

  // Check for state inconsistency
  useEffect(() => {
    if (!cart || !cart.products || isUpdating) return;

    const hasMismatch = checkCartStateMismatch();
    setIsStateMismatch(hasMismatch);
  }, [cart, isUpdating]);

  useEffect(() => {
    const handleScroll = () => {
      setIsTop(window.scrollY < 200);
    };

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

  useEffect(() => {
    const loadCartWithStorage = async () => {
      if (typeof auth === 'object' && !cart) {
        await loadCart(auth.id);
        setIsStepApproval(auth?.feature?.soApproval);

        // Sync selected items with server data using cookies
        if (cart?.products) {
          const { items, needsUpdate } = syncSelectedItemsWithCookie(
            cart.products
          );

          // If there's a mismatch between cookie and server data, update the UI
          if (needsUpdate) {
            const updatedCart = {
              ...cart,
              products: cart.products.map((item) => ({
                ...item,
                selected:
                  items[item.id] !== undefined ? items[item.id] : item.selected,
              })),
            };
            updateCartItem(updatedCart);
          }
        }
      }
    };

    loadCartWithStorage();
  }, [auth, cart]);

  const hasSelectedPromo = useMemo(() => {
    if (!cart) return false;
    return cart?.products?.some(
      (item) => item.cart_type === 'promotion' && item.selected
    );
  }, [cart]);

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

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

  const hasSelectedAll = useMemo(() => {
    if (!cart || !Array.isArray(cart.products)) return false;
    return (
      cart.products.length > 0 && cart.products.every((item) => item.selected)
    );
  }, [cart]);

  const handleCheckout = () => {
    if (isUpdating || isLoadDelete || isAnyCheckboxUpdating) {
      toast.error('Harap tunggu pembaruan selesai');
      return;
    }
    router.push('/shop/checkout');
  };

  const handleQuotation = () => {
    if (isUpdating || isLoadDelete || isAnyCheckboxUpdating) {
      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 handleChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    if (cart && !isUpdating && typeof auth === 'object') {
      const newSelectedState = !hasSelectedAll;

      // Set updating flag
      setIsUpdating(true);

      // Notify checkbox update state system with the special select all ID
      checkboxUpdateState.startUpdate(SELECT_ALL_ID);

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

      updateCartItem(updatedCart);

      // Get all product IDs in cart
      const productIds = cart.products.map((item) => item.id);

      // Update cookies immediately for responsive UI
      setAllSelectedInCookie(productIds, newSelectedState, false); // We're already notifying

      try {
        // Update all items on server in background
        const updatePromises = cart.products.map((item) =>
          upsertUserCart({
            userId: auth.id,
            type: item.cart_type,
            id: item.id,
            qty: item.quantity,
            selected: newSelectedState,
            purchase_tax_id: item.purchase_tax_id || null, // Fix integer field issue
          })
        );

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

        // Revert changes on error
        const revertedCart = {
          ...cart,
          products: cart.products.map((item) => ({
            ...item,
            selected: !newSelectedState,
          })),
        };

        updateCartItem(revertedCart);

        // Revert cookies
        setAllSelectedInCookie(productIds, !newSelectedState, false);

        toast.error('Gagal memperbarui pilihan');
      } finally {
        setIsUpdating(false);

        // End update notification
        checkboxUpdateState.endUpdate(SELECT_ALL_ID);
      }
    }
  };

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

    setIsLoadDelete(true);
    checkboxUpdateState.startUpdate('delete_operation');

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

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

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

      // Step 3: Clean up cookies AFTER state update
      removeSelectedItemsFromCookie(itemIdsToDelete);
      removeCartItemsFromCookie(cartIdsToDelete);

      // Step 4: Reload from server to ensure consistency (but don't wait for it to complete UI update)
      loadCart(auth.id)
        .then(() => {
          console.log('Cart reloaded from server');
        })
        .catch((error) => {
          console.error('Error reloading cart:', error);
          // If reload fails, at least we have the optimistic update
        });

      // Step 5: Trigger context refresh
      setRefreshCart(true);

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

      // If deletion failed, reload cart to restore proper state
      loadCart(auth.id);
    } finally {
      setIsLoadDelete(false);
      checkboxUpdateState.endUpdate('delete_operation');
    }
  };

  // Check if buttons should be disabled
  const areButtonsDisabled =
    isUpdating || isLoadDelete || isAnyCheckboxUpdating;

  // Only disable the select all checkbox if it specifically is updating
  const isSelectAllDisabled =
    isUpdating || checkboxUpdateState.isCheckboxUpdating(SELECT_ALL_ID);

  return (
    <>
      <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={handleChange}
              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={clsxm({
                'Tidak ada item yang dipilih': !hasSelected,
                'Harap tunggu pembaruan selesai': areButtonsDisabled,
              })}
            >
              <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>

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

            <div
              className={
                isStepApproval
                  ? style['summary-buttons-step-approval']
                  : style['summary-buttons']
              }
            >
              <Tooltip
                label={clsxm({
                  'Barang promo tidak dapat dibuat quotation': hasSelectedPromo,
                  'Harap tunggu pembaruan selesai': areButtonsDisabled,
                  'Tidak ada item yang dipilih': !hasSelected,
                })}
              >
                <Button
                  colorScheme='yellow'
                  w='full'
                  isDisabled={
                    hasSelectedPromo || !hasSelected || areButtonsDisabled
                  }
                  onClick={handleQuotation}
                >
                  {areButtonsDisabled ? <Spinner size='sm' mr={2} /> : null}
                  Quotation
                </Button>
              </Tooltip>
              {!isStepApproval && (
                <Tooltip
                  label={clsxm({
                    'Tidak ada item yang dipilih': !hasSelected,
                    'Terdapat item yang tidak ada harga': hasSelectNoPrice,
                    'Harap tunggu pembaruan selesai': areButtonsDisabled,
                  })}
                >
                  <Button
                    colorScheme='red'
                    w='full'
                    isDisabled={
                      !hasSelected || hasSelectNoPrice || areButtonsDisabled
                    }
                    onClick={handleCheckout}
                  >
                    {areButtonsDisabled ? <Spinner size='sm' mr={2} /> : null}
                    Checkout
                  </Button>
                </Tooltip>
              )}
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default CartPage;
