/**
 * Registration Container Component
 * Main container that manages registration state and flow with atomic payment architecture
 */

import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useSearchParams, useNavigate } from 'react-router-dom';
import { Card } from '../../ui';
import { showToast } from '../../../utils/toast';
import { useAuthStore } from '../../../stores/auth.store';
import { usePilotDetection } from '../../../hooks/usePilotDetection';
import { apiClient } from '../../../api';
import { validateEmail } from '../../../utils/validation';
import { getSubscriptionFromJWT, getTenantAccessFromJWT, getPrimaryTenantIdFromJWT } from '../../../utils/jwt';
import { loadStripe, Stripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
import { useRegistrationState, RegistrationStep } from './hooks/useRegistrationState';
import BasicInfoStep from './BasicInfoStep';
import SubscriptionStep from './SubscriptionStep';
import { PaymentStep } from './PaymentStep';
import { CheckCircle, Circle } from 'lucide-react';

// Helper to get Stripe key from runtime config or build-time env
const getStripeKey = (): string => {
  if (typeof window !== 'undefined' && window.__RUNTIME_CONFIG__?.VITE_STRIPE_PUBLISHABLE_KEY) {
    return window.__RUNTIME_CONFIG__.VITE_STRIPE_PUBLISHABLE_KEY;
  }
  return import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY || 'pk_test_51QuxKyIzCdnBmAVTGM8fvXYkItrBUILz6lHYwhAva6ZAH1HRi0e8zDRgZ4X3faN0zEABp5RHjCVBmMJL3aKXbaC200fFrSNnPl';
};

// Force Stripe to use test environment by loading from test endpoint
const stripePromise = loadStripe(getStripeKey(), {
  stripeAccount: import.meta.env.VITE_STRIPE_ACCOUNT_ID,
  apiVersion: '2023-10-16',
  betas: ['elements_v2']
});

interface RegistrationContainerProps {
  onSuccess?: () => void;
  onLoginClick?: () => void;
  className?: string;
}

export const RegistrationContainer: React.FC<RegistrationContainerProps> = ({
  onLoginClick,
  className
}) => {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const { isPilot, couponCode } = usePilotDetection();
  const [searchParams] = useSearchParams();

  // Get auth store functions for 3DS redirect recovery
  const verifySetupIntent = useAuthStore((state) => state.verifySetupIntent);
  const completeRegistrationAfterPayment = useAuthStore((state) => state.completeRegistrationAfterPayment);

  // Helper function to perform auto-login after registration (used in 3DS redirect recovery)
  const performAutoLogin = (result: any) => {
    if (result.access_token && result.refresh_token) {
      // Set tokens in API client
      apiClient.setAuthToken(result.access_token);
      apiClient.setRefreshToken(result.refresh_token);

      // Extract subscription from JWT
      const jwtSubscription = getSubscriptionFromJWT(result.access_token);
      const jwtTenantAccess = getTenantAccessFromJWT(result.access_token);
      const primaryTenantId = getPrimaryTenantIdFromJWT(result.access_token);

      // Update auth store directly using setState
      useAuthStore.setState({
        user: result.user ? {
          id: result.user.id,
          email: result.user.email,
          full_name: result.user.full_name,
          is_active: result.user.is_active,
          is_verified: result.user.is_verified || false,
          created_at: result.user.created_at || new Date().toISOString(),
          role: result.user.role || 'admin',
        } : null,
        token: result.access_token,
        refreshToken: result.refresh_token,
        isAuthenticated: true,
        isLoading: false,
        error: null,
        jwtSubscription,
        jwtTenantAccess,
        primaryTenantId,
        pendingSubscriptionId: result.subscription_id || null,
      });

      return true;
    }
    return false;
  };

  // Get URL parameters
  const planParam = searchParams.get('plan');
  const VALID_PLANS = ['starter', 'professional', 'enterprise'] as const;
  type PlanType = typeof VALID_PLANS[number];
  const preSelectedPlan: PlanType | null = (planParam && VALID_PLANS.includes(planParam as PlanType)) ? planParam as PlanType : null;
  
  const billingParam = searchParams.get('billing_cycle');
  const urlBillingCycle = (billingParam === 'monthly' || billingParam === 'yearly') ? billingParam : null;
  
  const urlPilotParam = searchParams.get('pilot') === 'true';
  // Use URL parameter to override pilot detection if present
  const effectivePilotState = urlPilotParam || isPilot;

  // 3DS redirect parameters (Stripe adds these after redirect)
  const setupIntentParam = searchParams.get('setup_intent');
  const setupIntentClientSecretParam = searchParams.get('setup_intent_client_secret');
  const redirectStatusParam = searchParams.get('redirect_status');

  // State for 3DS redirect recovery
  const [redirectRecoveryInProgress, setRedirectRecoveryInProgress] = useState(false);
  const [redirectRecoveryError, setRedirectRecoveryError] = useState<string | null>(null);

  const {
    step,
    setStep,
    registrationState,
    updateRegistrationState,
    nextStep,
    prevStep,
    isSubmitting
  } = useRegistrationState({
    initialPlan: preSelectedPlan || 'starter',
    initialBillingCycle: urlBillingCycle || 'monthly',
    isPilot: effectivePilotState // Use the effective pilot state
  });

  const [stripeInstance, setStripeInstance] = useState<Stripe | null>(null);
  // paymentComplete is used for 3DS redirect recovery to prevent re-processing
  const [paymentComplete, setPaymentComplete] = useState(false);
  
  useEffect(() => {
    const loadStripeInstance = async () => {
      const stripe = await stripePromise;
      setStripeInstance(stripe);
    };
    loadStripeInstance();
  }, []);

  // Handle 3DS redirect recovery when user returns from bank page
  useEffect(() => {
    const handle3DSRedirectRecovery = async () => {
      // Only proceed if we have the redirect parameters
      if (!setupIntentParam || !redirectStatusParam || !stripeInstance) {
        return;
      }

      // Don't re-process if already in progress or already completed
      if (redirectRecoveryInProgress || paymentComplete) {
        return;
      }

      setRedirectRecoveryInProgress(true);
      setRedirectRecoveryError(null);

      try {
        console.log('3DS redirect recovery: Processing redirect return', {
          setupIntent: setupIntentParam,
          redirectStatus: redirectStatusParam
        });

        // Verify the redirect status
        if (redirectStatusParam !== 'succeeded') {
          const errorMessage = t('auth:payment.3ds_redirect_failed', '3DS verification was not successful. Please try again.');
          setRedirectRecoveryError(errorMessage);
          showToast.error(errorMessage);
          setRedirectRecoveryInProgress(false);
          return;
        }

        // Retrieve saved registration state from sessionStorage
        const savedStateKey = `registration_state_${setupIntentParam}`;
        const savedStateJson = sessionStorage.getItem(savedStateKey);

        if (!savedStateJson) {
          // No saved state - user needs to restart registration
          const errorMessage = t('auth:payment.session_expired', 'Your registration session has expired. Please start again.');
          setRedirectRecoveryError(errorMessage);
          showToast.error(errorMessage);
          setRedirectRecoveryInProgress(false);
          return;
        }

        const savedState = JSON.parse(savedStateJson);
        console.log('3DS redirect recovery: Found saved state', savedState);

        // Restore registration state
        updateRegistrationState({
          basicInfo: savedState.basicInfo,
          subscription: savedState.subscription,
          paymentSetup: savedState.paymentSetup
        });
        setStep('payment');

        // Verify the SetupIntent status with our backend
        const verificationResult = await verifySetupIntent(setupIntentParam);

        if (!verificationResult.verified) {
          const errorMessage = verificationResult.error || t('auth:payment.verification_failed', 'Payment verification failed.');
          setRedirectRecoveryError(errorMessage);
          showToast.error(errorMessage);
          setRedirectRecoveryInProgress(false);
          return;
        }

        console.log('3DS redirect recovery: SetupIntent verified', verificationResult);

        // SetupIntent is verified - now complete the registration
        const registrationData = {
          email: savedState.basicInfo.email,
          full_name: `${savedState.basicInfo.firstName} ${savedState.basicInfo.lastName}`,
          password: savedState.basicInfo.password,
          subscription_plan: savedState.subscription.planId,
          billing_cycle: savedState.subscription.billingInterval,
          payment_customer_id: savedState.paymentSetup.customerId,
          payment_method_id: savedState.paymentSetup.paymentMethodId || verificationResult.payment_method_id,
          subscription_id: verificationResult.subscription_id,
          coupon_code: effectivePilotState ? couponCode : savedState.subscription.couponCode,
          terms_accepted: savedState.basicInfo.acceptTerms,
          privacy_accepted: savedState.basicInfo.acceptTerms,
          marketing_consent: savedState.basicInfo.marketingConsent,
          analytics_consent: savedState.basicInfo.analyticsConsent,
          setup_intent_id: setupIntentParam,
          threeds_completed: true
        };

        // Complete the registration after 3DS verification
        const result = await completeRegistrationAfterPayment(registrationData);

        if (result.success) {
          // Clean up saved state
          sessionStorage.removeItem(savedStateKey);

          // Clean up URL parameters
          const newUrl = new URL(window.location.href);
          newUrl.searchParams.delete('setup_intent');
          newUrl.searchParams.delete('setup_intent_client_secret');
          newUrl.searchParams.delete('redirect_status');
          window.history.replaceState({}, '', newUrl.toString());

          // Perform auto-login if tokens are returned
          performAutoLogin(result);

          showToast.success(t('auth:registration_complete', 'Registration complete! Redirecting to onboarding...'));

          // Mark payment as complete to prevent re-processing
          setPaymentComplete(true);

          // Navigate to onboarding
          setTimeout(() => {
            navigate('/app/onboarding');
          }, 100);
        } else {
          setRedirectRecoveryError(result.message || t('auth:registration_failed', 'Registration failed'));
          showToast.error(result.message || t('auth:registration_failed', 'Registration failed'));
        }
      } catch (error) {
        console.error('3DS redirect recovery error:', error);
        const errorMessage = error instanceof Error ? error.message : t('auth:payment.recovery_failed', 'Failed to recover payment session');
        setRedirectRecoveryError(errorMessage);
        showToast.error(errorMessage);
      } finally {
        setRedirectRecoveryInProgress(false);
      }
    };

    handle3DSRedirectRecovery();
  }, [setupIntentParam, redirectStatusParam, stripeInstance, paymentComplete, redirectRecoveryInProgress]);

  const handleRegistrationSubmit = async () => {
    try {
      if (step === 'basic_info') {
        // Validate basic info and proceed to next step
        const isValid = validateBasicInfo();
        if (!isValid) return;
        
        // Skip subscription step if plan was pre-selected from URL (landing page selection)
        if (preSelectedPlan) {
          // Ensure subscription data is set with the pre-selected plan
          updateRegistrationState({
            subscription: {
              ...registrationState.subscription,
              planId: preSelectedPlan,
              billingInterval: urlBillingCycle || registrationState.subscription.billingInterval
            }
          });
          // Skip directly to payment step
          setStep('payment');
        } else {
          // Go to subscription selection step
          nextStep();
        }
      } else if (step === 'subscription') {
        // Validate subscription selection and proceed to payment step
        const isValid = validateSubscription();
        if (!isValid) return;
        nextStep();
      } else if (step === 'payment') {
        // Payment step is handled by PaymentStep component
        // This should not be reached as PaymentStep handles its own submission
      }
    } catch (error) {
      console.error('Registration step error:', error);
      showToast.error(t('auth:alerts.error_create'), {
        title: t('auth:alerts.error')
      });
    }
  };
  
  const validateBasicInfo = (): boolean => {
    const { basicInfo } = registrationState;
    const newErrors: any = {};
    
    if (!basicInfo.email || !validateEmail(basicInfo.email)) {
      newErrors.email = t('auth:register.invalid_email');
    }
    
    if (!basicInfo.firstName || basicInfo.firstName.length < 2) {
      newErrors.firstName = t('auth:register.invalid_first_name');
    }
    
    if (!basicInfo.lastName || basicInfo.lastName.length < 2) {
      newErrors.lastName = t('auth:register.invalid_last_name');
    }
    
    if (!basicInfo.password || basicInfo.password.length < 8) {
      newErrors.password = t('auth:register.invalid_password');
    }
    
    if (!basicInfo.acceptTerms) {
      newErrors.acceptTerms = t('auth:register.terms_required');
    }
    
    if (Object.keys(newErrors).length > 0) {
      updateRegistrationState({ errors: newErrors });
      return false;
    }
    
    return true;
  };
  
  const validateSubscription = (): boolean => {
    const { subscription } = registrationState;

    if (!subscription.planId || !subscription.billingInterval) {
      updateRegistrationState({
        errors: { subscription: t('auth:register.select_plan') }
      });
      return false;
    }

    return true;
  };

  // Calculate progress percentage
  const getProgressPercentage = () => {
    const steps = preSelectedPlan
      ? ['basic_info', 'payment']
      : ['basic_info', 'subscription', 'payment'];
    const currentIndex = steps.indexOf(step);
    return currentIndex >= 0 ? ((currentIndex + 1) / steps.length) * 100 : 0;
  };

  // Get step names for progress indicator
  const getStepName = (stepKey: RegistrationStep) => {
    switch (stepKey) {
      case 'basic_info': return t('auth:register.step_basic_info', 'Información Básica');
      case 'subscription': return t('auth:register.step_subscription', 'Suscripción');
      case 'payment': return t('auth:register.step_payment', 'Pago');
      default: return '';
    }
  };

  // Determine which steps to show in progress indicator
  const progressSteps: RegistrationStep[] = preSelectedPlan
    ? ['basic_info', 'payment']
    : ['basic_info', 'subscription', 'payment'];

  // Render current step
  const renderStep = () => {
    switch (step) {
      case 'basic_info':
        return (
          <BasicInfoStep
            formData={registrationState.basicInfo}
            errors={registrationState.errors}
            updateField={(field, value) => updateRegistrationState({ 
              basicInfo: { ...registrationState.basicInfo, [field]: value } 
            })}
            onNext={handleRegistrationSubmit}
            isPilot={isPilot}
            isSubmitting={isSubmitting}
            onLoginClick={onLoginClick}
          />
        );
      case 'subscription':
        return (
          <SubscriptionStep
            selectedPlan={registrationState.subscription.planId}
            billingCycle={registrationState.subscription.billingInterval}
            useTrial={registrationState.subscription.useTrial}
            couponCode={registrationState.subscription.couponCode}
            updateField={(field, value) => updateRegistrationState({ 
              subscription: { ...registrationState.subscription, [field]: value } 
            })}
            onNext={handleRegistrationSubmit}
            onBack={prevStep}
            isPilot={isPilot}
          />
        );
      case 'payment':
        return (
          <Elements
            stripe={stripeInstance}
            options={{
              mode: 'setup',
              currency: 'eur',
              paymentMethodCreation: 'manual' // Required for Payment Element
            }}
          >
            <PaymentStep
              onBack={prevStep}
              registrationState={registrationState}
              updateRegistrationState={updateRegistrationState}
            />
          </Elements>
        );
      default:
        return null;
    }
  };
  
  // Show loading state during 3DS redirect recovery
  if (redirectRecoveryInProgress) {
    return (
      <Card className={`registration-container w-full max-w-xl mx-auto px-4 sm:px-6 ${className || ''}`} variant="elevated" padding="md" shadow="lg">
        <div className="flex flex-col items-center justify-center py-12">
          <div className="animate-spin rounded-full h-12 w-12 border-4 border-[var(--color-primary)] border-t-transparent mb-4"></div>
          <h3 className="text-lg font-semibold text-[var(--text-primary)] mb-2">
            {t('auth:payment.verifying_payment', 'Verifying your payment...')}
          </h3>
          <p className="text-sm text-[var(--text-secondary)] text-center">
            {t('auth:payment.completing_registration', 'Please wait while we complete your registration.')}
          </p>
        </div>
      </Card>
    );
  }

  // Show error state if redirect recovery failed
  if (redirectRecoveryError && setupIntentParam) {
    return (
      <Card className={`registration-container w-full max-w-xl mx-auto px-4 sm:px-6 ${className || ''}`} variant="elevated" padding="md" shadow="lg">
        <div className="flex flex-col items-center justify-center py-12">
          <div className="w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 flex items-center justify-center mb-4">
            <Circle className="w-6 h-6 text-red-500" />
          </div>
          <h3 className="text-lg font-semibold text-[var(--text-primary)] mb-2">
            {t('auth:payment.recovery_failed_title', 'Payment Verification Failed')}
          </h3>
          <p className="text-sm text-[var(--text-secondary)] text-center mb-4">
            {redirectRecoveryError}
          </p>
          <button
            onClick={() => {
              // Clear error and redirect params, allow user to restart
              setRedirectRecoveryError(null);
              const newUrl = new URL(window.location.href);
              newUrl.searchParams.delete('setup_intent');
              newUrl.searchParams.delete('setup_intent_client_secret');
              newUrl.searchParams.delete('redirect_status');
              window.history.replaceState({}, '', newUrl.toString());
            }}
            className="px-4 py-2 bg-[var(--color-primary)] text-white rounded-lg hover:opacity-90 transition-opacity"
          >
            {t('auth:payment.try_again', 'Try Again')}
          </button>
        </div>
      </Card>
    );
  }

  return (
    <Card className={`registration-container w-full ${step === 'subscription' ? 'max-w-6xl' : 'max-w-xl'} mx-auto px-4 sm:px-6 ${className || ''}`} variant="elevated" padding="md" shadow="lg">
      {/* Progress Indicator - Simplified for mobile */}
      <div className="mb-4 sm:mb-6">
        {/* Progress Header */}
        <div className="flex items-center justify-between mb-3 sm:mb-4">
          <h3 className="text-sm sm:text-base font-semibold text-[var(--text-primary)]">
            {t('auth:register.registration_progress', 'Registration Progress')}
          </h3>
          <span className="text-lg sm:text-xl font-bold text-[var(--color-primary)]">
            {Math.round(getProgressPercentage())}%
          </span>
        </div>

        {/* Step Indicators - Compact on mobile */}
        <div className="flex items-center justify-between mb-3 gap-1">
          {progressSteps.map((stepKey, index) => {
            const isActive = step === stepKey;
            const isCompleted = progressSteps.indexOf(step) > index;

            return (
              <div key={stepKey} className="flex flex-col items-center flex-1">
                {/* Step Circle - Smaller on mobile */}
                <div className={`flex items-center justify-center w-8 h-8 sm:w-10 sm:h-10 rounded-full border-2 transition-all ${
                  isCompleted ? 'bg-[var(--color-primary)] border-[var(--color-primary)]' :
                  isActive ? 'bg-[var(--color-primary)] border-[var(--color-primary)]' :
                  'bg-gray-100 dark:bg-gray-700 border-gray-300 dark:border-gray-600'
                }`}>
                  {isCompleted ? (
                    <CheckCircle className="w-4 h-4 sm:w-5 sm:h-5 text-white" />
                  ) : (
                    <span className={`text-xs sm:text-sm ${
                      isActive ? 'text-white' : 'text-gray-500 dark:text-gray-400'
                    }`}>
                      {index + 1}
                    </span>
                  )}
                </div>

                {/* Step Label - Only show on larger screens */}
                <span className={`text-[10px] sm:text-xs mt-1 font-medium text-center hidden sm:block ${
                  isCompleted || isActive ? 'text-[var(--color-primary)]' : 'text-gray-400 dark:text-gray-500'
                }`}>
                  {getStepName(stepKey)}
                </span>
              </div>
            );
          })}
        </div>

        {/* Progress Bar */}
        <div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-1.5 sm:h-2 overflow-hidden">
          <div
            className="bg-[var(--color-primary)] h-full transition-all duration-300 ease-in-out"
            style={{ width: `${getProgressPercentage()}%` }}
          />
        </div>
      </div>

      {renderStep()}
    </Card>
  );
};

export default RegistrationContainer;