import React, { useEffect, useState } from 'react';
import {
  createPaymentOrder,
  recordCodPayment,
  verifyPayment,
} from '../core/checkout-api';
import type { PaymentStepProps } from '../core/types';

declare global {
  interface Window {
    Razorpay?: new (options: Record<string, unknown>) => { open: () => void };
  }
}

const RAZORPAY_SCRIPT = 'https://checkout.razorpay.com/v1/checkout.js';

function loadRazorpayScript(): Promise<void> {
  if (window.Razorpay) return Promise.resolve();
  return new Promise((resolve, reject) => {
    const existing = document.querySelector(`script[src="${RAZORPAY_SCRIPT}"]`);
    if (existing) {
      existing.addEventListener('load', () => resolve());
      return;
    }
    const script = document.createElement('script');
    script.src = RAZORPAY_SCRIPT;
    script.async = true;
    script.onload = () => resolve();
    script.onerror = () => reject(new Error('Failed to load Razorpay'));
    document.body.appendChild(script);
  });
}

const PaymentStep: React.FC<PaymentStepProps> = ({
  checkoutConfig,
  sessionToken,
  sessionId,
  amountPaise,
  enableCod = false,
  codAllowed = false,
  addressRisk,
  theme = 'light',
  onComplete,
  onBack,
  onEvent,
  orderConfirmationUrl,
}) => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const isDark = theme === 'dark';

  useEffect(() => {
    onEvent?.('payment_step_viewed');
  }, [onEvent]);

  const handlePrepaid = async () => {
    setLoading(true);
    setError(null);
    try {
      await loadRazorpayScript();
      const order = await createPaymentOrder(checkoutConfig, sessionToken, amountPaise);

      await new Promise<void>((resolve, reject) => {
        if (!window.Razorpay) {
          reject(new Error('Razorpay unavailable'));
          return;
        }
        const rzp = new window.Razorpay({
          key: order.razorpay_key_id,
          amount: order.amount_paise,
          currency: order.currency,
          order_id: order.razorpay_order_id,
          name: 'Checkout',
          handler: async (response: {
            razorpay_payment_id: string;
            razorpay_order_id: string;
            razorpay_signature: string;
          }) => {
            try {
              const result = await verifyPayment(checkoutConfig, sessionToken, {
                razorpay_order_id: response.razorpay_order_id,
                razorpay_payment_id: response.razorpay_payment_id,
                razorpay_signature: response.razorpay_signature,
                payment_method: 'prepaid',
              });
              onEvent?.('payment_method_selected', result.payment_method);
              onComplete({
                paymentMethod: result.payment_method,
                razorpayOrderId: result.razorpay_order_id,
                razorpayPaymentId: result.razorpay_payment_id,
              });
              if (orderConfirmationUrl) {
                const url = orderConfirmationUrl.replace('{{sessionId}}', sessionId ?? '');
                window.location.href = url;
              }
              resolve();
            } catch (e) {
              reject(e);
            }
          },
          modal: {
            ondismiss: () => reject(new Error('Payment cancelled')),
          },
        });
        rzp.open();
      });
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Payment failed');
    } finally {
      setLoading(false);
    }
  };

  const handleCod = async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await recordCodPayment(checkoutConfig, sessionToken);
      onEvent?.('payment_method_selected', result.payment_method);
      onComplete({ paymentMethod: result.payment_method });
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Failed to select COD');
    } finally {
      setLoading(false);
    }
  };

  const amountDisplay = `₹${(amountPaise / 100).toLocaleString('en-IN')}`;
  const codBlockedByRisk = addressRisk?.interventions.includes('hide_cod') ?? false;
  const riskTone =
    addressRisk?.level === 'high' ? 'high' : addressRisk?.level === 'medium' ? 'medium' : 'low';

  return (
    <div className={`qr-payment-step${isDark ? ' qr-payment-step--dark' : ''}`}>
      {onBack ? (
        <button type="button" className="qr-back-btn qr-back-btn--auth" onClick={onBack} disabled={loading}>
          ← Back
        </button>
      ) : null}
      <h3 className="qr-auth-step__title">Choose payment</h3>
      <p className="qr-auth-step__sub">
        Order total: <strong>{amountDisplay}</strong>
      </p>

      {error ? <p className="qr-auth-step__error" role="alert">{error}</p> : null}

      {addressRisk && addressRisk.level !== 'low' ? (
        <div className={`qr-risk-banner qr-risk-banner--${riskTone}`} role="status">
          <strong>
            {addressRisk.level === 'high' ? 'Address needs extra confirmation' : 'Address confidence check'}
          </strong>
          <span>{addressRisk.reasons[0]}</span>
          {codBlockedByRisk ? (
            <span>Cash on Delivery is disabled for this order. Online payment is still available.</span>
          ) : null}
        </div>
      ) : null}

      <button
        type="button"
        className="qr-payment-option qr-payment-option--primary"
        onClick={handlePrepaid}
        disabled={loading}
      >
        <span className="qr-payment-option__icon" aria-hidden="true">UPI</span>
        <span className="qr-payment-option__copy">
          <span className="qr-payment-option__title">
            {loading ? 'Processing...' : 'Pay online'}
          </span>
          <span className="qr-payment-option__sub">UPI, cards, wallets</span>
        </span>
        <strong className="qr-payment-option__amount">{amountDisplay}</strong>
      </button>

      {enableCod && codAllowed && !codBlockedByRisk ? (
        <button
          type="button"
          className="qr-payment-option qr-payment-option--secondary"
          onClick={handleCod}
          disabled={loading}
        >
          <span className="qr-payment-option__icon" aria-hidden="true">₹</span>
          <span className="qr-payment-option__copy">
            <span className="qr-payment-option__title">Cash on Delivery</span>
            <span className="qr-payment-option__sub">Pay when the order arrives</span>
          </span>
        </button>
      ) : null}

      {sessionId ? (
        <p className="qr-payment-step__meta">Session {sessionId.slice(0, 8)}…</p>
      ) : null}
    </div>
  );
};

export default PaymentStep;
