import React, { useState } from 'react';
import {
  Box,
  Typography,
  TextField,
  Button,
  CircularProgress,
  Alert,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Chip,
} from '@mui/material';
import { CardElement, AddressElement, useStripe, useElements } from '@stripe/react-stripe-js';
import { format } from 'date-fns';
import toast from 'react-hot-toast';
import { Card } from '../../../shared-minimal/components/Card';
import { useCreateDonation, useDonations } from '../hooks/useSubscription';
import type { StripeCardElementChangeEvent, StripeAddressElementChangeEvent } from '@stripe/stripe-js';
import type { SubscriptionTier } from '../types/subscription.types';

interface DonationSectionProps {
  currentTier?: SubscriptionTier;
}

const CARD_ELEMENT_OPTIONS = {
  style: {
    base: {
      fontSize: '16px',
      color: '#424770',
      '::placeholder': {
        color: '#aab7c4',
      },
    },
    invalid: {
      color: '#9e2146',
    },
  },
};

export const DonationSection: React.FC<DonationSectionProps> = ({ currentTier }) => {
  const stripe = useStripe();
  const elements = useElements();
  const [amount, setAmount] = useState<string>('');
  const [error, setError] = useState<string | null>(null);
  const [processing, setProcessing] = useState(false);
  const [cardComplete, setCardComplete] = useState(false);
  const [addressComplete, setAddressComplete] = useState(false);
  const [showSuccess, setShowSuccess] = useState(false);

  const createDonationMutation = useCreateDonation();
  const { data: donationsData, isLoading: isLoadingDonations } = useDonations();

  const donations = donationsData?.data || [];

  const handleCardChange = (event: StripeCardElementChangeEvent) => {
    setError(event.error?.message || null);
    setCardComplete(event.complete);
  };

  const handleAddressChange = (event: StripeAddressElementChangeEvent) => {
    setAddressComplete(event.complete);
  };

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

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

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

    const addressElement = elements.getElement(AddressElement);
    if (!addressElement) {
      return;
    }

    // Validate amount
    const amountNum = parseFloat(amount);
    if (isNaN(amountNum) || amountNum < 0.5) {
      setError('Minimum donation amount is $0.50');
      return;
    }

    // Get billing address data
    const addressData = await addressElement.getValue();
    if (!addressData.complete) {
      setError('Please complete the billing address');
      return;
    }

    setProcessing(true);
    setError(null);

    try {
      // Create donation payment intent
      const donationResponse = await createDonationMutation.mutateAsync(amountNum);
      const { clientSecret } = donationResponse.data;

      // Confirm payment with Stripe including billing details
      const { error: confirmError } = await stripe.confirmCardPayment(clientSecret, {
        payment_method: {
          card: cardElement,
          billing_details: {
            name: addressData.value.name,
            address: {
              line1: addressData.value.address.line1,
              line2: addressData.value.address.line2 || undefined,
              city: addressData.value.address.city,
              state: addressData.value.address.state,
              postal_code: addressData.value.address.postal_code,
              country: addressData.value.address.country,
            },
          },
        },
      });

      if (confirmError) {
        setError(confirmError.message || 'Payment failed');
        setProcessing(false);
        return;
      }

      // Success!
      setShowSuccess(true);
      setAmount('');
      cardElement.clear();
      toast.success('Thank you for your donation!');

      // Hide success message after 5 seconds
      setTimeout(() => {
        setShowSuccess(false);
      }, 5000);
    } catch (err: unknown) {
      const error = err as { response?: { data?: { error?: string } } };
      setError(error.response?.data?.error || 'An unexpected error occurred');
    } finally {
      setProcessing(false);
    }
  };

  const isFormValid = amount && parseFloat(amount) >= 0.5 && cardComplete && addressComplete && !processing;

  return (
    <Card padding="lg">
      <Typography variant="h6" fontWeight="bold" gutterBottom>
        Support MotoVaultPro
      </Typography>

      {currentTier === 'free' && (
        <Alert severity="info" sx={{ mb: 3 }}>
          Love MotoVaultPro? Consider making a one-time donation to help pay for the costs to run the site.
        </Alert>
      )}

      <Typography variant="body2" color="text.secondary" gutterBottom sx={{ mb: 3 }}>
        Your donations help us pay for hosting costs and coffee. Thank you for your support!
      </Typography>

      {showSuccess && (
        <Alert severity="success" sx={{ mb: 3 }}>
          Thank you for the donation! You're helping keep the tires on the road.
        </Alert>
      )}

      <form onSubmit={handleSubmit}>
        <Box sx={{ mb: 3 }}>
          <Typography variant="subtitle2" gutterBottom>
            Donation Amount
          </Typography>
          <TextField
            fullWidth
            type="number"
            value={amount}
            onChange={(e) => setAmount(e.target.value)}
            placeholder="Enter amount"
            InputProps={{
              startAdornment: <Typography sx={{ mr: 1 }}>$</Typography>,
            }}
            inputProps={{
              min: 0.5,
              step: 0.01,
            }}
            disabled={processing}
          />
        </Box>

        <Box sx={{ mb: 3 }}>
          <Typography variant="subtitle2" gutterBottom>
            Billing Address
          </Typography>
          <Box
            sx={{
              border: 1,
              borderColor: 'divider',
              borderRadius: 1,
              p: 2,
              '&:hover': {
                borderColor: 'primary.main',
              },
            }}
          >
            <AddressElement
              options={{
                mode: 'billing',
                defaultValues: {
                  address: {
                    country: 'US',
                  },
                },
              }}
              onChange={handleAddressChange}
            />
          </Box>
        </Box>

        <Box sx={{ mb: 3 }}>
          <Typography variant="subtitle2" gutterBottom>
            Card Details
          </Typography>
          <Box
            sx={{
              border: 1,
              borderColor: 'divider',
              borderRadius: 1,
              p: 2,
              '&:hover': {
                borderColor: 'primary.main',
              },
            }}
          >
            <CardElement options={CARD_ELEMENT_OPTIONS} onChange={handleCardChange} />
          </Box>
        </Box>

        {error && (
          <Alert severity="error" sx={{ mb: 2 }}>
            {error}
          </Alert>
        )}

        <Button
          type="submit"
          variant="contained"
          color="primary"
          fullWidth
          disabled={!isFormValid}
          startIcon={processing && <CircularProgress size={20} />}
        >
          {processing ? 'Processing...' : 'Donate'}
        </Button>
      </form>

      {donations.length > 0 && (
        <Box sx={{ mt: 4 }}>
          <Typography variant="subtitle1" fontWeight="bold" gutterBottom>
            Donation History
          </Typography>

          {isLoadingDonations ? (
            <Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}>
              <CircularProgress />
            </Box>
          ) : (
            <TableContainer>
              <Table>
                <TableHead>
                  <TableRow>
                    <TableCell>Date</TableCell>
                    <TableCell>Amount</TableCell>
                    <TableCell>Status</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {donations.map((donation: any) => (
                    <TableRow key={donation.id}>
                      <TableCell>{format(new Date(donation.createdAt), 'MMM dd, yyyy')}</TableCell>
                      <TableCell>${(donation.amountCents / 100).toFixed(2)}</TableCell>
                      <TableCell>
                        <Chip
                          label={donation.status}
                          color={donation.status === 'succeeded' ? 'success' : 'default'}
                          size="small"
                        />
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </TableContainer>
          )}
        </Box>
      )}
    </Card>
  );
};
