import React, { useState, useEffect } from 'react';
import { CreditCard, X, CheckCircle, AlertCircle, Loader2 } from 'lucide-react';
import { Button, Modal, Input } from '../../components/ui';
import { DialogModal } from '../../components/ui/DialogModal/DialogModal';
import { subscriptionService } from '../../api';
import { showToast } from '../../utils/toast';
import { useTranslation } from 'react-i18next';
import { loadStripe, Stripe, StripeElements } from '@stripe/stripe-js';
import { 
  Elements, 
  CardElement, 
  useStripe as useStripeHook, 
  useElements as useElementsHook 
} from '@stripe/react-stripe-js';

interface PaymentMethodUpdateModalProps {
  isOpen: boolean;
  onClose: () => void;
  tenantId: string;
  currentPaymentMethod?: {
    brand?: string;
    last4?: string;
    exp_month?: number;
    exp_year?: number;
  };
  onPaymentMethodUpdated: (paymentMethod: {
    brand: string;
    last4: string;
    exp_month?: number;
    exp_year?: number;
  }) => void;
}

// Get Stripe publishable key from environment with proper fallback
const getStripePublishableKey = (): string => {
  // Try runtime config first (for production)
  if (typeof window !== 'undefined' && (window as any).__RUNTIME_CONFIG__?.VITE_STRIPE_PUBLISHABLE_KEY) {
    return (window as any).__RUNTIME_CONFIG__.VITE_STRIPE_PUBLISHABLE_KEY;
  }
  
  // Try build-time env variable
  if (import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY) {
    return import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY;
  }
  
  // Fallback for development - should not be used in production
  console.warn('Stripe publishable key not found in environment. Using test key for development.');
  return 'pk_test_51QuxKyIzCdnBmAVTGM8fvXYkItrBUILz6lHYwhAva6ZAH1HRi0e8zDRgZ4X3faN0zEABp5RHjCVBmMJL3aKXbaC200fFrSNnPl';
};

// Create Stripe promise for Elements provider
const stripePromise = loadStripe(getStripePublishableKey(), {
  betas: ['elements_v2'],
  locale: 'auto',
  stripeAccount: import.meta.env.VITE_STRIPE_ACCOUNT_ID,
  apiVersion: '2023-10-16'
});

/**
 * Stripe Card Form Component
 * This component handles the actual Stripe card input and submission
 */
const StripeCardForm = ({ 
  tenantId, 
  onSuccess, 
  onError, 
  onLoading 
}: {
  tenantId: string;
  onSuccess: (paymentMethod: any) => void;
  onError: (error: string) => void;
  onLoading: (loading: boolean) => void;
}) => {
  const stripe = useStripeHook();
  const elements = useElementsHook();
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [authenticating, setAuthenticating] = useState(false);

  // Check if elements are ready
  const [elementsReady, setElementsReady] = useState(false);
  
  useEffect(() => {
    if (elements) {
      const checkElementsReady = async () => {
        try {
          // Wait a moment for elements to be fully ready
          await new Promise(resolve => setTimeout(resolve, 50));
          setElementsReady(true);
        } catch (err) {
          console.error('Elements not ready:', err);
          setError('Payment form not ready. Please try again.');
        }
      };
      
      checkElementsReady();
    }
  }, [elements]);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    if (!stripe || !elements || !elementsReady) {
      setError('Payment processor not loaded');
      onError('Payment processor not loaded');
      return;
    }

    setLoading(true);
    setError(null);
    onLoading(true);

    try {
      // Trigger form validation and wallet collection
      const { error: submitError } = await elements.submit();
      
      if (submitError) {
        setError(submitError.message || 'Failed to validate payment information');
        setLoading(false);
        onLoading(false);
        onError(submitError.message || 'Failed to validate payment information');
        return;
      }

      // Create payment method using Stripe Elements
      const cardElement = elements.getElement(CardElement);
      const { paymentMethod, error: stripeError } = await stripe.createPaymentMethod({
        type: 'card',
        card: cardElement,
      });

      if (stripeError) {
        setError(stripeError.message || 'Failed to create payment method');
        setLoading(false);
        onLoading(false);
        onError(stripeError.message || 'Failed to create payment method');
        return;
      }

      if (!paymentMethod || !paymentMethod.id) {
        setError('No payment method created');
        setLoading(false);
        onLoading(false);
        onError('No payment method created');
        return;
      }

      // Call backend to update payment method
      const result = await subscriptionService.updatePaymentMethod(tenantId, paymentMethod.id);

      // Handle 3D Secure authentication if required
      if (result.requires_action && result.client_secret) {
        setAuthenticating(true);
        setLoading(false);
        
        try {
          // Handle 3D Secure authentication
          const { error: confirmError, setupIntent } = await stripe.confirmCardSetup(result.client_secret);
          
          if (confirmError) {
            setError(confirmError.message || '3D Secure authentication failed');
            setAuthenticating(false);
            onLoading(false);
            onError(confirmError.message || '3D Secure authentication failed');
            return;
          }

          if (setupIntent && setupIntent.status === 'succeeded') {
            onSuccess({
              brand: result.brand,
              last4: result.last4,
              exp_month: result.exp_month,
              exp_year: result.exp_year,
            });
          } else {
            setError('3D Secure authentication completed but payment method not confirmed');
            setAuthenticating(false);
            onLoading(false);
            onError('3D Secure authentication completed but payment method not confirmed');
          }
        } catch (authError) {
          console.error('Error during 3D Secure authentication:', authError);
          const errorMessage = authError instanceof Error 
            ? authError.message 
            : '3D Secure authentication error. Please try again.';
          setError(errorMessage);
          setAuthenticating(false);
          onLoading(false);
          onError(errorMessage);
        }
      } else if (result.success) {
        // No authentication required
        onSuccess({
          brand: result.brand,
          last4: result.last4,
          exp_month: result.exp_month,
          exp_year: result.exp_year,
        });
      } else {
        // Handle different payment intent statuses
        let errorMessage = result.message || 'Failed to update payment method';
        if (result.payment_intent_status === 'requires_payment_method') {
          errorMessage = 'Your card was declined. Please try a different payment method.';
        } else if (result.payment_intent_status === 'requires_action') {
          errorMessage = 'Authentication required but client secret missing. Please try again.';
        } else if (result.payment_intent_status === 'processing') {
          errorMessage = 'Payment is processing. Please wait a few minutes and try again.';
        } else if (result.payment_intent_status === 'canceled') {
          errorMessage = 'Payment was canceled. Please try again.';
        }
        
        setError(errorMessage);
        setLoading(false);
        onLoading(false);
        onError(errorMessage);
      }
    } catch (err) {
      console.error('Error updating payment method:', err);
      const errorMessage = err instanceof Error 
        ? err.message 
        : 'An unexpected error occurred while updating payment method.';
      setError(errorMessage);
      setLoading(false);
      onLoading(false);
      onError(errorMessage);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <div>
        <label className="block text-sm font-medium text-[var(--text-primary)] mb-2">
          Nueva Tarjeta
        </label>
        <div className="p-3 border border-[var(--border-primary)] rounded-lg bg-[var(--bg-primary)] min-h-[50px]">
          {!elementsReady ? (
            <div className="flex items-center gap-2 text-[var(--text-secondary)] h-[50px]">
              <Loader2 className="w-4 h-4 animate-spin" />
              <span>Preparando formulario de pago...</span>
            </div>
          ) : (
            <CardElement 
              options={
                {
                  style: {
                    base: {
                      fontSize: '16px',
                      color: '#32325d',
                      '::placeholder': {
                        color: '#aab7c4',
                      },
                    },
                    invalid: {
                      color: '#fa755a',
                      iconColor: '#fa755a',
                    },
                  },
                }
              }
            />
          )}
        </div>
      </div>

      {/* 3D Secure Authentication Status */}
      {authenticating && (
        <div className="p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg flex items-center gap-2 text-blue-500">
          <CreditCard className="w-4 h-4" />
          <span className="text-sm">Completing secure authentication with your bank...</span>
        </div>
      )}

      {/* Error Display */}
      {error && (
        <div className="p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center gap-2 text-red-500">
          <AlertCircle className="w-4 h-4" />
          <span className="text-sm">{error}</span>
        </div>
      )}

      {/* Action Buttons */}
      <div className="flex gap-3 justify-end">
        <Button
          type="button"
          variant="outline"
          disabled={loading || authenticating}
        >
          Cancelar
        </Button>
        <Button
          type="submit"
          variant="primary"
          disabled={loading || authenticating}
          className="flex items-center gap-2"
        >
          {(loading || authenticating) && <Loader2 className="w-4 h-4 animate-spin" />}
          {authenticating ? 'Autenticando...' : loading ? 'Procesando...' : 'Actualizar Método de Pago'}
        </Button>
      </div>
    </form>
  );
};

/**
 * Main Payment Method Update Modal Component
 */
export const PaymentMethodUpdateModal: React.FC<PaymentMethodUpdateModalProps> = ({
  isOpen,
  onClose,
  tenantId,
  currentPaymentMethod,
  onPaymentMethodUpdated
}) => {
  const { t } = useTranslation('subscription');
  const [loading, setLoading] = useState(false);
  const [success, setSuccess] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [stripeLoaded, setStripeLoaded] = useState(false);
  const [stripeError, setStripeError] = useState<string | null>(null);

  const handleSuccess = (paymentMethod: any) => {
    setSuccess(true);
    showToast.success('Payment method updated successfully');
    onPaymentMethodUpdated(paymentMethod);
    
    // Close modal after a brief delay to show success message
    setTimeout(() => {
      handleClose();
    }, 2000);
  };

  const handleError = (errorMessage: string) => {
    setError(errorMessage);
  };

  const handleLoading = (isLoading: boolean) => {
    setLoading(isLoading);
  };

  // Track Stripe loading status
  useEffect(() => {
    if (isOpen) {
      setStripeLoaded(false);
      setStripeError(null);
      
      // Check if Stripe is already loaded
      const checkStripeLoaded = async () => {
        try {
          // Give Stripe a moment to load
          await new Promise(resolve => setTimeout(resolve, 100));
          
          // Check if the Stripe promise resolves successfully
          const stripe = await stripePromise;
          if (stripe) {
            setStripeLoaded(true);
          }
        } catch (err) {
          console.error('Failed to load Stripe:', err);
          setStripeError('Failed to load payment processor. Please check your connection.');
        }
      };
      
      checkStripeLoaded();
    }
  }, [isOpen]);

  const handleClose = () => {
    setError(null);
    setSuccess(false);
    setStripeLoaded(false);
    setStripeError(null);
    onClose();
  };

  return (
    <DialogModal
      isOpen={isOpen}
      onClose={handleClose}
      title="Actualizar Método de Pago"
      type="custom"
      size="md"
      message={
        <div className="space-y-6">
          {/* Current Payment Method Info */}
          {currentPaymentMethod && (
            <div className="p-4 bg-[var(--bg-secondary)] rounded-lg border border-[var(--border-secondary)]">
              <h4 className="font-medium text-[var(--text-primary)] mb-2">Método de Pago Actual</h4>
              <div className="flex items-center gap-3">
                <CreditCard className="w-6 h-6 text-blue-500" />
                <div>
                  <p className="text-[var(--text-primary)]">
                    {currentPaymentMethod.brand} terminando en {currentPaymentMethod.last4}
                  </p>
                  {currentPaymentMethod.exp_month && currentPaymentMethod.exp_year && (
                    <p className="text-sm text-[var(--text-secondary)]">
                      Expira: {currentPaymentMethod.exp_month}/{currentPaymentMethod.exp_year}
                    </p>
                  )}
                </div>
              </div>
            </div>
          )}

          {/* Stripe Elements Provider with Card Form */}
          {!stripeLoaded && !stripeError && (
            <div className="p-4 bg-blue-500/5 border border-blue-500/20 rounded-lg text-center">
              <Loader2 className="w-6 h-6 animate-spin mx-auto mb-2 text-blue-500" />
              <span className="text-[var(--text-secondary)]">Cargando procesador de pagos seguro...</span>
            </div>
          )}
          
          {stripeError && (
            <div className="p-4 bg-red-500/10 border border-red-500/20 rounded-lg text-center text-red-500">
              <AlertCircle className="w-6 h-6 mx-auto mb-2" />
              <span className="text-sm">Error loading payment processor. Please refresh the page.</span>
              <Button 
                type="button"
                variant="text"
                size="sm"
                onClick={() => window.location.reload()}
                className="mt-2 text-red-600 hover:text-red-800"
              >
                Refresh Page
              </Button>
            </div>
          )}
          
          {stripeLoaded && stripePromise && (
            <Elements stripe={stripePromise}>
              <StripeCardForm
                tenantId={tenantId}
                onSuccess={handleSuccess}
                onError={handleError}
                onLoading={handleLoading}
              />
            </Elements>
          )}

          {/* Success Message */}
          {success && (
            <div className="p-3 bg-green-500/10 border border-green-500/20 rounded-lg flex items-center gap-2 text-green-500">
              <CheckCircle className="w-4 h-4" />
              <span className="text-sm">Método de pago actualizado correctamente</span>
            </div>
          )}

          {/* Error Message (from modal level) */}
          {error && (
            <div className="p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center gap-2 text-red-500">
              <AlertCircle className="w-4 h-4" />
              <span className="text-sm">{error}</span>
            </div>
          )}

          {/* Security Info */}
          <div className="p-3 bg-blue-500/5 border border-blue-500/20 rounded-lg text-sm text-[var(--text-secondary)]">
            <p className="flex items-center gap-2">
              <CreditCard className="w-4 h-4 text-blue-500" />
              <span>Tus datos de pago están protegidos y se procesan de forma segura.</span>
            </p>
          </div>
        </div>
      }
    />
  );
};
