import React, { useEffect, useState } from 'react';

interface SquarePaymentProps {
  amount: number;
  onPaymentSuccess: (paymentResult: any) => void;
  onPaymentError: (error: string) => void;
  tierId: number;
}

const SquarePayment: React.FC<SquarePaymentProps> = ({
  amount,
  onPaymentSuccess,
  onPaymentError,
  tierId
}) => {
  const [isLoading, setIsLoading] = useState(true);
  const [card, setCard] = useState<any>(null);
  const [payments, setPayments] = useState<any>(null);
  const [squareConfig, setSquareConfig] = useState<any>(null);
  
  // Billing details state
  const [cardholderName, setCardholderName] = useState('');
  const [addressLine1, setAddressLine1] = useState('');
  const [addressLine2, setAddressLine2] = useState('');
  const [city, setCity] = useState('');
  const [postalCode, setPostalCode] = useState('');
  const [isProcessing, setIsProcessing] = useState(false);

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

  useEffect(() => {
    if (squareConfig && !payments) {
      initializeSquare();
    }
  }, [squareConfig]);

  const loadSquareSDK = (environment: string): Promise<void> => {
    return new Promise((resolve, reject) => {
      // Check if Square SDK is already loaded
      if (window.Square) {
        resolve();
        return;
      }

      const script = document.createElement('script');
      script.type = 'text/javascript';
      
      // Load the correct SDK based on environment
      if (environment?.toLowerCase() === 'sandbox') {
        script.src = 'https://sandbox.web.squarecdn.com/v1/square.js';
      } else {
        script.src = 'https://web.squarecdn.com/v1/square.js';
      }
      
      script.onload = () => resolve();
      script.onerror = () => reject(new Error('Failed to load Square SDK'));
      
      document.head.appendChild(script);
    });
  };

  const loadSquareConfig = async () => {
    try {
      const response = await fetch('/api/v1/payments/config/square', {
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        }
      });
      const config = await response.json();
      console.log('Square config received:', config);
      
      // Load the appropriate Square SDK based on environment
      await loadSquareSDK(config.environment);
      console.log('Square SDK loaded for environment:', config.environment);
      
      setSquareConfig(config);
    } catch (error) {
      console.error('Failed to load Square config:', error);
      onPaymentError('Failed to load payment configuration');
      setIsLoading(false);
    }
  };

  const initializeSquare = async () => {
    if (!window.Square) {
      console.error('Square.js failed to load');
      onPaymentError('Payment system failed to load. Please refresh the page.');
      setIsLoading(false);
      return;
    }

    try {
      // Determine environment - default to production if not explicitly set to sandbox
      const environment = squareConfig.environment?.toLowerCase() === 'sandbox' ? 'sandbox' : 'production';
      console.log('Initializing Square with environment:', environment);
      console.log('Application ID:', squareConfig.application_id);
      console.log('Location ID:', squareConfig.location_id);
      
      const paymentsInstance = window.Square.payments(
        squareConfig.application_id,
        squareConfig.location_id,
        {
          environment: environment
        }
      );
      setPayments(paymentsInstance);

      // Initialize card without postal code (we collect it separately in billing form)
      const cardInstance = await paymentsInstance.card({
        style: {
          '.input-container': {
            borderColor: '#E0E0E0',
            borderRadius: '4px'
          },
          '.input-container.is-focus': {
            borderColor: '#4CAF50'
          },
          '.message-text': {
            color: '#999'
          },
          '.message-icon': {
            color: '#999'
          },
          'input': {
            fontSize: '14px'
          }
        }
      });
      await cardInstance.attach('#card-container');
      setCard(cardInstance);
      setIsLoading(false);
    } catch (error) {
      console.error('Failed to initialize Square:', error);
      onPaymentError('Failed to initialize payment form');
      setIsLoading(false);
    }
  };

  const handlePayment = async () => {
    if (!card || !payments) {
      onPaymentError('Payment form not initialized');
      return;
    }

    // Validate billing details
    if (!cardholderName.trim()) {
      onPaymentError('Please enter cardholder name');
      return;
    }
    if (!addressLine1.trim()) {
      onPaymentError('Please enter address line 1');
      return;
    }
    if (!city.trim()) {
      onPaymentError('Please enter city');
      return;
    }
    if (!postalCode.trim()) {
      onPaymentError('Please enter postal code');
      return;
    }

    setIsLoading(true);
    setIsProcessing(true);

    try {
      // Tokenize the payment method with billing details
      const result = await card.tokenize();
      
      if (result.status === 'OK') {
        // Send the token to your backend with billing details
        const response = await fetch('/api/v1/payments/square/process', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${localStorage.getItem('token')}`
          },
          body: JSON.stringify({
            source_id: result.token,
            amount: amount,
            tier_id: tierId,
            note: `Membership payment - £${amount.toFixed(2)}`,
            billing_details: {
              cardholder_name: cardholderName,
              address_line_1: addressLine1,
              address_line_2: addressLine2 || undefined,
              city: city,
              postal_code: postalCode,
              country: 'GB'
            }
          })
        });

        const paymentResult = await response.json();

        if (response.ok && paymentResult.success) {
          onPaymentSuccess(paymentResult);
        } else {
          // Handle error response gracefully
          let errorMessage = 'Payment failed. Please try again.';
          
          if (paymentResult.errors && Array.isArray(paymentResult.errors) && paymentResult.errors.length > 0) {
            // Show the first error message (they're already user-friendly from backend)
            errorMessage = paymentResult.errors[0];
          } else if (paymentResult.detail) {
            errorMessage = paymentResult.detail;
          }
          
          onPaymentError(errorMessage);
        }
      } else {
        const errors = result.errors?.map((e: any) => e.message).join(', ') || 'Card tokenization failed';
        onPaymentError(errors);
      }
    } catch (error: any) {
      console.error('Payment error:', error);
      onPaymentError(error.message || 'Payment processing failed');
    } finally {
      setIsLoading(false);
      setIsProcessing(false);
    }
  };

  return (
    <div style={{ maxWidth: '500px', margin: '0 auto' }}>
      <div style={{ marginBottom: '24px' }}>
        <h4 style={{ marginBottom: '10px' }}>Card Payment</h4>
        <p style={{ fontSize: '14px', color: '#666' }}>
          Amount: <strong>£{amount.toFixed(2)}</strong>
        </p>
      </div>

      {/* Cardholder Name */}
      <div style={{ marginBottom: '16px' }}>
        <label style={{ display: 'block', marginBottom: '6px', fontSize: '14px', fontWeight: '500' }}>
          Cardholder Name *
        </label>
        <input
          type="text"
          value={cardholderName}
          onChange={(e) => setCardholderName(e.target.value)}
          placeholder="Name as it appears on card"
          style={{
            width: '100%',
            padding: '10px 12px',
            fontSize: '14px',
            border: '1px solid #E0E0E0',
            borderRadius: '4px',
            boxSizing: 'border-box'
          }}
          disabled={isLoading || !card}
        />
      </div>

      {/* Address Line 1 */}
      <div style={{ marginBottom: '16px' }}>
        <label style={{ display: 'block', marginBottom: '6px', fontSize: '14px', fontWeight: '500' }}>
          Address Line 1 *
        </label>
        <input
          type="text"
          value={addressLine1}
          onChange={(e) => setAddressLine1(e.target.value)}
          placeholder="Street address"
          style={{
            width: '100%',
            padding: '10px 12px',
            fontSize: '14px',
            border: '1px solid #E0E0E0',
            borderRadius: '4px',
            boxSizing: 'border-box'
          }}
          disabled={isLoading || !card}
        />
      </div>

      {/* Address Line 2 */}
      <div style={{ marginBottom: '16px' }}>
        <label style={{ display: 'block', marginBottom: '6px', fontSize: '14px', fontWeight: '500' }}>
          Address Line 2
        </label>
        <input
          type="text"
          value={addressLine2}
          onChange={(e) => setAddressLine2(e.target.value)}
          placeholder="Apartment, suite, etc. (optional)"
          style={{
            width: '100%',
            padding: '10px 12px',
            fontSize: '14px',
            border: '1px solid #E0E0E0',
            borderRadius: '4px',
            boxSizing: 'border-box'
          }}
          disabled={isLoading || !card}
        />
      </div>

      {/* City and Postal Code */}
      <div style={{ display: 'flex', gap: '12px', marginBottom: '16px' }}>
        <div style={{ flex: '1' }}>
          <label style={{ display: 'block', marginBottom: '6px', fontSize: '14px', fontWeight: '500' }}>
            Town/City *
          </label>
          <input
            type="text"
            value={city}
            onChange={(e) => setCity(e.target.value)}
            placeholder="City"
            style={{
              width: '100%',
              padding: '10px 12px',
              fontSize: '14px',
              border: '1px solid #E0E0E0',
              borderRadius: '4px',
              boxSizing: 'border-box'
            }}
            disabled={isLoading || !card}
          />
        </div>
        <div style={{ flex: '1' }}>
          <label style={{ display: 'block', marginBottom: '6px', fontSize: '14px', fontWeight: '500' }}>
            Postcode *
          </label>
          <input
            type="text"
            value={postalCode}
            onChange={(e) => setPostalCode(e.target.value.toUpperCase())}
            placeholder="SW1A 1AA"
            style={{
              width: '100%',
              padding: '10px 12px',
              fontSize: '14px',
              border: '1px solid #E0E0E0',
              borderRadius: '4px',
              boxSizing: 'border-box'
            }}
            disabled={isLoading || !card}
          />
        </div>
      </div>

      {/* Card Details */}
      <div style={{ marginBottom: '16px' }}>
        <label style={{ display: 'block', marginBottom: '6px', fontSize: '14px', fontWeight: '500' }}>
          Card Details *
        </label>
        <div 
          id="card-container" 
          style={{
            minHeight: '120px'
          }}
        />
      </div>

      <button
        className="btn btn-primary"
        onClick={handlePayment}
        disabled={isLoading || !card || isProcessing}
        style={{ width: '100%', padding: '12px' }}
      >
        {isProcessing ? 'Processing...' : `Pay £${amount.toFixed(2)}`}
      </button>

      <div style={{ marginTop: '16px', fontSize: '12px', color: '#666', textAlign: 'center' }}>
        <p>Secure payment powered by Square</p>
        {squareConfig?.environment === 'sandbox' && (
          <p style={{ color: '#ff9800', marginTop: '8px' }}>
            <strong>Test Mode:</strong> Use card 4111 1111 1111 1111 with any future expiry
          </p>
        )}
      </div>
    </div>
  );
};

// Extend Window interface for TypeScript
declare global {
  interface Window {
    Square: any;
  }
}

export default SquarePayment;
