'use client';

import { useState, useEffect } from 'react';
import Button from '@/components/ui/button/Button';
import XenditScriptLoader from '@/components/common/XenditScriptLoader';
import MidtransScriptLoader from '@/components/common/MidtransScriptLoader';
import { currencyToSymbol, currencyToLocaleString } from '@/lib/transactionUtil';
import {
  EXPIRY_FIELD_LABEL_CLASS_NAME,
  getCreditCardBorderClassName,
  getExpiryFieldClassName,
} from './creditCardFormStyles';
import {
  buildXenditCardData,
  hasXenditPaymentApi,
  type XenditCardDetails,
} from './creditCardFormXendit';
import type { CreditCardProvider } from '../services/creditCardProvider';
import {
  getMidtransCardToken,
  getMidtransClient,
  redirectWithMidtrans,
} from '../services/midtransCard';

interface CreditCardFormProps {
  paymentSessionId?: string;
  amount: number;
  currency: string;
  onBack: () => void;
  isLinkingMode?: boolean;
  onLinkSuccess?: () => void;
  provider?: CreditCardProvider;
  clientKey?: string;
  onMidtransTokenized?: (token: string) => Promise<{ redirectUrl?: string } | void>;
  onXenditCardSubmitted?: (cardDetails: XenditCardDetails) => Promise<{ redirectUrl?: string } | void>;
}

declare global {
  interface Window {
    Xendit: any;
  }
}

export function CreditCardForm({ 
  paymentSessionId, 
  amount, 
  currency, 
  onBack,
  isLinkingMode = false,
  onLinkSuccess,
  provider = 'XENDIT',
  clientKey,
  onMidtransTokenized,
  onXenditCardSubmitted,
}: CreditCardFormProps) {
  const isMidtrans = provider === 'MIDTRANS';
  const isDirectXendit = !isMidtrans && Boolean(onXenditCardSubmitted);
  
  const [formData, setFormData] = useState({
    cardNumber: '',
    expiryMonth: '',
    expiryYear: '',
    cvn: '',
    cardholderFirstName: '',
    cardholderLastName: '',
    cardholderEmail: '',
    cardholderPhoneNumber: '',
  });

  const [isProcessing, setIsProcessing] = useState(false);
  const [errors, setErrors] = useState<{ [key: string]: string }>({});
  const [isPaymentSdkReady, setIsPaymentSdkReady] = useState(false);
  const hasExpiryError = Boolean(errors.expiry);

  // Wait for the selected provider's browser SDK to become available.
  useEffect(() => {
    const checkSdk = () => {
      const ready = isMidtrans
        ? Boolean(getMidtransClient())
        : isDirectXendit
          ? true
        : typeof window !== 'undefined' && hasXenditPaymentApi(window.Xendit);

      setIsPaymentSdkReady(ready);
    };

    checkSdk();
    const interval = window.setInterval(checkSdk, 250);
    const eventName = isMidtrans ? 'midtransLoaded' : 'xenditLoaded';
    window.addEventListener(eventName, checkSdk);

    return () => {
      window.clearInterval(interval);
      window.removeEventListener(eventName, checkSdk);
    };
  }, [isDirectXendit, isMidtrans]);

  const validateForm = () => {
    const newErrors: { [key: string]: string } = {};
    if (!formData.cardNumber || formData.cardNumber.length < 13) newErrors.cardNumber = 'Invalid card number';
    if (!formData.expiryMonth || !formData.expiryYear) newErrors.expiry = 'Invalid expiry date';
    if (!formData.cvn || formData.cvn.length < 3) newErrors.cvn = 'Invalid CVV';
    if (!formData.cardholderFirstName) newErrors.cardholderFirstName = 'Required';
    if (!formData.cardholderLastName) newErrors.cardholderLastName = 'Required';
    if (!formData.cardholderEmail) newErrors.cardholderEmail = 'Required';
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    console.info('[topup][credit-card] submit-attempt', {
      at: new Date().toISOString(),
      provider,
      isDirectXendit,
      amount,
    });

    if (!validateForm()) {
      console.warn('[topup][credit-card] validation-failed');
      return;
    }

    setIsProcessing(true);

    if (isMidtrans) {
      const client = getMidtransClient();
      if (!client || !isPaymentSdkReady) {
        setIsProcessing(false);
        alert('Midtrans payment system is not ready yet, please wait');
        return;
      }

      if (!onMidtransTokenized) {
        setIsProcessing(false);
        alert('Midtrans payment handler is not configured');
        return;
      }

      void (async () => {
        try {
          const token = await getMidtransCardToken(
            {
              card_number: formData.cardNumber.replace(/\s/g, ''),
              card_cvv: formData.cvn,
              card_exp_month: formData.expiryMonth,
              card_exp_year: formData.expiryYear,
            },
            client,
          );
          const result = await onMidtransTokenized(token);

          if (result?.redirectUrl) {
            redirectWithMidtrans(client, result.redirectUrl);
          }
        } catch (error) {
          console.error('Midtrans card tokenization error:', error);
          alert(error instanceof Error ? error.message : 'Payment failed');
        } finally {
          setIsProcessing(false);
        }
      })();
      return;
    }

    if (onXenditCardSubmitted) {
      void (async () => {
        try {
          console.info('[topup][xendit][credit-card] client-submit', {
            at: new Date().toISOString(),
            amount,
            cardNumberLength: formData.cardNumber.replace(/\s/g, '').length,
            hasExpiry: Boolean(formData.expiryMonth && formData.expiryYear),
            hasCvn: Boolean(formData.cvn),
            hasCardholderFirstName: Boolean(formData.cardholderFirstName),
            hasCardholderLastName: Boolean(formData.cardholderLastName),
            hasCardholderEmail: Boolean(formData.cardholderEmail),
            hasCardholderPhoneNumber: Boolean(formData.cardholderPhoneNumber),
          });
          const result = await onXenditCardSubmitted({
            cardNumber: formData.cardNumber,
            expiryMonth: formData.expiryMonth,
            expiryYear: formData.expiryYear,
            cvn: formData.cvn,
            firstName: formData.cardholderFirstName,
            lastName: formData.cardholderLastName,
            email: formData.cardholderEmail,
            phoneNumber: formData.cardholderPhoneNumber,
          });

          if (result?.redirectUrl) {
            window.location.href = result.redirectUrl;
          }
        } catch (error) {
          console.error('Xendit credit card payment error:', error);
          alert(error instanceof Error ? error.message : 'Payment failed');
        } finally {
          setIsProcessing(false);
        }
      })();
      return;
    }

    if (!isPaymentSdkReady) {
      setIsProcessing(false);
      alert('Xendit not ready yet, please wait');
      return;
    }

    // Function to handle Xendit response.
    const handleXenditResponse = (response: any) => {
      
      // Check for action_url in the response (should be present in both full form and CVN-only cases)
      if (response.action_url) {
        // For all cases including linking mode, redirect to action URL for authentication
        window.location.href = response.action_url;
      } else if (response.payment_request_id) {
        if (isLinkingMode) {
          // Store the payment token ID for later use
          if (onLinkSuccess) {
            onLinkSuccess();
          } else {
            alert('Card linking initiated successfully!');
            // You may want to redirect here or update UI
          }
        } else {
          // Payment case but no action_url (unusual but handle it)
          alert('Payment is being processed. You may need to refresh the page.');
        }
      } else if (response.status === 'VERIFIED' || response.status === 'AUTHORIZED') {
        // Handle successful payment that doesn't need 3DS
        if (isLinkingMode) {
          alert('Card linked successfully!');
          if (onLinkSuccess) onLinkSuccess();
        } else {
          alert('Payment processed successfully!');
        }
      } else {
        // Handle other failure cases
        console.error('Unexpected response format:', response);
        alert('Operation failed: ' + (response.status || response.message || 'Unknown error'));
      }
    };

    const reqData = buildXenditCardData({
      cardNumber: formData.cardNumber.replace(/\s/g, ''),
      expiryMonth: formData.expiryMonth,
      expiryYear: formData.expiryYear,
      cvn: formData.cvn,
      firstName: formData.cardholderFirstName,
      lastName: formData.cardholderLastName,
      email: formData.cardholderEmail,
      phoneNumber: formData.cardholderPhoneNumber,
      paymentSessionId,
      saveForFuture: isLinkingMode,
    });

    window.Xendit.payment.collectCardData(reqData, (err: any, response: any) => {
      setIsProcessing(false);

      if (err) {
        console.error('Xendit error:', err);
        alert(err.message || 'Payment failed');
        return;
      }

      handleXenditResponse(response);
    });
  };

  const formatCardNumber = (value: string) => {
    const numericValue = value.replace(/\D/g, '');
    return numericValue.replace(/(\d{4})(?=\d)/g, '$1 ');
  };

  const handleInputChange = (field: string, value: string | boolean) => {
    if (field === 'cardNumber' && typeof value === 'string') value = formatCardNumber(value);
    setFormData((prev) => ({ ...prev, [field]: value }));
    if (errors[field]) setErrors((prev) => ({ ...prev, [field]: '' }));
  };

  return (
    <>
      {isMidtrans ? (
        <MidtransScriptLoader clientKey={clientKey} />
      ) : isDirectXendit ? null : (
        <XenditScriptLoader />
      )}

      <div className="flex flex-col bg-white dark:bg-gray-900 max-h-[75vh] overflow-y-auto" style={{ scrollbarWidth: 'thin', scrollbarColor: 'rgba(156, 163, 175, 0.5) transparent' }}>
        <div className="sticky top-0 z-10 pt-4 pb-2 px-4 bg-white/90 dark:bg-gray-900/90 backdrop-blur-sm border-b border-gray-100 dark:border-gray-800">
          <button
            onClick={onBack}
            className="flex items-center gap-2 text-gray-600 hover:text-gray-800 dark:text-gray-300 dark:hover:text-white transition-colors"
          >
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
            </svg>
            <span className="font-medium text-sm">Back</span>
          </button>
        </div>

        <div className="flex-1 px-4 pb-6">
          <div className="w-full max-w-md mx-auto">
            <div className="text-center text-black dark:text-white mb-6 mt-4">
              <h1 className="mb-2 text-2xl font-bold text-brand-500">
                {isLinkingMode ? 'Link Credit Card' : 'Enter Card Details'}
              </h1>
              <p className="text-sm text-gray-500 dark:text-gray-400">
                {isLinkingMode 
                  ? 'Add your credit card for faster payments'
                  : `Amount to pay: ${currencyToSymbol(currency)}${amount.toLocaleString(currencyToLocaleString(currency))}`
                }
              </p>
              {!isPaymentSdkReady && (
                <p className="text-sm text-yellow-600 dark:text-yellow-400 mt-2">Loading payment system...</p>
              )}
            </div>

            <form onSubmit={handleSubmit} className="space-y-5">
              <div className='flex flex-col gap-2'>
                  {/* Card Number */}
                  <div>
                    <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Card Number *</label>
                    <input
                      type="text"
                      value={formData.cardNumber}
                      onChange={(e) => handleInputChange('cardNumber', e.target.value)}
                      placeholder="1234 5678 9012 3456"
                      maxLength={19}
                      className={`w-full px-4 py-3 rounded-lg border text-sm bg-white dark:bg-gray-900 placeholder-gray-400 dark:placeholder-gray-500 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500 ${getCreditCardBorderClassName(Boolean(errors.cardNumber))}`}
                    />
                    {errors.cardNumber && <p className="text-red-600 dark:text-red-400 text-xs mt-1">{errors.cardNumber}</p>}
                  </div>

                  {/* Expiry + CVV */}
                  <div className="grid grid-cols-3 gap-2 sm:gap-3">
                    <div className="col-span-2">
                      <div className="grid grid-cols-2 gap-2 sm:gap-3">
                        <div>
                          <label className={EXPIRY_FIELD_LABEL_CLASS_NAME}>Month *</label>
                          <select
                            value={formData.expiryMonth}
                            onChange={(e) => handleInputChange('expiryMonth', e.target.value)}
                            className={getExpiryFieldClassName(hasExpiryError)}
                          >
                            <option value="">MM</option>
                            {Array.from({ length: 12 }, (_, i) => i + 1).map((m) => (
                              <option key={m} value={m.toString().padStart(2, '0')}>
                                {m.toString().padStart(2, '0')}
                              </option>
                            ))}
                          </select>
                        </div>
                        <div>
                          <label className={EXPIRY_FIELD_LABEL_CLASS_NAME}>Year *</label>
                          <select
                            value={formData.expiryYear}
                            onChange={(e) => handleInputChange('expiryYear', e.target.value)}
                            className={getExpiryFieldClassName(hasExpiryError)}
                          >
                            <option value="">YYYY</option>
                            {Array.from({ length: 20 }, (_, i) => new Date().getFullYear() + i).map((y) => (
                              <option key={y} value={y.toString()}>
                                {y}
                              </option>
                            ))}
                          </select>
                        </div>
                      </div>
                      {errors.expiry && <p className="text-center text-red-600 dark:text-red-400 text-xs mt-1">{errors.expiry}</p>}
                    </div>
                    <div>
                      <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">CVV *</label>
                      <input
                        type="text"
                        value={formData.cvn}
                        onChange={(e) => handleInputChange('cvn', e.target.value.replace(/\D/g, ''))}
                        placeholder="123"
                        maxLength={4}
                        className={`w-full h-12 box-border px-4 py-3 rounded-lg border text-sm bg-white dark:bg-gray-900 placeholder-gray-400 dark:placeholder-gray-500 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500 ${getCreditCardBorderClassName(Boolean(errors.cvn))}`}
                      />
                      {errors.cvn && <p className="text-red-600 dark:text-red-400 text-xs mt-1">{errors.cvn}</p>}
                    </div>
                  </div>

                  {/* Name */}
                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">First Name *</label>
                      <input
                        type="text"
                        value={formData.cardholderFirstName}
                        onChange={(e) => handleInputChange('cardholderFirstName', e.target.value)}
                        placeholder="John"
                        className={`w-full px-4 py-3 rounded-lg border text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500 ${getCreditCardBorderClassName(Boolean(errors.cardholderFirstName))}`}
                      />
                      {errors.cardholderFirstName && <p className="text-red-500 text-xs mt-1">{errors.cardholderFirstName}</p>}
                    </div>
                    <div>
                      <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Last Name *</label>
                      <input
                        type="text"
                        value={formData.cardholderLastName}
                        onChange={(e) => handleInputChange('cardholderLastName', e.target.value)}
                        placeholder="Doe"
                        className={`w-full px-4 py-3 rounded-lg border text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500 ${getCreditCardBorderClassName(Boolean(errors.cardholderLastName))}`}
                      />
                      {errors.cardholderLastName && <p className="text-red-500 text-xs mt-1">{errors.cardholderLastName}</p>}
                    </div>
                  </div>

                  {/* Email */}
                  <div>
                    <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Email *</label>
                    <input
                      type="email"
                      value={formData.cardholderEmail}
                      onChange={(e) => handleInputChange('cardholderEmail', e.target.value)}
                      placeholder="john.doe@example.com"
                      className={`w-full px-4 py-3 rounded-lg border text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500 ${getCreditCardBorderClassName(Boolean(errors.cardholderEmail))}`}
                    />
                    {errors.cardholderEmail && <p className="text-red-500 text-xs mt-1">{errors.cardholderEmail}</p>}
                  </div>

                  {/* Phone */}
                  <div>
                    <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Phone Number</label>
                    <input
                      type="tel"
                      value={formData.cardholderPhoneNumber}
                      onChange={(e) => handleInputChange('cardholderPhoneNumber', e.target.value)}
                      placeholder="+1234567890"
                      className="w-full px-4 py-3 rounded-lg border text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 border-gray-300 dark:border-gray-700 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500"
                    />
                  </div>

              </div>

              {/* Button */}
              <div className="pt-4 sticky bottom-0 bg-white/90 dark:bg-gray-900/90 backdrop-blur-sm pb-2 border-t border-gray-100 dark:border-gray-800">
                <Button type="submit" variant="primary" className="w-full py-3 text-base" disabled={isProcessing}>
                  {isProcessing
                    ? 'Processing...'
                    : isLinkingMode
                      ? 'Link Card'
                      : `Pay ${currencyToSymbol(currency)}${amount.toLocaleString(currencyToLocaleString(currency))}`
                  }
                </Button>
              </div>
            </form>
          </div>
        </div>
      </div>
    </>
  );
}
