'use client';

import { useCallback, useMemo, useState, useEffect } from 'react';
import assert from 'assert';

import { Connection, LAMPORTS_PER_SOL } from '@solana/web3.js';
import { useWallet } from '@solana/wallet-adapter-react';

import { sendSolanaPayment, getRecipientAddress } from '@/services/solana';
import { getRequiredTokenInfo } from '@/services/jupiter-price';
import { PaymentModalProps, PaymentRequest } from '@/types';
import { PAYMENT_METHOD_LABELS, SOL_PAYMENT_AMOUNT_LAMPORTS } from '@/constants/payments';
import { usePaymentMethod } from '@/contexts/PaymentMethodContext';

assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL;
const SOLANA_SOL_RPC_URL = process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL;

export default function PaymentModal({
  isOpen,
  onClose,
  url,
  onPaymentComplete,
}: PaymentModalProps) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const { selectedPaymentMethod } = usePaymentMethod();
  const paymentMethod = selectedPaymentMethod;
  const [tokenAmount, setTokenAmount] = useState<number>(0);
  const [tokenDecimals, setTokenDecimals] = useState<number>(6); // Default fallback
  const [loadingPrice, setLoadingPrice] = useState(false);

  const { wallet, publicKey } = useWallet();

  const directConnection = useMemo(() => new Connection(SOLANA_RPC_URL), []);
  const solConnection = useMemo(() =>
    SOLANA_SOL_RPC_URL ? new Connection(SOLANA_SOL_RPC_URL) : directConnection,
    [directConnection]
  );

  // Get configuration from environment variables
  const targetUsdAmount = parseFloat(process.env.NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT_USD!);
  const mintAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS!;
  const tokenSymbol = process.env.NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL || 'TOKEN';

  // Fetch token amount based on USD price when SPL token method is selected
  useEffect(() => {
    if (!isOpen || paymentMethod !== 'spl-token') {
      setLoadingPrice(false);
      return;
    }

    const fetchTokenAmount = async () => {
      setLoadingPrice(true);
      setError('');

      try {
        const {requiredAmountInBaseUnits, decimals} = await getRequiredTokenInfo(targetUsdAmount, mintAddress);
        setTokenAmount(requiredAmountInBaseUnits);
        setTokenDecimals(decimals);
      } catch (error) {
        console.error('Error fetching token price:', error);
        setError('Unable to fetch current token price. Please try again.');
      } finally {
        setLoadingPrice(false);
      }
    };

    fetchTokenAmount();
  }, [isOpen, paymentMethod, targetUsdAmount, mintAddress]);

  // Initialize payment method when modal opens
  useEffect(() => {
    if (isOpen) {
      setError('');
      setLoadingPrice(false);

      // Set tokenAmount for native GOR payments to maintain consistency
      if (paymentMethod === 'nat-gor') {
        setTokenAmount(SOL_PAYMENT_AMOUNT_LAMPORTS);
      } else {
        setTokenAmount(0);
      }
    }
  }, [isOpen, paymentMethod]);


  const handlePayment = useCallback(async () => {
    if (!paymentMethod) {
      return;
    }

    if (tokenAmount === 0 || (paymentMethod === 'spl-token' && loadingPrice)) {
      setError('Payment amount not ready. Please wait.');
      return;
    }

    if (!wallet?.adapter) {
      setError('Wallet not connected.');
      return;
    }

    setLoading(true);
    setError('');

    try {
      const paymentRequest: PaymentRequest = {
        paymentMethod: paymentMethod,
        amount: tokenAmount,
        recipientAddress: getRecipientAddress(paymentMethod)
      };

      // Use different RPC connection based on payment method
      const connectionToUse = paymentMethod === 'nat-gor' ? solConnection : directConnection;

      const result = await sendSolanaPayment(
        wallet.adapter,
        connectionToUse,
        publicKey!.toBase58(),
        paymentRequest
      );

      if (result.success && result.transactionSignature) {
        onPaymentComplete(result.transactionSignature, paymentMethod);
      } else {
        setError(result.error || 'Payment failed. Please try again.');
      }
    } catch (error) {
      setError(error instanceof Error ? error.message : 'Payment failed. Please try again.');
    } finally {
      setLoading(false);
    }
  }, [paymentMethod, tokenAmount, loadingPrice, wallet, directConnection, solConnection, publicKey, onPaymentComplete]);

  const getPaymentAmountDisplay = () => {
    switch (paymentMethod) {
      case 'nat-gor':
        return `${SOL_PAYMENT_AMOUNT_LAMPORTS / LAMPORTS_PER_SOL} GOR`;
      case 'spl-token':
        if (loadingPrice) return 'Loading...';
        return tokenAmount > 0 ? `${(tokenAmount / Math.pow(10, tokenDecimals)).toFixed(6)} ${tokenSymbol}` : '0';
      default:
        return '';
    }
  };

  if (!isOpen || !paymentMethod) return null;

  return (
    <div className="fixed inset-0 flex items-center justify-center p-4 z-50" style={{ background: 'rgba(15, 23, 42, 0.75)' }}>
      <div className="max-w-md w-full rounded-xl shadow-xl animate-appear"
          style={{ background: 'var(--card-bg)', border: '1px solid var(--card-border)' }}>
        <div className="p-6 border-b" style={{ borderColor: 'var(--card-border)' }}>
          <h2 className="text-xl font-semibold" style={{ color: 'var(--foreground)' }}>
            Complete Payment
          </h2>
        </div>

        <div className="p-6 space-y-6">
          <div>
            <p className="text-sm mb-2 font-medium" style={{ color: 'var(--muted)' }}>URL to be deployed:</p>
            <div className="p-3 rounded-md break-all" style={{ background: 'var(--muted-light)', color: 'var(--foreground)' }}>
              <code className="text-sm font-mono">{url}</code>
            </div>
          </div>

          {/* Payment Method Display */}
          <div>
            <label className="block text-sm font-medium mb-3" style={{ color: 'var(--foreground)' }}>
              Payment Method
            </label>
            <div className="p-3 rounded-md" style={{ background: 'var(--muted-light)', color: 'var(--foreground)' }}>
              <p className="text-sm font-semibold">
                {PAYMENT_METHOD_LABELS[paymentMethod]}
              </p>
            </div>
          </div>

          {/* Payment Details */}
          <div>
            <p className="text-sm mb-2 font-medium" style={{ color: 'var(--muted)' }}>Recipient Address:</p>
            <div className="p-3 rounded-md overflow-hidden" style={{ background: 'var(--muted-light)', color: 'var(--foreground)' }}>
              <code className="text-sm font-mono break-all block">{getRecipientAddress(paymentMethod)}</code>
            </div>
          </div>

          <div>
            <label className="block text-sm font-medium mb-2" style={{ color: 'var(--foreground)' }}>
              Payment Amount
            </label>
            <div className="space-y-3">
              <div className="relative">
                <input
                  type="text"
                  value={targetUsdAmount}
                  disabled={true}
                  className="w-full p-3 pr-12 rounded-md"
                  style={{
                    background: 'var(--card-bg)',
                    border: '1px solid var(--input-border)',
                    color: 'var(--foreground)',
                    opacity: '0.7'
                  }}
                  readOnly
                />
                <div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                  <span className="text-sm font-medium" style={{ color: 'var(--muted)' }}>USD</span>
                </div>
              </div>

              <div className="relative">
                {(paymentMethod === 'spl-token' && loadingPrice) ? (
                  <div className="w-full p-3 rounded-md flex items-center" style={{
                    background: 'var(--muted-light)',
                    border: '1px solid var(--input-border)',
                    color: 'var(--muted)'
                  }}>
                    <svg className="animate-spin h-4 w-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                      <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                      <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                    </svg>
                    Fetching token amount...
                  </div>
                ) : (
                  <input
                    type="text"
                    value={getPaymentAmountDisplay()}
                    disabled={true}
                    className="w-full p-3 pr-20 rounded-md"
                    style={{
                      background: 'var(--card-bg)',
                      border: '1px solid var(--input-border)',
                      color: 'var(--foreground)',
                      opacity: '0.7'
                    }}
                    readOnly
                  />
                )}
                {!(paymentMethod === 'spl-token' && loadingPrice) && (
                  <div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                    <span className="text-sm font-medium" style={{ color: 'var(--muted)' }}>
                      {paymentMethod === 'nat-gor' ? 'GOR (native)' : tokenSymbol}
                    </span>
                  </div>
                )}
              </div>
            </div>
            {paymentMethod === 'spl-token' && (
              <p className="text-xs mt-1" style={{ color: 'var(--muted)' }}>
                Token information fetched from <a className='text-blue-400 underline' href={`https://jup.ag/tokens/${mintAddress}`} target="_blank" rel="noopener noreferrer">Jupiter</a>
              </p>
            )}
          </div>

          {error && (
            <div className="p-3 rounded-md text-sm" style={{ backgroundColor: 'var(--error-light)', color: 'var(--error)' }}>
              {error}
            </div>
          )}
        </div>

        <div className="p-6 flex justify-end space-x-4 border-t" style={{ borderColor: 'var(--card-border)' }}>
          <button
            onClick={onClose}
            className="px-4 py-2 rounded-md transition-colors"
            style={{
              border: '1px solid var(--input-border)',
              color: 'var(--foreground)',
              opacity: loading ? '0.5' : '1'
            }}
            disabled={loading}
          >
            Cancel
          </button>
          <button
            onClick={handlePayment}
            className="px-5 py-2 rounded-md flex items-center transition-colors"
            style={{
              backgroundColor: (loading || loadingPrice) ? 'var(--muted)' : 'var(--primary)',
              color: 'var(--primary-foreground)',
              opacity: (loading || loadingPrice) ? '0.8' : '1'
            }}
            disabled={loading || loadingPrice}
          >
            {(loading || loadingPrice) && (
              <svg className="animate-spin -ml-1 mr-2 h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
              </svg>
            )}
            {loadingPrice ? 'Loading Price...' :
             loading ? 'Processing...' :
             'Pay with Solana Wallet'}
          </button>
        </div>
      </div>
    </div>
  );
}