import clsx from 'clsx';
import {
  useGetCheckoutLoyaltyBalanceQuery,
  usePayWithLoyaltyBalanceMutation
} from '@akinon/next/data/client/checkout';
import { useAppSelector } from '@akinon/next/redux/hooks';
import { useEffect, useMemo, useState } from 'react';
import { useLocalization } from '@akinon/next/hooks';
import { twMerge } from 'tailwind-merge';
import { Icon, Price } from '@theme/components';
import { Trans } from '@akinon/next/components';
import { LoaderSpinner } from '@theme/components';
import { AccountUsage, LoyaltyBalanceItem } from '@akinon/next/types';

export const StoreCredits = () => {
  const { t } = useLocalization();

  const [payWithLoyaltyBalance, { isLoading: isPayLoading }] =
    usePayWithLoyaltyBalanceMutation();

  const { loyaltyBalance, loyaltyBalances, preOrder } = useAppSelector(
    (state) => state.checkout
  );

  const { data: checkoutLoyaltyData, isLoading: isLoyaltyBalanceLoading } =
    useGetCheckoutLoyaltyBalanceQuery(undefined, {
      refetchOnMountOrArgChange: true,
      skip: !preOrder?.payment_option
    });

  // New approach: read accounts from LoyaltyMoneyUsagePage context
  const loyaltyAccounts: LoyaltyBalanceItem[] = useMemo(() => {
    const loyaltyContext = checkoutLoyaltyData?.context_list?.find(
      (ctx) => ctx.page_name === 'LoyaltyMoneyUsagePage'
    );
    return (
      (loyaltyContext?.page_context?.accounts as LoyaltyBalanceItem[]) ?? []
    );
  }, [checkoutLoyaltyData]);

  const selectableAccounts = useMemo(() => {
    return loyaltyAccounts.filter((account) => parseFloat(account.balance) > 0);
  }, [loyaltyAccounts]);

  // Determine which mode to use:
  // - "accounts" mode: backend returns page_context.accounts (new)
  // - "legacy" mode: Redux loyaltyBalance/loyaltyBalances from page_context.balance/balances (old)
  const hasAccounts = selectableAccounts.length > 0;
  const hasLegacyGrouped = !hasAccounts && loyaltyBalances?.length > 0;
  const hasLegacySingle =
    !hasAccounts && !hasLegacyGrouped && parseFloat(loyaltyBalance || '0') > 0;

  const isLoyaltyBalanceUsed = useMemo(() => {
    return parseFloat(preOrder?.loyalty_money ?? '0') > 0;
  }, [preOrder?.loyalty_money]);

  // --- Accounts mode state ---
  const [selectedAccountIds, setSelectedAccountIds] = useState<Set<string>>(
    new Set()
  );

  useEffect(() => {
    if (!hasAccounts) return;
    const usages = preOrder?.loyalty_account_usages;
    if (usages && Array.isArray(usages)) {
      setSelectedAccountIds(
        new Set(
          usages
            .filter((u) => parseFloat(String(u.amount)) > 0)
            .map((u) => String(u.label_id))
        )
      );
    } else if (
      parseFloat(preOrder?.loyalty_money ?? '0') > 0 &&
      selectableAccounts.length > 0
    ) {
      setSelectedAccountIds(
        new Set(selectableAccounts.map((a) => String(a.label_id)))
      );
    } else {
      setSelectedAccountIds(new Set());
    }
  }, [
    hasAccounts,
    preOrder?.loyalty_account_usages,
    preOrder?.loyalty_money,
    selectableAccounts
  ]);

  // --- Legacy grouped mode state ---
  const [selectedLabels, setSelectedLabels] = useState<Record<string, boolean>>(
    {}
  );

  const [isLoading, setIsLoading] = useState(false);

  const totalGroupedBalance = useMemo(() => {
    if (!loyaltyBalances) return 0;
    return loyaltyBalances.reduce(
      (sum, item) => sum + parseFloat(item.balance || '0'),
      0
    );
  }, [loyaltyBalances]);

  // --- Handlers ---
  const handleToggleAccount = async (account: LoyaltyBalanceItem) => {
    if (isLoading) return;
    setIsLoading(true);

    try {
      const key = String(account.label_id);
      const newSelected = new Set(selectedAccountIds);

      if (newSelected.has(key)) {
        newSelected.delete(key);
      } else {
        newSelected.add(key);
      }

      setSelectedAccountIds(newSelected);

      const accountUsages: AccountUsage[] = selectableAccounts
        .filter((acc) => newSelected.has(String(acc.label_id)))
        .map((acc) => ({
          label_id: acc.label_id,
          amount: parseFloat(acc.balance)
        }));

      await payWithLoyaltyBalance({ account_usages: accountUsages });
    } finally {
      setIsLoading(false);
    }
  };

  const handleToggleLegacyAll = async () => {
    if (isLoading) return;
    setIsLoading(true);

    try {
      if (isLoyaltyBalanceUsed) {
        if (hasLegacyGrouped) {
          const accountUsages: AccountUsage[] = loyaltyBalances.map((item) => ({
            label_id: item.label_id,
            amount: 0
          }));
          await payWithLoyaltyBalance({ account_usages: accountUsages });
          setSelectedLabels({});
        } else {
          await payWithLoyaltyBalance('0');
        }
      } else {
        if (hasLegacyGrouped) {
          const accountUsages: AccountUsage[] = loyaltyBalances.map((item) => ({
            label_id: item.label_id,
            amount: parseFloat(item.balance)
          }));
          await payWithLoyaltyBalance({ account_usages: accountUsages });
          const allSelected = loyaltyBalances.reduce(
            (acc, item) => ({ ...acc, [String(item.label_id)]: true }),
            {} as Record<string, boolean>
          );
          setSelectedLabels(allSelected);
        } else {
          await payWithLoyaltyBalance(loyaltyBalance);
        }
      }
    } finally {
      setIsLoading(false);
    }
  };

  const handleToggleLegacyLabel = async (item: LoyaltyBalanceItem) => {
    if (isLoading) return;
    setIsLoading(true);

    try {
      const key = String(item.label_id);
      const isCurrentlySelected = selectedLabels[key] ?? false;
      const newSelectedLabels = {
        ...selectedLabels,
        [key]: !isCurrentlySelected
      };

      const accountUsages: AccountUsage[] = loyaltyBalances.map((b) => ({
        label_id: b.label_id,
        amount: newSelectedLabels[String(b.label_id)]
          ? parseFloat(b.balance)
          : 0
      }));

      await payWithLoyaltyBalance({ account_usages: accountUsages });
      setSelectedLabels(newSelectedLabels);
    } finally {
      setIsLoading(false);
    }
  };

  // --- Early returns ---
  if (preOrder?.is_guest) {
    return null;
  }

  if (isLoyaltyBalanceLoading) {
    return (
      <div className="mb-3 px-4 py-3 xs:px-0">
        <LoaderSpinner />
      </div>
    );
  }

  if (!hasAccounts && !hasLegacyGrouped && !hasLegacySingle) {
    return null;
  }

  // --- Accounts mode render (new: from page_context.accounts) ---
  if (hasAccounts) {
    return (
      <div
        className={twMerge(
          'flex flex-col w-full mb-4 border border-solid border-gray-400 px-0 md:p-4',
          isPayLoading && 'pointer-events-none opacity-30'
        )}
      >
        {selectableAccounts.map((account) => {
          const isSelected = selectedAccountIds.has(String(account.label_id));

          return (
            <div
              key={String(account.label_id) ?? 'default'}
              className="mb-3 flex w-full items-center"
            >
              <button onClick={() => handleToggleAccount(account)}>
                <span
                  className={clsx(
                    'flex h-5 w-5 items-center justify-center rounded border border-solid border-primary',
                    isSelected ? 'bg-primary' : 'bg-white'
                  )}
                >
                  <Icon
                    name={isSelected ? 'check' : ''}
                    size={10}
                    className={clsx({ 'text-white': isSelected })}
                  />
                </span>
              </button>

              <div className="w-full pl-4 rtl:pr-4">
                <p
                  className="cursor-pointer text-sm"
                  onClick={() => handleToggleAccount(account)}
                >
                  {account.label ??
                    t('checkout.payment.store_credit.use_my_store_credits')}
                </p>
                <p className="flex text-sm text-[#606060]">
                  {t('checkout.payment.store_credit.available_balance')}:
                  <Price
                    value={account.balance}
                    currencyCode={
                      account.currency?.toUpperCase() ||
                      preOrder?.currency_type_label
                    }
                    className="pe-1 font-bold"
                  />
                </p>
              </div>
            </div>
          );
        })}

        {isLoyaltyBalanceUsed && parseFloat(preOrder?.unpaid_amount) > 0 && (
          <p className="my-4 text-[15px] font-light italic text-[#707070] max-xs:text-xs">
            <Trans
              i18nKey="checkout.payment.store_credit.insufficient_balance"
              components={{
                Amount: (
                  <div className="inline-flex">
                    <Price
                      value={preOrder?.unpaid_amount}
                      currencyCode={preOrder?.currency_type_label}
                      className="text-primary"
                    />
                  </div>
                )
              }}
            />
          </p>
        )}
      </div>
    );
  }

  // --- Legacy grouped mode render (from Redux loyaltyBalances) ---
  if (hasLegacyGrouped) {
    return (
      <div
        className={twMerge(
          'flex flex-col w-full mb-4 border border-solid border-gray-400 px-0 md:p-4',
          isPayLoading && 'pointer-events-none opacity-30'
        )}
      >
        <div className="flex w-full items-center mb-3">
          <button onClick={handleToggleLegacyAll}>
            <span
              className={clsx(
                'flex h-5 w-5 items-center justify-center rounded border border-solid border-primary',
                isLoyaltyBalanceUsed ? 'bg-primary' : 'bg-white'
              )}
            >
              <Icon
                name={isLoyaltyBalanceUsed ? 'check' : ''}
                size={10}
                className={clsx({ 'text-white': isLoyaltyBalanceUsed })}
              />
            </span>
          </button>

          <div className="w-full pl-4">
            <p
              className="cursor-pointer text-sm"
              onClick={handleToggleLegacyAll}
            >
              {t('checkout.payment.store_credit.use_my_store_credits')}
            </p>
            <p className="flex text-sm text-[#606060]">
              {t('checkout.payment.store_credit.total_balance')}:
              <Price
                value={String(totalGroupedBalance)}
                currencyCode={preOrder?.currency_type_label}
                className="pe-1 font-bold"
              />
            </p>
          </div>
        </div>

        <div className="ml-9 flex flex-col gap-2">
          {loyaltyBalances.map((item) => {
            const isSelected = selectedLabels[String(item.label_id)] ?? false;
            return (
              <div
                key={String(item.label_id)}
                className="flex items-center border border-solid border-gray-200 rounded p-2"
              >
                <button onClick={() => handleToggleLegacyLabel(item)}>
                  <span
                    className={clsx(
                      'flex h-4 w-4 items-center justify-center rounded border border-solid border-primary',
                      isSelected ? 'bg-primary' : 'bg-white'
                    )}
                  >
                    <Icon
                      name={isSelected ? 'check' : ''}
                      size={8}
                      className={clsx({ 'text-white': isSelected })}
                    />
                  </span>
                </button>
                <div className="flex w-full items-center justify-between pl-3">
                  <span
                    className="cursor-pointer text-sm"
                    onClick={() => handleToggleLegacyLabel(item)}
                  >
                    {item.label ??
                      t('checkout.payment.store_credit.use_my_store_credits')}
                  </span>
                  <Price
                    value={item.balance}
                    currencyCode={
                      item.currency?.toUpperCase() ||
                      preOrder?.currency_type_label
                    }
                    className="text-sm font-bold"
                  />
                </div>
              </div>
            );
          })}
        </div>

        {isLoyaltyBalanceUsed && parseFloat(preOrder?.unpaid_amount) > 0 && (
          <p className="my-4 text-[15px] font-light italic text-[#707070] max-xs:text-xs">
            <Trans
              i18nKey="checkout.payment.store_credit.insufficient_balance"
              components={{
                Amount: (
                  <div className="inline-flex">
                    <Price
                      value={preOrder?.unpaid_amount}
                      currencyCode={preOrder?.currency_type_label}
                      className="text-primary"
                    />
                  </div>
                )
              }}
            />
          </p>
        )}
      </div>
    );
  }

  // --- Legacy single balance mode render (from Redux loyaltyBalance) ---
  return (
    <div
      className={twMerge(
        'flex flex-col w-full mb-4 border border-solid border-gray-400 px-0 md:p-4',
        isPayLoading && 'pointer-events-none opacity-30'
      )}
    >
      <div className="flex w-full items-center">
        <button onClick={handleToggleLegacyAll}>
          <span
            className={clsx(
              'flex h-5 w-5 items-center justify-center rounded border border-solid border-primary',
              isLoyaltyBalanceUsed ? 'bg-primary' : 'bg-white'
            )}
          >
            <Icon
              name={isLoyaltyBalanceUsed ? 'check' : ''}
              size={10}
              className={clsx({ 'text-white': isLoyaltyBalanceUsed })}
            />
          </span>
        </button>

        <div className="w-full pl-4">
          <p
            className="cursor-pointer text-sm"
            onClick={handleToggleLegacyAll}
          >
            {t('checkout.payment.store_credit.use_my_store_credits')}
          </p>
          <p className="flex text-sm text-[#606060]">
            {t('checkout.payment.store_credit.available_balance')}:
            <Price
              value={loyaltyBalance}
              currencyCode={preOrder?.currency_type_label}
              className="pe-1 font-bold"
            />
          </p>
        </div>
      </div>

      {isLoyaltyBalanceUsed && parseFloat(preOrder?.unpaid_amount) > 0 && (
        <p className="my-4 text-[15px] font-light italic text-[#707070] max-xs:text-xs">
          <Trans
            i18nKey="checkout.payment.store_credit.insufficient_balance"
            components={{
              Amount: (
                <div className="inline-flex">
                  <Price
                    value={preOrder?.unpaid_amount}
                    currencyCode={preOrder?.currency_type_label}
                    className="text-primary"
                  />
                </div>
              )
            }}
          />
        </p>
      )}
    </div>
  );
};
