import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { TextField, Button, Alert, Box, InputAdornment } from '@mui/material';
import { Add } from '@mui/icons-material';
import { useState } from 'react';
import LoadingButton from './loading-button';
import api from '../libs/api';
import { usePaymentContext } from '../contexts/payment';

export interface AppliedPromoCode {
  id: string;
  code: string;
  discount_amount?: string;
}

interface PromotionCodeProps {
  checkoutSessionId: string;
  initialAppliedCodes?: AppliedPromoCode[];
  disabled?: boolean;
  className?: string;
  placeholder?: string;
  currencyId: string;
  onUpdate?: (data: { appliedCodes: AppliedPromoCode[]; discountAmount: string }) => void;
}

export default function PromotionCode({
  checkoutSessionId,
  initialAppliedCodes = [],
  disabled = false,
  className = '',
  placeholder = '',
  onUpdate = undefined,
  currencyId,
}: PromotionCodeProps) {
  const { t } = useLocaleContext();
  const [showInput, setShowInput] = useState(false);
  const [code, setCode] = useState('');
  const [error, setError] = useState('');
  const [applying, setApplying] = useState(false);
  const [appliedCodes, setAppliedCodes] = useState<AppliedPromoCode[]>(initialAppliedCodes);
  const { session, paymentState } = usePaymentContext();

  const handleLoginCheck = () => {
    if (!session.user) {
      session?.login(() => {
        handleApply();
      });
    } else {
      handleApply();
    }
  };

  const handleApply = async () => {
    if (!code.trim()) return;

    // Prevent applying promotion during payment process
    if (paymentState.paying || paymentState.stripePaying) {
      return;
    }

    setApplying(true);
    setError('');

    try {
      const response = await api.post(`/api/checkout-sessions/${checkoutSessionId}/apply-promotion`, {
        promotion_code: code.trim(),
        currency_id: currencyId,
      });

      const discounts = response.data.discounts || [];
      const appliedDiscount = discounts[0];

      if (appliedDiscount) {
        const newCode: AppliedPromoCode = {
          id: appliedDiscount.promotion_code || appliedDiscount.coupon,
          code: code.trim(),
          discount_amount: appliedDiscount.discount_amount,
        };

        setAppliedCodes([newCode]);
        setCode('');
        setShowInput(false);

        onUpdate?.({
          appliedCodes: [newCode],
          discountAmount: appliedDiscount.discount_amount,
        });
      }
    } catch (err: any) {
      const errorMessage = err.response?.data?.error || err.message;
      setError(errorMessage);
    } finally {
      setApplying(false);
    }
  };

  const handleKeyPress = (event: React.KeyboardEvent) => {
    if (event.key === 'Enter' && !applying && code.trim()) {
      handleLoginCheck();
    }
  };

  const isPaymentInProgress = paymentState.paying || paymentState.stripePaying;

  return (
    <Box className={className}>
      {/* Input field or add button - only show if no codes applied */}
      {appliedCodes.length === 0 &&
        !disabled &&
        !isPaymentInProgress &&
        (showInput ? (
          <Box
            onBlur={() => {
              if (!code.trim()) {
                setShowInput(false);
              }
            }}>
            <TextField
              fullWidth
              value={code}
              onChange={(e) => setCode(e.target.value)}
              onKeyPress={handleKeyPress}
              placeholder={placeholder || t('payment.checkout.promotion.placeholder')}
              variant="outlined"
              size="small"
              disabled={applying}
              autoFocus
              slotProps={{
                input: {
                  endAdornment: (
                    <InputAdornment position="end">
                      <LoadingButton
                        size="small"
                        onClick={handleLoginCheck}
                        loading={applying}
                        disabled={!code.trim()}
                        variant="text"
                        sx={{
                          color: 'primary.main',
                          fontSize: 'small',
                        }}>
                        {t('payment.checkout.promotion.apply')}
                      </LoadingButton>
                    </InputAdornment>
                  ),
                },
              }}
              sx={{
                '& .MuiOutlinedInput-root': {
                  pr: 1,
                },
              }}
            />

            {error && (
              <Alert
                severity="error"
                sx={{
                  my: 1,
                }}>
                {error}
              </Alert>
            )}
          </Box>
        ) : (
          <Button
            onClick={() => setShowInput(true)}
            startIcon={<Add fontSize="small" />}
            variant="text"
            sx={{
              fontWeight: 'normal',
              textTransform: 'none',
              justifyContent: 'flex-start',
              p: 0,
              '&:hover': {
                backgroundColor: 'transparent',
                textDecoration: 'underline',
              },
            }}>
            {t('payment.checkout.promotion.add_code')}
          </Button>
        ))}
    </Box>
  );
}
