import { Button } from '../../../components/ui/button'
import { usePaymentNavigation } from '../lib/navigation'
import React from 'react'
import { PaymentInstructions } from './PaymentInstructions'
import { TrustStrip } from './TrustStrip'
import { postCharge } from '../../../services/api'
import { InlinePaymentStatus } from './InlinePaymentStatus'

type StoreKey = 'alfamart' | 'indomaret'

// Shared guards/tasks to prevent duplicate charges under StrictMode/HMR and double clicks
const attemptedCStoreKeys = new Set<string>()
const cstoreTasks = new Map<string, Promise<any>>()

export function CStorePanel({ orderId, amount, locked, onChargeInitiated, defaultStore }: { orderId: string; amount: number; locked?: boolean; onChargeInitiated?: () => void; defaultStore?: StoreKey }) {
  const nav = usePaymentNavigation()
  const [selected] = React.useState<StoreKey | null>(defaultStore ?? null)
  const [showGuide, setShowGuide] = React.useState(false)
  const [busy, setBusy] = React.useState(false)
  const [paymentCode, setPaymentCode] = React.useState('')
  const [storeFromRes, setStoreFromRes] = React.useState('')

  React.useEffect(() => {
    let cancelled = false
    async function run() {
      // Only auto-charge when a store is selected, not locked, and code not yet generated
      if (!selected || locked || paymentCode) return
      const chargeKey = `${orderId}:${selected}`
      // If there's already an in-flight task, await it
      if (attemptedCStoreKeys.has(chargeKey) && cstoreTasks.has(chargeKey)) {
        setBusy(true)
        try {
          const res = await cstoreTasks.get(chargeKey)!
          if (!cancelled) {
            if (typeof res?.payment_code === 'string') setPaymentCode(res.payment_code)
            if (typeof res?.store === 'string') setStoreFromRes(res.store)
          }
        } catch (e) {
          if (!cancelled) alert(`Gagal membuat kode pembayaran: ${(e as Error).message}`)
        } finally {
          if (!cancelled) setBusy(false)
          cstoreTasks.delete(chargeKey)
        }
        return
      }
      setBusy(true)
      onChargeInitiated?.()
      try {
        const payload: Record<string, any> = {
          payment_type: 'cstore',
          transaction_details: { order_id: orderId, gross_amount: amount },
          cstore: { store: selected, message: `Pembayaran untuk order ${orderId}` },
        }
        attemptedCStoreKeys.add(chargeKey)
        const task = postCharge(payload)
        cstoreTasks.set(chargeKey, task)
        const res = await task
        if (!cancelled) {
          if (typeof res?.payment_code === 'string') setPaymentCode(res.payment_code)
          if (typeof res?.store === 'string') setStoreFromRes(res.store)
        }
      } catch (e) {
        if (!cancelled) alert(`Gagal membuat kode pembayaran: ${(e as Error).message}`)
        attemptedCStoreKeys.delete(chargeKey)
      } finally {
        if (!cancelled) setBusy(false)
        cstoreTasks.delete(chargeKey)
      }
    }
    run()
    return () => { cancelled = true }
  }, [selected, orderId, amount])

  function copy(text: string, label: string) {
    if (!text) return
    navigator.clipboard?.writeText(text)
    alert(`${label} disalin: ${text}`)
  }

  return (
    <div className="space-y-3">
      <div className="font-medium">Convenience Store</div>
      {selected && (
        <div className="text-xs text-black/60 dark:text-white/60">Toko dipilih: <span className="font-medium text-black dark:text-white">{selected.toUpperCase()}</span></div>
      )}
      <button
        type="button"
        onClick={() => setShowGuide((v) => !v)}
        className="text-xs text-brand-600 hover:underline"
        aria-expanded={showGuide}
      >
        Cara bayar
      </button>
      {showGuide && <PaymentInstructions method="cstore" />}
      {locked && (
        <div className="text-xs text-black/60 dark:text-white/60">Metode terkunci. Gunakan kode pembayaran di kasir {selected?.toUpperCase()}.</div>
      )}
      <div className="pt-2 space-y-2">
        <div className="rounded border border-black/10 dark:border-white/10 p-2 text-sm" aria-live="polite">
          <div className="font-medium">Kode Pembayaran</div>
          {!selected && (
            <div className="text-xs text-black/60 dark:text-white/60">Pilih toko terlebih dahulu di langkah sebelumnya.</div>
          )}
          {selected && busy && (
            <div className="inline-flex items-center gap-2 text-xs text-black/60 dark:text-white/60">
              <span className="h-4 w-4 animate-spin rounded-full border-2 border-black/40 dark:border-white/40 border-t-transparent" aria-hidden />
              Membuat kode…
            </div>
          )}
          {selected && !busy && (storeFromRes || paymentCode) && (
            <>
              {storeFromRes ? <div>Toko: {storeFromRes.toUpperCase()}</div> : null}
              {paymentCode ? <div>Kode: <span className="font-mono text-lg tracking-[0.06em] select-all">{paymentCode}</span></div> : null}
            </>
          )}
          <div className="mt-2"><Button variant="outline" className="w-full sm:w-auto" onClick={() => copy(paymentCode, 'Kode pembayaran')} disabled={!paymentCode || busy}>Copy Kode</Button></div>
        </div>
        <Button
          variant="outline"
          className="w-full"
          disabled={busy || (!locked && !paymentCode)}
          onClick={() => nav.toStatus(orderId, 'cstore')}
        >
          Buka halaman status
        </Button>
        <InlinePaymentStatus orderId={orderId} method="cstore" />
      </div>
      <TrustStrip />
    </div>
  )
}