import React from 'react'
import { Button } from '../../../components/ui/button'
import { getPaymentMode } from '../lib/paymentMode'
import { Alert } from '../../../components/alert/Alert'
import { LoadingOverlay } from '../../../components/LoadingOverlay'
import { mapErrorToUserMessage } from '../../../lib/errorMessages'
import { Logger } from '../../../lib/logger'
import { SnapTokenService } from './SnapTokenService'

interface SnapPaymentTriggerProps {
  orderId: string
  amount: number
  customer?: { name?: string; phone?: string; email?: string }
  paymentMethod?: string
  onSuccess?: (result: any) => void
  onError?: (error: any) => void
  onChargeInitiated?: () => void
}

export function SnapPaymentTrigger({
  orderId,
  amount,
  customer,
  paymentMethod,
  onSuccess,
  onError,
  onChargeInitiated
}: SnapPaymentTriggerProps) {
  const mode = getPaymentMode()

  // If Core mode, render the appropriate Core component
  if (mode === 'CORE') {
    return (
      <CorePaymentComponent
        paymentMethod={paymentMethod || 'bank_transfer'}
        orderId={orderId}
        amount={amount}
        onChargeInitiated={onChargeInitiated}
      />
    )
  }

  // Snap mode - use hosted payment interface
  return (
    <SnapHostedPayment
      orderId={orderId}
      amount={amount}
      customer={customer}
      onSuccess={onSuccess}
      onError={onError}
    />
  )
}

function CorePaymentComponent({ paymentMethod, orderId, amount, onChargeInitiated }: {
  paymentMethod: string
  orderId: string
  amount: number
  onChargeInitiated?: () => void
}) {
  const [Component, setComponent] = React.useState<React.ComponentType<any> | null>(null)
  const [loading, setLoading] = React.useState(true)

  React.useEffect(() => {
    const loadComponent = async () => {
      try {
        let componentModule: any

        switch (paymentMethod) {
          case 'bank_transfer':
            componentModule = await import('../core/BankTransferPanel')
            setComponent(() => componentModule.BankTransferPanel)
            break
          case 'credit_card':
            componentModule = await import('../core/CardPanel')
            setComponent(() => componentModule.CardPanel)
            break
          case 'gopay':
            componentModule = await import('../core/GoPayPanel')
            setComponent(() => componentModule.GoPayPanel)
            break
          case 'cstore':
            componentModule = await import('../core/CStorePanel')
            setComponent(() => componentModule.CStorePanel)
            break
          default:
            componentModule = await import('../core/BankTransferPanel')
            setComponent(() => componentModule.BankTransferPanel)
        }
      } catch (error) {
        console.error('Failed to load payment component:', error)
      } finally {
        setLoading(false)
      }
    }

    loadComponent()
  }, [paymentMethod])

  if (loading) {
    return <div>Loading payment component...</div>
  }

  if (!Component) {
    return <div>Payment method not available</div>
  }

  return <Component orderId={orderId} amount={amount} onChargeInitiated={onChargeInitiated} />
}

function SnapHostedPayment({ orderId, amount, customer, onSuccess, onError }: Omit<SnapPaymentTriggerProps, 'paymentMethod' | 'onChargeInitiated'>) {
  const [loading, setLoading] = React.useState(false)
  const [error, setError] = React.useState('')

  const handleSnapPayment = async () => {
    try {
      setLoading(true)
      setError('')

      Logger.paymentInfo('snap.payment.init', { orderId, amount, customer })

      // Create Snap transaction token using service
      const token = await SnapTokenService.createToken({
        transaction_details: {
          order_id: orderId,
          gross_amount: amount
        },
        customer_details: customer ? {
          first_name: customer.name,
          email: customer.email,
          phone: customer.phone
        } : undefined,
        item_details: [{
          id: orderId,
          name: 'Payment',
          price: amount,
          quantity: 1
        }]
      })

      Logger.paymentInfo('snap.token.received', { orderId, token: token.substring(0, 10) + '...' })

      // Trigger Snap payment popup
      if (window.snap && typeof window.snap.pay === 'function') {
        window.snap.pay(token, {
          onSuccess: (result: any) => {
            Logger.paymentInfo('snap.payment.success', { orderId, transactionId: result.transaction_id })
            onSuccess?.(result)
          },
          onPending: (result: any) => {
            Logger.paymentInfo('snap.payment.pending', { orderId, transactionId: result.transaction_id })
            // Handle pending state
          },
          onError: (result: any) => {
            Logger.paymentError('snap.payment.error', { orderId, error: result })
            const message = mapErrorToUserMessage(result)
            setError(message)
            onError?.(result)
          },
          onClose: () => {
            Logger.paymentInfo('snap.popup.closed', { orderId })
            // User closed the popup without completing payment
          }
        })
      } else {
        throw new Error('Snap.js not loaded')
      }

    } catch (e: any) {
      Logger.paymentError('snap.payment.error', { orderId, error: e.message })
      const message = mapErrorToUserMessage(e)
      setError(message)
      onError?.(e)
    } finally {
      setLoading(false)
    }
  }

  return (
    <div className="space-y-4">
      {error && (
        <Alert title="Pembayaran Gagal">
          {error}
        </Alert>
      )}

      <div className="text-center">
        <p className="text-sm text-gray-600 mb-4">
          Klik tombol di bawah untuk melanjutkan pembayaran dengan Midtrans Snap
        </p>

        <Button
          onClick={handleSnapPayment}
          disabled={loading}
          className="w-full max-w-xs"
        >
          {loading ? 'Memproses...' : 'Bayar Sekarang'}
        </Button>
      </div>

      {loading && <LoadingOverlay isLoading={loading} />}
    </div>
  )
}