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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '../ui/select';
import { Textarea } from '../ui/textarea';
import { Label } from '../ui/label';
import {
  CreditCard,
  Plus,
  Loader2,
  AlertCircle,
  Eye,
  Banknote,
  Building2,
  FileCheck,
  Trash2,
  Star,
} from 'lucide-react';
import { toast } from 'sonner';
import api from '../../utils/api';
import useStripeConfig from '../../hooks/use-stripe-config';
import ConfirmationDialog from '../ConfirmationDialog';
import PasswordConfirmDialog from '../PasswordConfirmDialog';
import AddPaymentMethodDialog from '../AddPaymentMethodDialog';

/**
 * Get icon for payment method type
 */
const getPaymentTypeIcon = (paymentType) => {
  switch (paymentType) {
    case 'cash':
      return Banknote;
    case 'bank_transfer':
      return Building2;
    case 'check':
      return FileCheck;
    default:
      return CreditCard;
  }
};

/**
 * Format payment type for display
 */
const formatPaymentType = (paymentType) => {
  switch (paymentType) {
    case 'cash':
      return 'Cash';
    case 'bank_transfer':
      return 'Bank Transfer';
    case 'check':
      return 'Check';
    case 'card':
      return 'Card';
    default:
      return paymentType;
  }
};

/**
 * AdminPaymentMethodsPanel - Admin panel for managing user payment methods
 */
const AdminPaymentMethodsPanel = ({ userId, userName }) => {
  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 [addCardDialogOpen, setAddCardDialogOpen] = useState(false);
  const [addManualDialogOpen, setAddManualDialogOpen] = useState(false);
  const [clientSecret, setClientSecret] = useState(null);
  const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
  const [methodToDelete, setMethodToDelete] = useState(null);
  const [revealDialogOpen, setRevealDialogOpen] = useState(false);
  const [revealedData, setRevealedData] = useState(null);

  // Manual payment form state
  const [manualPaymentType, setManualPaymentType] = useState('cash');
  const [manualNotes, setManualNotes] = useState('');
  const [manualSetDefault, setManualSetDefault] = useState(false);

  /**
   * Fetch payment methods from API
   */
  const fetchPaymentMethods = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const response = await api.get(`/admin/users/${userId}/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);
    }
  }, [userId]);

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

  /**
   * Create SetupIntent for adding a card
   */
  const handleAddCard = async () => {
    try {
      setActionLoading(true);
      const response = await api.post(`/admin/users/${userId}/payment-methods/setup-intent`);
      setClientSecret(response.data.client_secret);
      setAddCardDialogOpen(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 card addition
   */
  const handleCardAddSuccess = () => {
    setAddCardDialogOpen(false);
    setClientSecret(null);
    fetchPaymentMethods();
  };

  /**
   * Save manual payment method
   */
  const handleSaveManualPayment = async () => {
    try {
      setActionLoading(true);
      await api.post(`/admin/users/${userId}/payment-methods/manual`, {
        payment_type: manualPaymentType,
        manual_notes: manualNotes || null,
        set_as_default: manualSetDefault,
      });
      toast.success('Manual payment method recorded');
      setAddManualDialogOpen(false);
      setManualPaymentType('cash');
      setManualNotes('');
      setManualSetDefault(false);
      fetchPaymentMethods();
    } catch (err) {
      const errorMessage = err.response?.data?.detail || 'Failed to record payment method';
      toast.error(errorMessage);
      console.error('Failed to save manual payment:', err);
    } finally {
      setActionLoading(false);
    }
  };

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

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

    try {
      setActionLoading(true);
      await api.delete(`/admin/users/${userId}/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);
    } finally {
      setActionLoading(false);
    }
  };

  /**
   * Reveal sensitive payment details with password confirmation
   */
  const handleRevealDetails = async (password) => {
    try {
      setActionLoading(true);
      const response = await api.post(`/admin/users/${userId}/payment-methods/reveal`, {
        password,
      });
      setRevealedData(response.data);
      setRevealDialogOpen(false);
      toast.success('Sensitive details revealed');
    } catch (err) {
      const errorMessage = err.response?.data?.detail || 'Failed to reveal details';
      throw new Error(errorMessage);
    } finally {
      setActionLoading(false);
    }
  };

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

  return (
    <>
      <Card className="p-6 bg-background rounded-2xl border border-[var(--neutral-800)]">
        {/* Header */}
        <div className="flex items-center justify-between mb-6">
          <div className="flex items-center gap-2">
            <CreditCard className="h-5 w-5 text-brand-purple" />
            <h2
              className="text-lg font-semibold text-[var(--purple-ink)]"
              style={{ fontFamily: "'Inter', sans-serif" }}
            >
              Payment Methods
            </h2>
          </div>
          <div className="flex items-center gap-2">
            <Button
              type="button"
              onClick={() => setRevealDialogOpen(true)}
              disabled={actionLoading || paymentMethods.length === 0}
              variant="outline"
              size="sm"
              className="border-brand-purple text-brand-purple hover:bg-[var(--lavender-300)] rounded-lg"
            >
              <Eye className="h-4 w-4 mr-1" />
              Reveal Details
            </Button>
            <Button
              type="button"
              onClick={() => setAddManualDialogOpen(true)}
              disabled={actionLoading}
              variant="outline"
              size="sm"
              className="border-brand-purple text-brand-purple hover:bg-[var(--lavender-300)] rounded-lg"
            >
              <Banknote className="h-4 w-4 mr-1" />
              Add Manual
            </Button>
            <Button
              type="button"
              onClick={handleAddCard}
              disabled={actionLoading}
              size="sm"
              className="bg-brand-purple text-white hover:bg-[var(--purple-ink)] rounded-lg"
            >
              {actionLoading ? (
                <Loader2 className="h-4 w-4 animate-spin" />
              ) : (
                <>
                  <Plus className="h-4 w-4 mr-1" />
                  Add Card
                </>
              )}
            </Button>
          </div>
        </div>

        {/* Loading State */}
        {loading && (
          <div className="flex items-center justify-center py-8">
            <Loader2 className="h-6 w-6 animate-spin text-brand-purple" />
          </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">{error}</p>
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={fetchPaymentMethods}
              className="ml-auto"
            >
              Retry
            </Button>
          </div>
        )}

        {/* Payment Methods List */}
        {!loading && !error && (
          <div className="space-y-3">
            {paymentMethods.length === 0 ? (
              <p
                className="text-center py-6 text-brand-purple"
                style={{ fontFamily: "'Nunito Sans', sans-serif" }}
              >
                No payment methods on file for this user.
              </p>
            ) : (
              (revealedData || paymentMethods).map((method) => {
                const PaymentIcon = getPaymentTypeIcon(method.payment_type);
                return (
                  <div
                    key={method.id}
                    className={`flex items-center justify-between p-4 border rounded-xl ${
                      method.is_default
                        ? 'border-brand-purple bg-[var(--lavender-500)]'
                        : 'border-[var(--neutral-800)] bg-white'
                    }`}
                  >
                    <div className="flex items-center gap-3">
                      <div
                        className={`p-2 rounded-full ${
                          method.is_default
                            ? 'bg-brand-purple text-white'
                            : 'bg-[var(--lavender-300)] text-brand-purple'
                        }`}
                      >
                        <PaymentIcon className="h-4 w-4" />
                      </div>
                      <div>
                        {method.payment_type === 'card' ? (
                          <>
                            <div className="flex items-center gap-2">
                              <span
                                className="font-medium text-[var(--purple-ink)]"
                                style={{ fontFamily: "'Inter', sans-serif" }}
                              >
                                {method.card_brand
                                  ? method.card_brand.charAt(0).toUpperCase() +
                                    method.card_brand.slice(1)
                                  : 'Card'}{' '}
                                •••• {method.card_last4 || '****'}
                              </span>
                              {method.is_default && (
                                <span className="flex items-center gap-1 text-xs text-brand-purple font-medium">
                                  <Star className="h-3 w-3 fill-current" />
                                  Default
                                </span>
                              )}
                            </div>
                            <p
                              className="text-sm text-brand-purple"
                              style={{ fontFamily: "'Nunito Sans', sans-serif" }}
                            >
                              Expires {method.card_exp_month?.toString().padStart(2, '0')}/
                              {method.card_exp_year?.toString().slice(-2)}
                              {revealedData && method.stripe_payment_method_id && (
                                <span className="ml-2 text-xs font-mono bg-[var(--lavender-300)] px-2 py-0.5 rounded">
                                  {method.stripe_payment_method_id}
                                </span>
                              )}
                            </p>
                          </>
                        ) : (
                          <>
                            <div className="flex items-center gap-2">
                              <span
                                className="font-medium text-[var(--purple-ink)]"
                                style={{ fontFamily: "'Inter', sans-serif" }}
                              >
                                {formatPaymentType(method.payment_type)}
                              </span>
                              {method.is_default && (
                                <span className="flex items-center gap-1 text-xs text-brand-purple font-medium">
                                  <Star className="h-3 w-3 fill-current" />
                                  Default
                                </span>
                              )}
                            </div>
                            {method.manual_notes && (
                              <p
                                className="text-sm text-brand-purple"
                                style={{ fontFamily: "'Nunito Sans', sans-serif" }}
                              >
                                {method.manual_notes}
                              </p>
                            )}
                          </>
                        )}
                      </div>
                    </div>

                    {/* Actions */}
                    <div className="flex items-center gap-2">
                      {!method.is_default && (
                        <Button
                          type="button"
                          variant="outline"
                          size="sm"
                          onClick={() => handleSetDefault(method.id)}
                          disabled={actionLoading}
                          className="text-xs"
                        >
                          Set Default
                        </Button>
                      )}
                      <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={() => {
                          setMethodToDelete(method.id);
                          setDeleteConfirmOpen(true);
                        }}
                        disabled={actionLoading}
                        className="border-red-500 text-red-500 hover:bg-red-50 p-2"
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    </div>
                  </div>
                );
              })
            )}
          </div>
        )}
      </Card>

      {/* Add Card Dialog */}
      {clientSecret && stripePromise && (
        <Elements stripe={stripePromise} options={elementsOptions}>
          <AddPaymentMethodDialog
            open={addCardDialogOpen}
            onOpenChange={(open) => {
              setAddCardDialogOpen(open);
              if (!open) setClientSecret(null);
            }}
            onSuccess={handleCardAddSuccess}
            clientSecret={clientSecret}
            saveEndpoint={`/admin/users/${userId}/payment-methods`}
          />
        </Elements>
      )}

      {/* Add Manual Payment Method Dialog */}
      <ConfirmationDialog
        open={addManualDialogOpen}
        onOpenChange={setAddManualDialogOpen}
        onConfirm={handleSaveManualPayment}
        title="Record Manual Payment Method"
        description={
          <div className="space-y-4 mt-4">
            <div className="space-y-2">
              <Label>Payment Type</Label>
              <Select value={manualPaymentType} onValueChange={setManualPaymentType}>
                <SelectTrigger className="w-full">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="cash">Cash</SelectItem>
                  <SelectItem value="check">Check</SelectItem>
                  <SelectItem value="bank_transfer">Bank Transfer</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Notes (optional)</Label>
              <Textarea
                value={manualNotes}
                onChange={(e) => setManualNotes(e.target.value)}
                placeholder="e.g., Check #1234, received 01/15/2026"
                className="min-h-[80px]"
              />
            </div>
          </div>
        }
        confirmText="Save"
        variant="info"
        loading={actionLoading}
      />

      {/* 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"
        variant="danger"
        loading={actionLoading}
      />

      {/* Password Confirm Dialog for Reveal */}
      <PasswordConfirmDialog
        open={revealDialogOpen}
        onOpenChange={setRevealDialogOpen}
        onConfirm={handleRevealDetails}
        title="Reveal Sensitive Details"
        description="Enter your password to view Stripe payment method IDs. This action will be logged."
        loading={actionLoading}
      />
    </>
  );
};

export default AdminPaymentMethodsPanel;
