import { useEffect, useRef, useState } from 'react'
import { buildPacs008, won } from '../util'

// RTGS 참가기관 단말(DT). 접속 센터(DC1/DC2/DC3)를 골라 그 센터의 Gucci 관문으로
// 로그인·이체·조회한다. 센터 전환 = API prefix(/dcN) 변경. 장애 시 다른 센터로 전환해 계속 이용.

type Account = { code: string; name: string; balance: number }
const CENTERS = [
  { id: 'dc1', name: 'DC1', gucci: 8095 },
  { id: 'dc2', name: 'DC2', gucci: 8195 },
  { id: 'dc3', name: 'DC3', gucci: 8295 },
]
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))
const rand = (n: number) => Math.random().toString(36).slice(2, 2 + n)

function genBmi(sender: string): string {
  const d = new Date()
  const date = `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, '0')}${String(d.getDate()).padStart(2, '0')}`
  const serial = String(Date.now() % 10_000_000_000).padStart(10, '0')
  return date + sender.padStart(4, '0') + serial
}

export default function DtApp() {
  const [dc, setDc] = useState('dc1')
  const base = `/${dc}`
  const center = CENTERS.find((c) => c.id === dc)!

  const [token, setToken] = useState<string | null>(null)
  const [user] = useState('a')
  const [secret, setSecret] = useState('1')
  const [health, setHealth] = useState<any>(null)
  const [accounts, setAccounts] = useState<Account[]>([])
  const [from, setFrom] = useState('1001')
  const [to, setTo] = useState('1002')
  const [amount, setAmount] = useState(50000)
  const [busy, setBusy] = useState(false)
  const [log, setLog] = useState<{ t: string; msg: string; kind?: string }[]>([])
  const [err, setErr] = useState<string | null>(null)
  const bottom = useRef<HTMLDivElement>(null)

  const addLog = (msg: string, kind?: string) =>
    setLog((l) => [...l, { t: new Date().toLocaleTimeString('ko-KR'), msg, kind }])
  useEffect(() => { bottom.current?.scrollIntoView({ behavior: 'smooth' }) }, [log])

  // 센터 전환 시 세션 초기화(센터별 로그인)
  useEffect(() => { setToken(null); setAccounts([]); setErr(null); loadHealth() /* eslint-disable-next-line */ }, [dc])

  const loadHealth = async () => {
    try { setHealth(await (await fetch(`${base}/gucci/health/centers`)).json()) }
    catch { setHealth(null) }
  }

  const login = async () => {
    setErr(null)
    try {
      const r = await fetch(`${base}/gucci/auth/login`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ username: user, secret }),
      })
      if (!r.ok) { setErr('로그인 실패 — 자격증명/센터 상태 확인'); return }
      const j = await r.json()
      setToken(j.token)
      addLog(`[${center.name}] 로그인 성공 (role ${j.role})`, 'ok')
      await loadAccounts(j.token)
    } catch (e: any) { setErr('로그인 오류: ' + e.message) }
  }

  const loadAccounts = async (tok = token) => {
    try {
      const r = await fetch(`${base}/gucci/accounts`, { headers: { Authorization: `Bearer ${tok}` } })
      if (r.ok) setAccounts(await r.json())
    } catch { /* ignore */ }
  }

  const submit = async () => {
    if (!token) { setErr('먼저 로그인하세요'); return }
    if (from === to) { setErr('송신/수신 기관이 같을 수 없습니다'); return }
    setErr(null); setBusy(true)
    const bmi = genBmi(from)
    addLog(`[${center.name}] 이체 신청 ${from}→${to} ${won(amount)} (BMI ${bmi})`)
    try {
      const res = await fetch(`${base}/gucci/pay/customer`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/xml',
          Authorization: `Bearer ${token}`,
          'X-Nonce': `${bmi}-${rand(6)}`,
          'X-Timestamp': String(Math.floor(Date.now() / 1000)), // Gucci ReplayGuard는 초 단위 기대

        },
        body: buildPacs008(bmi, from, to, amount),
      })
      const txt = await res.text()
      if (!res.ok) { addLog(`관문 거부(HTTP ${res.status}): ${txt.slice(0, 120)}`, 'err'); setBusy(false); return }
      const recv = new DOMParser().parseFromString(txt, 'application/xml').querySelector('TxSts')?.textContent ?? '?'
      addLog(`접수 응답: ${recv}`, recv === 'RCVD' ? 'ok' : 'err')
      if (recv !== 'RCVD') { setBusy(false); return }
      // 완결까지 폴링
      let final = '처리중'
      for (let i = 0; i < 10; i++) {
        await sleep(700)
        const j = await (await fetch(`${base}/gucci/inquiry/${bmi}`, { headers: { Authorization: `Bearer ${token}` } })).json()
        if (j.status === 'ACCC' || j.status === 'RJCT') { final = j.status; break }
      }
      addLog(`최종 상태: ${final}`, final === 'ACCC' ? 'ok' : 'err')
      await loadAccounts()
    } catch (e: any) { addLog('이체 오류: ' + e.message, 'err') }
    finally { setBusy(false) }
  }

  const coreUp = health?.centers?.[0]?.['core(chanel)'] === 'UP'
  const inp: React.CSSProperties = { padding: 8, borderRadius: 6, border: '1px solid #ccc' }
  const bankOpt = (a: Account) => <option key={a.code} value={a.code}>{a.code} {a.name}</option>

  return (
    <div style={{ fontFamily: 'system-ui, sans-serif', maxWidth: 720, margin: '1.5rem auto', padding: '0 1rem' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 8 }}>
        <h1 style={{ margin: 0, fontSize: 22 }}>🏧 RTGS 단말 <span style={{ fontSize: 13, color: '#888' }}>(DT · 참가기관)</span></h1>
        <label style={{ fontSize: 14 }}>접속 센터&nbsp;
          <select value={dc} onChange={(e) => setDc(e.target.value)} style={{ ...inp, fontWeight: 700 }}>
            {CENTERS.map((c) => <option key={c.id} value={c.id}>{c.name} (Gucci :{c.gucci})</option>)}
          </select>
        </label>
      </div>

      <div style={{ marginTop: 12, padding: '10px 14px', borderRadius: 8, background: coreUp ? '#e6f4ea' : '#fde8e8', border: `1px solid ${coreUp ? '#8bd3a0' : '#f0a0a0'}` }}>
        이 단말은 <b>{center.name}</b> 센터를 이용 중 — 관문 {coreUp ? '🟢 정상' : '🔴 접속 불가'} {token ? '· 🔓 로그인됨' : '· 🔒 미로그인'}
        {!coreUp && <span style={{ color: '#c00' }}> (다른 센터로 전환해 계속 이용 가능)</span>}
      </div>

      {/* 로그인 */}
      {!token && (
        <section style={{ marginTop: 16, padding: 16, border: '1px solid #e2e2e2', borderRadius: 8 }}>
          <h3 style={{ marginTop: 0 }}>🔑 로그인</h3>
          <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
            <input value={user} readOnly style={{ ...inp, width: 90, background: '#f5f5f5' }} />
            <input value={secret} onChange={(e) => setSecret(e.target.value)} type="password" placeholder="비밀번호" style={{ ...inp, width: 120 }} />
            <button onClick={login} style={{ ...inp, background: '#0b63c4', color: '#fff', border: 0, cursor: 'pointer', fontWeight: 600 }}>로그인</button>
            <span style={{ color: '#999', fontSize: 12 }}>테스트 계정 a / 1</span>
          </div>
        </section>
      )}

      {/* 이체 */}
      {token && (
        <section style={{ marginTop: 16, padding: 16, border: '1px solid #e2e2e2', borderRadius: 8, background: '#f7fbff' }}>
          <h3 style={{ marginTop: 0 }}>💸 자금이체 신청 <span style={{ fontSize: 12, color: '#888' }}>({center.name} 관문 경유)</span></h3>
          <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'flex-end' }}>
            <label>송신기관<br /><select value={from} onChange={(e) => setFrom(e.target.value)} style={{ ...inp, minWidth: 160 }}>{accounts.map(bankOpt)}</select></label>
            <label>수신기관<br /><select value={to} onChange={(e) => setTo(e.target.value)} style={{ ...inp, minWidth: 160 }}>{accounts.map(bankOpt)}</select></label>
            <label>금액(원)<br /><input type="number" min={1} value={amount} onChange={(e) => setAmount(Number(e.target.value))} style={{ ...inp, width: 130 }} /></label>
            <button onClick={submit} disabled={busy} style={{ ...inp, background: busy ? '#9ac' : '#0b63c4', color: '#fff', border: 0, cursor: 'pointer', fontWeight: 600 }}>{busy ? '처리중…' : '이체 신청'}</button>
          </div>
        </section>
      )}

      {err && <p style={{ color: '#c00' }}>{err}</p>}

      {/* 처리 로그 */}
      <section style={{ marginTop: 16 }}>
        <h3 style={{ marginBottom: 6 }}>📜 단말 처리 로그</h3>
        <div style={{ background: '#0d1117', color: '#c9d1d9', borderRadius: 8, padding: 12, height: 260, overflow: 'auto', fontSize: 13, fontFamily: 'monospace' }}>
          {log.length === 0 && <div style={{ color: '#666' }}>(이체를 신청하면 처리 과정이 여기에 표시됩니다)</div>}
          {log.map((l, i) => (
            <div key={i} style={{ color: l.kind === 'ok' ? '#3fb950' : l.kind === 'err' ? '#f85149' : '#c9d1d9' }}>
              <span style={{ color: '#6e7681' }}>{l.t}</span> {l.msg}
            </div>
          ))}
          <div ref={bottom} />
        </div>
      </section>
    </div>
  )
}
