/**
 * PaymentMethodsManager Component
 * Complete payment methods management with Stripe Elements for adding new cards
 * Epic: OQI-005 Pagos y Stripe
 */

import React, { useState, useCallback } from 'react';
import {
  CreditCard,
  Plus,
  X,
  Loader2,
  AlertCircle,
  Shield,
} from 'lucide-react';
import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
import { StripeCardElementChangeEvent } from '@stripe/stripe-js';

import PaymentMethodsList from './PaymentMethodsList';
import StripeElementsWrapper from './StripeElementsWrapper';
import {
  usePaymentMethods,
  useAddPaymentMethod,
} from '../../hooks/usePayments';

// Card Element options for dark theme
const CARD_ELEMENT_OPTIONS = {
  style: {
    base: {
      color: '#f1f5f9',
      fontFamily: 'Inter, system-ui, sans-serif',
      fontSize: '16px',
      fontSmoothing: 'antialiased',
      '::placeholder': {
        color: '#64748b',
      },
    },
    invalid: {
      color: '#ef4444',
      iconColor: '#ef4444',
    },
  },
  hidePostalCode: true,
};

// ============================================================================
// Add Payment Method Form (internal, wrapped in Elements)
// ============================================================================

interface AddPaymentMethodFormProps {
  onSuccess: () => void;
  onCancel: () => void;
}

const AddPaymentMethodForm: React.FC<AddPaymentMethodFormProps> = ({
  onSuccess,
  onCancel,
}) => {
  const stripe = useStripe();
  const elements = useElements();
  const addPaymentMethod = useAddPaymentMethod();

  const [isProcessing, setIsProcessing] = useState(false);
  const [cardError, setCardError] = useState<string | null>(null);
  const [cardComplete, setCardComplete] = useState(false);
  const [setAsDefault, setSetAsDefault] = useState(true);

  const handleCardChange = useCallback((event: StripeCardElementChangeEvent) => {
    setCardError(event.error?.message || null);
    setCardComplete(event.complete);
  }, []);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!stripe || !elements) {
      return;
    }

    const cardElement = elements.getElement(CardElement);
    if (!cardElement) {
      return;
    }

    setIsProcessing(true);
    setCardError(null);

    try {
      // Create payment method with Stripe
      const { error, paymentMethod } = await stripe.createPaymentMethod({
        type: 'card',
        card: cardElement,
      });

      if (error) {
        setCardError(error.message || 'Failed to create payment method');
        setIsProcessing(false);
        return;
      }

      if (!paymentMethod) {
        setCardError('Failed to create payment method');
        setIsProcessing(false);
        return;
      }

      // Save to backend
      await addPaymentMethod.mutateAsync(paymentMethod.id);

      onSuccess();
    } catch (err) {
      setCardError(err instanceof Error ? err.message : 'Failed to add payment method');
    } finally {
      setIsProcessing(false);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      {/* Card Element */}
      <div className="space-y-2">
        <label className="block text-sm font-medium text-gray-300">
          Card Details
        </label>
        <div className="p-4 bg-gray-900 border border-gray-700 rounded-lg focus-within:border-blue-500 transition-colors">
          <CardElement options={CARD_ELEMENT_OPTIONS} onChange={handleCardChange} />
        </div>
        {cardError && (
          <p className="text-sm text-red-400 flex items-center gap-1.5">
            <AlertCircle className="w-4 h-4" />
            {cardError}
          </p>
        )}
      </div>

      {/* Set as Default Checkbox */}
      <label className="flex items-center gap-3 cursor-pointer">
        <input
          type="checkbox"
          checked={setAsDefault}
          onChange={(e) => setSetAsDefault(e.target.checked)}
          className="w-4 h-4 rounded border-gray-600 bg-gray-800 text-blue-600 focus:ring-blue-500"
        />
        <span className="text-gray-300 text-sm">Set as default payment method</span>
      </label>

      {/* Security Note */}
      <div className="flex items-center gap-2 p-3 bg-gray-900/50 rounded-lg">
        <Shield className="w-4 h-4 text-green-400" />
        <p className="text-xs text-gray-500">
          Your card information is securely processed by Stripe and never stored on our servers.
        </p>
      </div>

      {/* Actions */}
      <div className="flex items-center justify-end gap-3 pt-2">
        <button
          type="button"
          onClick={onCancel}
          disabled={isProcessing}
          className="px-4 py-2 text-gray-400 hover:text-white transition-colors disabled:opacity-50"
        >
          Cancel
        </button>
        <button
          type="submit"
          disabled={!stripe || !cardComplete || isProcessing}
          className="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white rounded-lg font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
        >
          {isProcessing ? (
            <>
              <Loader2 className="w-4 h-4 animate-spin" />
              Processing...
            </>
          ) : (
            <>
              <Plus className="w-4 h-4" />
              Add Card
            </>
          )}
        </button>
      </div>
    </form>
  );
};

// ============================================================================
// Main PaymentMethodsManager Component
// ============================================================================

export interface PaymentMethodsManagerProps {
  title?: string;
  showTitle?: boolean;
  compact?: boolean;
  onMethodChange?: () => void;
}

const PaymentMethodsManager: React.FC<PaymentMethodsManagerProps> = ({
  title = 'Payment Methods',
  showTitle = true,
  compact = false,
  onMethodChange,
}) => {
  const [showAddForm, setShowAddForm] = useState(false);
  const { data: methods, isLoading, error, refetch } = usePaymentMethods();

  const handleAddSuccess = useCallback(() => {
    setShowAddForm(false);
    refetch();
    onMethodChange?.();
  }, [refetch, onMethodChange]);

  const handleAddNew = useCallback(() => {
    setShowAddForm(true);
  }, []);

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-12">
        <Loader2 className="w-6 h-6 text-blue-400 animate-spin" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="text-center py-8">
        <AlertCircle className="w-10 h-10 text-red-400 mx-auto mb-3" />
        <p className="text-gray-400 mb-4">
          {error instanceof Error ? error.message : 'Failed to load payment methods'}
        </p>
        <button
          onClick={() => refetch()}
          className="px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white rounded-lg text-sm"
        >
          Retry
        </button>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* Header */}
      {showTitle && (
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div className="p-2 bg-blue-600/20 rounded-lg">
              <CreditCard className="w-5 h-5 text-blue-400" />
            </div>
            <div>
              <h2 className="text-lg font-semibold text-white">{title}</h2>
              <p className="text-sm text-gray-400">
                {methods?.length ?? 0} saved payment method{methods?.length !== 1 ? 's' : ''}
              </p>
            </div>
          </div>
          {!showAddForm && (
            <button
              onClick={handleAddNew}
              className="flex items-center gap-2 px-3 py-2 bg-blue-600 hover:bg-blue-500 text-white rounded-lg text-sm transition-colors"
            >
              <Plus className="w-4 h-4" />
              Add New
            </button>
          )}
        </div>
      )}

      {/* Add Payment Method Form */}
      {showAddForm && (
        <div className="p-6 bg-gray-800/50 rounded-xl border border-gray-700">
          <div className="flex items-center justify-between mb-4">
            <h3 className="text-white font-medium flex items-center gap-2">
              <CreditCard className="w-5 h-5 text-blue-400" />
              Add New Payment Method
            </h3>
            <button
              onClick={() => setShowAddForm(false)}
              className="p-1 text-gray-400 hover:text-white transition-colors"
            >
              <X className="w-5 h-5" />
            </button>
          </div>
          <StripeElementsWrapper showLoadingState={false}>
            <AddPaymentMethodForm
              onSuccess={handleAddSuccess}
              onCancel={() => setShowAddForm(false)}
            />
          </StripeElementsWrapper>
        </div>
      )}

      {/* Payment Methods List */}
      <PaymentMethodsList
        onAddNew={handleAddNew}
        showAddButton={!showAddForm}
        compact={compact}
      />
    </div>
  );
};

export default PaymentMethodsManager;
