import React, { useState, useEffect, useCallback } from 'react';
import { Elements } from '@stripe/react-stripe-js';
import { Card } from './ui/card';
import { Button } from './ui/button';
import { CreditCard, Plus, Loader2, AlertCircle } from 'lucide-react';
import { toast } from 'sonner';
import api from '../utils/api';
import useStripeConfig from '../hooks/use-stripe-config';
import PaymentMethodCard from './PaymentMethodCard';
import AddPaymentMethodDialog from './AddPaymentMethodDialog';
import ConfirmationDialog from './ConfirmationDialog';

/**
 * PaymentMethodsSection - Manages user payment methods
 *
 * Features:
 * - List saved payment methods
 * - Add new payment method via Stripe SetupIntent
 * - Set default payment method
 * - Delete payment methods
 */
const PaymentMethodsSection = () => {
  const [paymentMethods, setPaymentMethods] = useState([]);
  const [loading, setLoading] = useState(true);
  const [actionLoading, setActionLoading] = useState(false);
  const [error, setError] = useState(null);

  // Get Stripe configuration from API
  const { stripePromise, loading: stripeLoading, error: stripeError } = useStripeConfig();

  // Dialog states
  const [addDialogOpen, setAddDialogOpen] = useState(false);
  const [clientSecret, setClientSecret] = useState(null);
  const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
  const [methodToDelete, setMethodToDelete] = useState(null);

  /**
   * Fetch payment methods from API
   */
  const fetchPaymentMethods = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const response = await api.get('/payment-methods');
      setPaymentMethods(response.data);
    } catch (err) {
      const errorMessage = err.response?.data?.detail || 'Failed to load payment methods';
      setError(errorMessage);
      console.error('Failed to fetch payment methods:', err);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchPaymentMethods();
  }, [fetchPaymentMethods]);

  /**
   * Create SetupIntent and open add dialog
   */
  const handleAddNew = async () => {
    try {
      setActionLoading(true);
      const response = await api.post('/payment-methods/setup-intent');
      setClientSecret(response.data.client_secret);
      setAddDialogOpen(true);
    } catch (err) {
      const errorMessage = err.response?.data?.detail || 'Failed to initialize payment setup';
      toast.error(errorMessage);
      console.error('Failed to create setup intent:', err);
    } finally {
      setActionLoading(false);
    }
  };

  /**
   * Handle successful payment method addition
   */
  const handleAddSuccess = () => {
    setAddDialogOpen(false);
    setClientSecret(null);
    fetchPaymentMethods();
  };

  /**
   * Set a payment method as default
   */
  const handleSetDefault = async (methodId) => {
    try {
      setActionLoading(true);
      await api.put(`/payment-methods/${methodId}/default`);
      toast.success('Default payment method updated');
      fetchPaymentMethods();
    } catch (err) {
      const errorMessage = err.response?.data?.detail || 'Failed to update default payment method';
      toast.error(errorMessage);
      console.error('Failed to set default:', err);
    } finally {
      setActionLoading(false);
    }
  };

  /**
   * Open delete confirmation dialog
   */
  const handleDeleteClick = (methodId) => {
    setMethodToDelete(methodId);
    setDeleteConfirmOpen(true);
  };

  /**
   * Confirm and delete payment method
   */
  const handleDeleteConfirm = async () => {
    if (!methodToDelete) return;

    try {
      setActionLoading(true);
      await api.delete(`/payment-methods/${methodToDelete}`);
      toast.success('Payment method removed');
      setDeleteConfirmOpen(false);
      setMethodToDelete(null);
      fetchPaymentMethods();
    } catch (err) {
      const errorMessage = err.response?.data?.detail || 'Failed to remove payment method';
      toast.error(errorMessage);
      console.error('Failed to delete payment method:', err);
    } finally {
      setActionLoading(false);
    }
  };

  // Stripe Elements options - simplified for CardElement
  const elementsOptions = {
    appearance: {
      theme: 'stripe',
      variables: {
        colorPrimary: '#6b5b95',
        colorBackground: '#ffffff',
        colorText: '#2d2a4a',
        colorDanger: '#ef4444',
        fontFamily: "'Nunito Sans', sans-serif",
        borderRadius: '12px',
      },
    },
  };

  return (
    <>
      <Card className="space-y-4 px-6 pb-6">
        {/* Header */}
        <div className="bg-brand-purple text-white px-4 py-3 rounded-t-lg -mx-6 -mt-0 flex items-center justify-between">
          <div className="flex items-center gap-2">
            <CreditCard className="h-5 w-5" />
            <h3
              className="font-semibold"
              style={{ fontFamily: "'Inter', sans-serif" }}
            >
              Payment Methods
            </h3>
          </div>
          <Button
            type="button"
            onClick={handleAddNew}
            disabled={actionLoading}
            size="sm"
            className="bg-white text-brand-purple hover:bg-[var(--lavender-300)] rounded-lg px-3 py-1"
          >
            {actionLoading ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <>
                <Plus className="h-4 w-4 mr-1" />
                Add
              </>
            )}
          </Button>
        </div>

        {/* Loading State */}
        {loading && (
          <div className="flex items-center justify-center py-8">
            <Loader2 className="h-6 w-6 animate-spin text-brand-purple" />
            <span
              className="ml-2 text-brand-purple"
              style={{ fontFamily: "'Nunito Sans', sans-serif" }}
            >
              Loading payment methods...
            </span>
          </div>
        )}

        {/* Error State */}
        {error && !loading && (
          <div className="flex items-center gap-2 p-4 bg-red-50 border border-red-200 rounded-xl">
            <AlertCircle className="h-5 w-5 text-red-500 flex-shrink-0" />
            <p
              className="text-sm text-red-600"
              style={{ fontFamily: "'Nunito Sans', sans-serif" }}
            >
              {error}
            </p>
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={fetchPaymentMethods}
              className="ml-auto border-red-500 text-red-500 hover:bg-red-50 rounded-lg"
            >
              Retry
            </Button>
          </div>
        )}

        {/* Payment Methods List */}
        {!loading && !error && (
          <div className="space-y-3">
            {paymentMethods.length === 0 ? (
              <div className="text-center py-8">
                <CreditCard className="h-12 w-12 text-[var(--lavender-500)] mx-auto mb-3" />
                <p
                  className="text-brand-purple mb-2"
                  style={{ fontFamily: "'Nunito Sans', sans-serif" }}
                >
                  No payment methods saved
                </p>
                <p
                  className="text-sm text-brand-purple/70 mb-4"
                  style={{ fontFamily: "'Nunito Sans', sans-serif" }}
                >
                  Add a card to make payments easier
                </p>
                <Button
                  type="button"
                  onClick={handleAddNew}
                  disabled={actionLoading}
                  className="bg-brand-purple text-white hover:bg-[var(--purple-ink)] rounded-full px-6"
                >
                  {actionLoading ? (
                    <>
                      <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                      Setting up...
                    </>
                  ) : (
                    <>
                      <Plus className="h-4 w-4 mr-2" />
                      Add Payment Method
                    </>
                  )}
                </Button>
              </div>
            ) : (
              paymentMethods.map((method) => (
                <PaymentMethodCard
                  key={method.id}
                  method={method}
                  onSetDefault={handleSetDefault}
                  onDelete={handleDeleteClick}
                  loading={actionLoading}
                />
              ))
            )}
          </div>
        )}

        {/* Info Text */}
        {!loading && paymentMethods.length > 0 && (
          <p
            className="text-xs text-brand-purple/70 pt-2 border-t border-[var(--neutral-800)]"
            style={{ fontFamily: "'Nunito Sans', sans-serif" }}
          >
            Your default payment method will be used for subscription renewals and donations.
          </p>
        )}
      </Card>

      {/* Add Payment Method Dialog */}
      {clientSecret && stripePromise && (
        <Elements stripe={stripePromise} options={elementsOptions}>
          <AddPaymentMethodDialog
            open={addDialogOpen}
            onOpenChange={(open) => {
              setAddDialogOpen(open);
              if (!open) setClientSecret(null);
            }}
            onSuccess={handleAddSuccess}
            clientSecret={clientSecret}
          />
        </Elements>
      )}

      {/* Delete Confirmation Dialog */}
      <ConfirmationDialog
        open={deleteConfirmOpen}
        onOpenChange={setDeleteConfirmOpen}
        onConfirm={handleDeleteConfirm}
        title="Remove Payment Method"
        description="Are you sure you want to remove this payment method? This action cannot be undone."
        confirmText="Remove"
        cancelText="Cancel"
        variant="danger"
        loading={actionLoading}
      />
    </>
  );
};

export default PaymentMethodsSection;
