import React, { useEffect, useMemo, useState } from 'react';
import { Modal, Button } from '@akinon/next/components';
import { RewardSelectionModalProps } from '../types/custom-render.types';
import type { RewardItem, RewardCategory } from '../types/payment.types';
import { parseRewardAmount, getCappedRewardAmounts } from '../utils/reward-utils';

const formatAmount = (amount: number | string, currency?: string) => {
  const formatted = parseRewardAmount(amount).toFixed(2);
  return currency ? `${formatted} ${currency.toUpperCase()}` : formatted;
};

const isSameReward = (a: RewardItem, b: RewardItem) => a.type === b.type;

const RewardSelectionModal: React.FC<RewardSelectionModalProps> = ({
  open,
  onClose,
  onConfirm,
  rewards,
  selectedRewards,
  isLoading = false,
  currency,
  payableAmount,
  texts
}) => {
  const [draft, setDraft] = useState<RewardItem[]>(selectedRewards);

  useEffect(() => {
    if (open) {
      setDraft(selectedRewards);
    }
  }, [open, selectedRewards]);

  const cappedAmounts = useMemo(
    () => getCappedRewardAmounts(draft, payableAmount),
    [draft, payableAmount]
  );

  const grouped = useMemo(() => {
    const map: Record<RewardCategory, RewardItem[]> = {
      special: [],
      general: []
    };
    rewards.forEach((reward) => {
      if (map[reward.type]) {
        map[reward.type].push(reward);
      }
    });
    return map;
  }, [rewards]);

  const toggleReward = (reward: RewardItem) => {
    setDraft((current) => {
      const exists = current.some((item) => isSameReward(item, reward));
      if (exists) {
        return current.filter((item) => !isSameReward(item, reward));
      }
      const withoutSameType = current.filter(
        (item) => item.type !== reward.type
      );
      return [...withoutSameType, reward];
    });
  };

  const isSelected = (reward: RewardItem) =>
    draft.some((item) => isSameReward(item, reward));

  const categoryLabel = (category: RewardCategory) =>
    category === 'special'
      ? texts.rewardCategorySpecialText
      : texts.rewardCategoryGeneralText;

  const handleConfirm = async () => {
    await onConfirm(draft);
  };

  const hasRewards = rewards.length > 0;

  return (
    <Modal
      portalId="masterpass-reward-modal"
      open={open}
      setOpen={onClose}
      title={texts.rewardModalTitle}
      className="w-full sm:w-[32rem] max-h-[90vh] overflow-y-auto"
    >
      <div className="px-6 pt-4 pb-6">
        {texts.rewardModalDescription && (
          <p className="text-sm text-gray-600 mb-4">
            {texts.rewardModalDescription}
          </p>
        )}

        {!hasRewards ? (
          <p className="text-center text-gray-500 py-8">
            {texts.rewardModalEmptyMessage}
          </p>
        ) : (
          <div className="space-y-5">
            {(Object.keys(grouped) as RewardCategory[])
              .filter((category) => grouped[category].length > 0)
              .map((category) => (
                <div key={category}>
                  <h3 className="text-sm font-semibold text-gray-700 mb-2">
                    {categoryLabel(category)}
                  </h3>
                  <ul className="space-y-2">
                    {grouped[category].map((reward) => {
                      const selected = isSelected(reward);
                      const fullValue = parseRewardAmount(reward.amount);
                      const capped = cappedAmounts[reward.type];
                      const isCapped = selected && capped < fullValue;
                      return (
                        <li key={`${reward.type}-${reward.name ?? ''}`}>
                          <label
                            className={`flex items-center justify-between gap-3 px-3 py-3 border cursor-pointer transition-colors ${
                              selected
                                ? 'border-primary bg-primary/5'
                                : 'border-gray-200 hover:bg-gray-50'
                            }`}
                          >
                            <div className="flex items-center gap-3">
                              <input
                                type="checkbox"
                                className="h-4 w-4"
                                checked={selected}
                                onChange={() => toggleReward(reward)}
                                disabled={isLoading}
                              />
                              <div>
                                <p className="font-medium">
                                  {reward.name || categoryLabel(reward.type)}
                                </p>
                                {reward.name && (
                                  <p className="text-xs text-gray-500">
                                    {categoryLabel(reward.type)}
                                  </p>
                                )}
                              </div>
                            </div>
                            <div className="text-right">
                              <span
                                className={`font-semibold ${
                                  isCapped
                                    ? 'text-gray-400 line-through text-sm'
                                    : ''
                                }`}
                              >
                                {formatAmount(reward.amount, currency)}
                              </span>
                              {isCapped && (
                                <p className="text-xs text-[#00a63d] font-medium mt-0.5">
                                  {(texts.rewardCappedNoticeText || '').replace(
                                    '{amount}',
                                    formatAmount(capped, currency)
                                  )}
                                </p>
                              )}
                            </div>
                          </label>
                        </li>
                      );
                    })}
                  </ul>
                </div>
              ))}
          </div>
        )}

        <div className="flex gap-3 justify-end mt-6">
          <Button
            appearance="outlined"
            className="px-5 py-3 h-auto"
            onClick={onClose}
            disabled={isLoading}
          >
            {texts.rewardModalCancelText}
          </Button>
          <Button
            appearance="filled"
            className="px-5 py-3 h-auto"
            onClick={handleConfirm}
            disabled={isLoading || !hasRewards}
          >
            {isLoading
              ? texts.rewardModalLoadingText
              : texts.rewardModalConfirmText}
          </Button>
        </div>
      </div>
    </Modal>
  );
};

export default RewardSelectionModal;
