import { useEffect, useState, useCallback } from 'react'
import type { AlbyInvoice } from '@/types/alby'
import { getAlbyService, isWebLNAvailable } from '@/lib/alby'
import { copyInvoiceToClipboard, openWalletForInvoice } from '@/lib/paymentModalHelpers'
import { AlbyInstaller } from './AlbyInstaller'
import { Modal } from './ui'
import { useToast } from './ui/ToastContainer'
import { t } from '@/lib/i18n'
import {
  PaymentHeader,
  InvoiceDisplay,
  PaymentInstructions,
  PaymentActions,
  ExpiredNotice,
  PaymentError,
} from './paymentModal/PaymentModalComponents'

interface PaymentModalProps {
  invoice: AlbyInvoice
  onClose: () => void
  onPaymentComplete: () => void
}

function useInvoiceTimer(expiresAt?: number): number | null {
  const [timeRemaining, setTimeRemaining] = useState<number | null>(null)

  useEffect(() => {
    if (!expiresAt) {
      return
    }
    const updateTimeRemaining = (): void => {
      const now = Math.floor(Date.now() / 1000)
      const remaining = expiresAt - now
      setTimeRemaining(remaining > 0 ? remaining : 0)
    }
    updateTimeRemaining()
    const interval = setInterval(updateTimeRemaining, 1000)
    return () => clearInterval(interval)
  }, [expiresAt])

  return timeRemaining
}


type PaymentModalState = {
  copied: boolean
  errorMessage: string | null
  paymentUrl: string
  timeRemaining: number | null
  handleCopy: () => Promise<void>
  handleOpenWallet: () => Promise<void>
}

function usePaymentModalState(invoice: AlbyInvoice, onPaymentComplete: () => void, showToast: ((message: string, variant?: 'success' | 'info' | 'warning' | 'error', duration?: number) => void) | undefined): PaymentModalState {
  const [copied, setCopied] = useState(false)
  const [errorMessage, setErrorMessage] = useState<string | null>(null)
  const paymentUrl = `lightning:${invoice.invoice}`
  const timeRemaining = useInvoiceTimer(invoice.expiresAt)

  const handleCopy = useCallback(
    (): Promise<void> => copyInvoiceToClipboard({ invoice: invoice.invoice, setCopied, setErrorMessage, showToast: showToast ?? undefined }),
    [invoice.invoice, showToast]
  )

  const handleOpenWallet = useCallback(
    (): Promise<void> => openWalletForInvoice({ invoice: invoice.invoice, onPaymentComplete, setErrorMessage, showToast: showToast ?? undefined }),
    [invoice.invoice, onPaymentComplete, showToast]
  )

  return { copied, errorMessage, paymentUrl, timeRemaining, handleCopy, handleOpenWallet }
}


function useAlbyDetection(): boolean {
  const [hasAlby, setHasAlby] = useState(false)

  useEffect(() => {
    const checkAlby = (): void => {
      const alby = getAlbyService()
      setHasAlby(isWebLNAvailable() && alby.isEnabled())
    }
    checkAlby()
    const interval = setInterval(checkAlby, 1000)
    return () => clearInterval(interval)
  }, [])

  return hasAlby
}


function PaymentModalContent({
  invoice,
  copied,
  errorMessage,
  paymentUrl,
  timeRemaining,
  handleCopy,
  handleOpenWallet,
  hasAlby,
}: {
  invoice: AlbyInvoice
  copied: boolean
  errorMessage: string | null
  paymentUrl: string
  timeRemaining: number | null
  handleCopy: () => Promise<void>
  handleOpenWallet: () => void
  hasAlby: boolean
}): React.ReactElement {
  return (
    <>
      {!hasAlby && <AlbyInstaller />}
      <PaymentHeader amount={invoice.amount} timeRemaining={timeRemaining} />
      <PaymentInstructions hasAlby={hasAlby} />
      <InvoiceDisplay invoiceText={invoice.invoice} paymentUrl={paymentUrl} />
      <PaymentActions
        copied={copied}
        onCopy={handleCopy}
        onOpenWallet={handleOpenWallet}
        hasAlby={hasAlby}
      />
      <ExpiredNotice show={timeRemaining !== null && timeRemaining <= 0} />
      <PaymentError errorMessage={errorMessage} onRetry={handleOpenWallet} />
      <p className="text-xs text-cyber-accent/70 mt-4 text-center">
        {t('payment.modal.autoVerify')}
      </p>
    </>
  )
}

export function PaymentModal({ invoice, onClose, onPaymentComplete }: PaymentModalProps): React.ReactElement {
  const { showToast } = useToast()
  const { copied, errorMessage, paymentUrl, timeRemaining, handleCopy, handleOpenWallet } =
    usePaymentModalState(invoice, onPaymentComplete, showToast)
  const hasAlby = useAlbyDetection()

  const handleOpenWalletSync = (): void => {
    void handleOpenWallet()
  }

  return (
    <Modal
      isOpen
      onClose={onClose}
      title={t('payment.modal.zapAmount', { amount: invoice.amount })}
      size="medium"
      aria-label={t('payment.modal.zapAmount', { amount: invoice.amount })}
    >
      <PaymentModalContent
        invoice={invoice}
        copied={copied}
        errorMessage={errorMessage}
        paymentUrl={paymentUrl}
        timeRemaining={timeRemaining}
        handleCopy={handleCopy}
        handleOpenWallet={handleOpenWalletSync}
        hasAlby={hasAlby}
      />
    </Modal>
  )
}
