import { useState } from 'react'
import { formatINR } from '@sims/domain'
import {
  Badge, Button, ConfirmDialog, DataTable, EmptyState, ErrorState, Notice, PageHeader,
  Skeleton, StatCard, Stats, Toolbar, useToast,
} from '@sims/ui'
import { commitApexImport, getImportStatus, stageApexCsv } from '../api'
import { useData } from './Clients'

/**
 * APEX cutover importer (D18 WS-B; owner-only). Stage the two CSV exports →
 * every row carries its own problem list → verify the totals → Commit, which the
 * server refuses while ANY problem remains. Re-stage as many times as needed;
 * after the final commit APEX goes read-only (no double entry, spec §4).
 */
export function ImportApex() {
  const toast = useToast()
  const status = useData(getImportStatus, [])
  const [clientsCsv, setClientsCsv] = useState<string | undefined>()
  const [invoicesCsv, setInvoicesCsv] = useState<string | undefined>()
  const [busy, setBusy] = useState(false)
  const [confirming, setConfirming] = useState(false)
  const [done, setDone] = useState<string | undefined>()

  const readFile = (set: (t: string) => void) => (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (file === undefined) return
    const reader = new FileReader()
    reader.onload = () => set(String(reader.result ?? ''))
    reader.onerror = () => toast.err(`Could not read ${file.name}`)
    reader.readAsText(file)
  }

  const stage = () => {
    if (busy) return
    if (clientsCsv === undefined && invoicesCsv === undefined) { toast.err('Pick at least one CSV first'); return }
    setBusy(true); setDone(undefined)
    stageApexCsv({
      ...(clientsCsv !== undefined ? { clientsCsv } : {}),
      ...(invoicesCsv !== undefined ? { invoicesCsv } : {}),
    })
      .then(() => { toast.ok('Staged — review the report below'); status.reload() })
      .catch((e: Error) => toast.err(e.message))
      .finally(() => setBusy(false))
  }

  const commit = () => {
    setBusy(true)
    commitApexImport()
      .then((r) => {
        setDone(`Committed: ${r.clients} clients, ${r.invoices} invoices`
          + (r.seeded !== null ? ` · INVOICE series seeded past ${r.seeded.fy} #${r.seeded.lastSeq}` : ''))
        toast.ok('Import committed — APEX is now read-only reference')
        status.reload()
      })
      .catch((e: Error) => toast.err(e.message))
      .finally(() => { setBusy(false); setConfirming(false) })
  }

  const s = status.data
  const problems = (s?.report.clients.problems ?? 0) + (s?.report.invoices.problems ?? 0)
  const staged = (s?.report.clients.staged ?? 0) + (s?.report.invoices.staged ?? 0)

  return (
    <div className="wf-page">
      <PageHeader
        title="APEX import"
        desc="The one-time 300-client cutover: stage the CSVs, clear every problem, verify, commit. Trial-run freely — only Commit writes real data."
      />

      <section>
        <h2>1 · Stage the CSV exports</h2>
        <Toolbar>
          <label className="wf" style={{ display: 'inline-flex', gap: 8, alignItems: 'center' }}>
            clients.csv
            <input type="file" accept=".csv,text/csv" onChange={readFile(setClientsCsv)} />
            {clientsCsv !== undefined && <Badge tone="ok">loaded</Badge>}
          </label>
          <label className="wf" style={{ display: 'inline-flex', gap: 8, alignItems: 'center' }}>
            invoices.csv
            <input type="file" accept=".csv,text/csv" onChange={readFile(setInvoicesCsv)} />
            {invoicesCsv !== undefined && <Badge tone="ok">loaded</Badge>}
          </label>
          <Button tone="primary" onClick={stage}>{busy ? 'Staging…' : 'Stage'}</Button>
        </Toolbar>
      </section>

      <section>
        <h2>2 · Verification report</h2>
        {status.error !== undefined ? <ErrorState message={status.error} onRetry={status.reload} />
          : s === undefined ? <Skeleton rows={3} />
          : staged === 0 ? <EmptyState>Nothing staged yet.</EmptyState> : (
          <>
            <Stats>
              <StatCard label="Clients staged" value={String(s.report.clients.staged)}
                {...(s.report.clients.problems > 0 ? { hint: `${s.report.clients.problems} with problems`, hintTone: 'err' as const } : { hint: 'clean' })} />
              <StatCard label="Invoices staged" value={String(s.report.invoices.staged)}
                {...(s.report.invoices.problems > 0 ? { hint: `${s.report.invoices.problems} with problems`, hintTone: 'err' as const } : { hint: 'clean' })} />
              <StatCard label="Invoice value" value={formatINR(s.report.invoices.totalPaise)} hint="cross-check vs APEX" />
            </Stats>
            <p style={{ fontSize: 12, opacity: 0.75 }}>
              First clients: {s.report.samples.firstClients.join(' · ') || '—'}<br />
              Last invoices: {s.report.samples.lastInvoices.join(' · ') || '—'}
            </p>
            {s.problemClients.length > 0 && (
              <>
                <h3>Client rows with problems (first 50 of {s.report.clients.problems})</h3>
                <DataTable
                  columns={[{ key: 'row', label: 'Row' }, { key: 'code', label: 'Code', mono: true }, { key: 'name', label: 'Name' }, { key: 'problems', label: 'Problems' }]}
                  rows={s.problemClients.map((p) => ({
                    row: String(p.row_no), code: p.code ?? '—', name: p.name ?? '—',
                    problems: (JSON.parse(p.problems) as string[]).join('; '),
                  }))}
                />
              </>
            )}
            {s.problemInvoices.length > 0 && (
              <>
                <h3>Invoice rows with problems (first 50 of {s.report.invoices.problems})</h3>
                <DataTable
                  columns={[{ key: 'row', label: 'Row' }, { key: 'client', label: 'Client code', mono: true }, { key: 'docNo', label: 'Doc no', mono: true }, { key: 'problems', label: 'Problems' }]}
                  rows={s.problemInvoices.map((p) => ({
                    row: String(p.row_no), client: p.client_code ?? '—', docNo: p.doc_no ?? '—',
                    problems: (JSON.parse(p.problems) as string[]).join('; '),
                  }))}
                />
              </>
            )}
          </>
        )}
      </section>

      <section>
        <h2>3 · Commit</h2>
        {problems > 0 && <Notice tone="err">{problems} staged row(s) still carry problems — fix the CSVs and re-stage. Commit stays locked.</Notice>}
        {done !== undefined && <Notice tone="ok">{done}</Notice>}
        <Button
          tone="primary"
          onClick={() => { if (staged > 0 && problems === 0 && !busy) setConfirming(true) }}
        >
          {busy ? 'Working…' : `Commit import${staged > 0 ? ` (${staged} rows)` : ''}`}
        </Button>
        {confirming && (
          <ConfirmDialog
            open
            onClose={() => setConfirming(false)}
            onConfirm={commit}
            title="Commit the APEX import"
            body="This writes the staged clients and invoices for real and seeds the INVOICE series past the legacy numbers. After the final cutover, APEX goes read-only — no double entry. Commit?"
            confirmLabel="Commit import"
            tone="danger"
          />
        )}
      </section>
    </div>
  )
}
