/**
 * DepositForm Component
 * Form for depositing funds to an investment account with Stripe integration
 */

import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { loadStripe } from '@stripe/stripe-js';
import {
  Elements,
  CardElement,
  useStripe,
  useElements,
} from '@stripe/react-stripe-js';

// ============================================================================
// Types
// ============================================================================

interface DepositFormData {
  amount: number;
  accountId: string;
}

interface DepositFormProps {
  accounts: Array<{
    id: string;
    accountNumber: string;
    productName: string;
    currentBalance: number;
  }>;
  onSuccess?: (transactionId: string) => void;
  onCancel?: () => void;
}

// ============================================================================
// Initialize Stripe
// ============================================================================

const stripePromise = loadStripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY || '');

// ============================================================================
// Stripe Card Styles
// ============================================================================

const cardElementOptions = {
  style: {
    base: {
      color: '#ffffff',
      fontFamily: 'system-ui, -apple-system, sans-serif',
      fontSmoothing: 'antialiased',
      fontSize: '16px',
      '::placeholder': {
        color: '#6b7280',
      },
    },
    invalid: {
      color: '#ef4444',
      iconColor: '#ef4444',
    },
  },
};

// ============================================================================
// Inner Form Component (with Stripe hooks)
// ============================================================================

function DepositFormInner({ accounts, onSuccess, onCancel }: DepositFormProps) {
  const stripe = useStripe();
  const elements = useElements();
  const [processing, setProcessing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState(false);

  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm<DepositFormData>({
    defaultValues: {
      amount: 100,
      accountId: accounts[0]?.id || '',
    },
  });

  const selectedAccountId = watch('accountId');
  const selectedAccount = accounts.find((a) => a.id === selectedAccountId);

  const onSubmit = async (data: DepositFormData) => {
    if (!stripe || !elements) {
      setError('Stripe has not loaded yet');
      return;
    }

    const cardElement = elements.getElement(CardElement);
    if (!cardElement) {
      setError('Card element not found');
      return;
    }

    setProcessing(true);
    setError(null);

    try {
      const token = localStorage.getItem('token');
      if (!token) {
        throw new Error('Please log in to continue');
      }

      // Create payment intent on the server
      const response = await fetch('/api/v1/payments/wallet/deposit', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({
          amount: data.amount,
          currency: 'USD',
          description: `Deposit to investment account ${selectedAccount?.accountNumber}`,
          metadata: {
            accountId: data.accountId,
            type: 'investment_deposit',
          },
        }),
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || 'Failed to create payment');
      }

      const paymentData = await response.json();

      // If the payment requires client-side confirmation
      if (paymentData.data?.clientSecret) {
        const { error: stripeError, paymentIntent } = await stripe.confirmCardPayment(
          paymentData.data.clientSecret,
          {
            payment_method: {
              card: cardElement,
            },
          }
        );

        if (stripeError) {
          throw new Error(stripeError.message || 'Payment failed');
        }

        if (paymentIntent?.status === 'succeeded') {
          setSuccess(true);
          onSuccess?.(paymentData.data.transactionId);
        }
      } else {
        // Payment was processed server-side
        setSuccess(true);
        onSuccess?.(paymentData.data?.id);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred');
    } finally {
      setProcessing(false);
    }
  };

  if (success) {
    return (
      <div className="text-center py-8">
        <div className="w-16 h-16 mx-auto mb-4 bg-emerald-500/20 rounded-full flex items-center justify-center">
          <svg className="w-8 h-8 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
          </svg>
        </div>
        <h3 className="text-lg font-semibold text-white mb-2">Deposit Successful!</h3>
        <p className="text-slate-400">Your funds will be credited to your account shortly.</p>
        <button
          type="button"
          onClick={onCancel}
          className="mt-6 px-6 py-2 bg-slate-700 text-white rounded-lg hover:bg-slate-600 transition-colors"
        >
          Close
        </button>
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
      {/* Account Selection */}
      <div>
        <label className="block text-sm font-medium text-slate-300 mb-2">
          Investment Account
        </label>
        <select
          {...register('accountId', { required: 'Please select an account' })}
          className="w-full px-4 py-2.5 bg-slate-800 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
        >
          {accounts.map((account) => (
            <option key={account.id} value={account.id}>
              {account.productName} ({account.accountNumber}) - ${account.currentBalance.toFixed(2)}
            </option>
          ))}
        </select>
        {errors.accountId && (
          <p className="mt-1 text-sm text-red-400">{errors.accountId.message}</p>
        )}
      </div>

      {/* Amount Input */}
      <div>
        <label className="block text-sm font-medium text-slate-300 mb-2">
          Amount (USD)
        </label>
        <div className="relative">
          <span className="absolute left-4 top-1/2 -translate-y-1/2 text-slate-400">$</span>
          <input
            type="number"
            step="0.01"
            min="10"
            max="100000"
            {...register('amount', {
              required: 'Amount is required',
              min: { value: 10, message: 'Minimum deposit is $10' },
              max: { value: 100000, message: 'Maximum deposit is $100,000' },
            })}
            className="w-full pl-8 pr-4 py-2.5 bg-slate-800 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
            placeholder="0.00"
          />
        </div>
        {errors.amount && (
          <p className="mt-1 text-sm text-red-400">{errors.amount.message}</p>
        )}
        <div className="mt-2 flex gap-2">
          {[100, 500, 1000, 5000].map((quickAmount) => (
            <button
              key={quickAmount}
              type="button"
              onClick={() => {
                const input = document.querySelector<HTMLInputElement>('input[name="amount"]');
                if (input) {
                  input.value = String(quickAmount);
                  input.dispatchEvent(new Event('input', { bubbles: true }));
                }
              }}
              className="px-3 py-1 text-sm bg-slate-700 text-slate-300 rounded hover:bg-slate-600 transition-colors"
            >
              ${quickAmount}
            </button>
          ))}
        </div>
      </div>

      {/* Card Element */}
      <div>
        <label className="block text-sm font-medium text-slate-300 mb-2">
          Card Details
        </label>
        <div className="p-4 bg-slate-800 border border-slate-700 rounded-lg">
          <CardElement options={cardElementOptions} />
        </div>
        <p className="mt-2 text-xs text-slate-500">
          Your payment is secured by Stripe. We never store your card details.
        </p>
      </div>

      {/* Error Message */}
      {error && (
        <div className="p-4 bg-red-500/10 border border-red-500/30 rounded-lg">
          <p className="text-sm text-red-400">{error}</p>
        </div>
      )}

      {/* Actions */}
      <div className="flex gap-3">
        <button
          type="submit"
          disabled={processing || !stripe}
          className="flex-1 px-6 py-2.5 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
        >
          {processing ? (
            <span className="flex items-center justify-center gap-2">
              <svg className="w-5 h-5 animate-spin" fill="none" viewBox="0 0 24 24">
                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
              </svg>
              Processing...
            </span>
          ) : (
            'Deposit Funds'
          )}
        </button>
        {onCancel && (
          <button
            type="button"
            onClick={onCancel}
            disabled={processing}
            className="px-6 py-2.5 bg-slate-700 text-white font-medium rounded-lg hover:bg-slate-600 disabled:opacity-50 transition-colors"
          >
            Cancel
          </button>
        )}
      </div>
    </form>
  );
}

// ============================================================================
// Main Component (with Stripe Elements wrapper)
// ============================================================================

export function DepositForm(props: DepositFormProps) {
  return (
    <Elements stripe={stripePromise}>
      <DepositFormInner {...props} />
    </Elements>
  );
}

export default DepositForm;
