import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { formatINR } from '@sims/domain'
import {
  Badge, Button, ConfirmDialog, DataTable, EmptyState, ErrorState, FilterChips, PageHeader,
  Skeleton, Toolbar, useToast,
} from '@sims/ui'
import { documentAction, getDocuments, DOC_STATUSES, type DocStatus, type DocType } from '../api'
import { useData, DOC_TONE } from './Clients'

const PAGE_SIZE = 50

const TYPE_LABEL: Record<DocType, string> = {
  QUOTATION: 'Quotation', PROFORMA: 'Proforma', INVOICE: 'Invoice',
  CREDIT_NOTE: 'Credit note', RECEIPT: 'Receipt',
}
const TYPE_CHIPS: { key: string; label: string }[] = [
  { key: 'all', label: 'All' },
  { key: 'QUOTATION', label: 'Quotations' },
  { key: 'PROFORMA', label: 'Proformas' },
  { key: 'INVOICE', label: 'Invoices' },
  { key: 'CREDIT_NOTE', label: 'Credit notes' },
  { key: 'RECEIPT', label: 'Receipts' },
]

/**
 * Documents register (go-live cluster WS-D): every document across all clients,
 * newest first, server-paginated with an honest total (rule 8). Type chips and
 * the status filter compose server-side; a row opens the document view.
 */
export function Documents() {
  const nav = useNavigate()
  const toast = useToast()
  const [type, setType] = useState('all')
  const [status, setStatus] = useState('')
  const [page, setPage] = useState(1)
  // D18 WS-G: one-click proforma → invoice & send, straight from the register.
  const [converting, setConverting] = useState<{ id: string; docNo: string } | undefined>()

  const list = useData(
    () => getDocuments({
      ...(type !== 'all' ? { type: type as DocType } : {}),
      ...(status !== '' ? { status: status as DocStatus } : {}),
      page, pageSize: PAGE_SIZE,
    }),
    [type, status, page],
  )

  const data = list.data
  const docs = data?.documents
  const totalPages = data !== undefined ? Math.max(1, Math.ceil(data.total / data.pageSize)) : 1
  const from = data !== undefined && data.total > 0 ? (data.page - 1) * data.pageSize + 1 : 0
  const to = data !== undefined ? Math.min(data.page * data.pageSize, data.total) : 0
  const why = [
    type !== 'all' ? ` of type ${TYPE_LABEL[type as DocType].toLowerCase()}` : '',
    status !== '' ? ` with status ${status}` : '',
  ].filter((x) => x !== '').join('')

  return (
    <div className="wf-page">
      <PageHeader
        title="Documents"
        desc="Every quotation, proforma, invoice, credit note and receipt — newest first. Click a row to open it."
      />
      <Toolbar>
        <FilterChips
          chips={TYPE_CHIPS}
          active={type}
          onChange={(k) => { setType(k); setPage(1) }}
        />
        <select
          className="wf" style={{ maxWidth: 180 }} value={status} aria-label="Status"
          onChange={(e) => { setStatus(e.target.value); setPage(1) }}
        >
          <option value="">Status: any</option>
          {DOC_STATUSES.map((s) => <option key={s} value={s}>{s}</option>)}
        </select>
        <span style={{ flex: 1 }} />
        {data !== undefined && <Badge>{data.total} total</Badge>}
      </Toolbar>
      {list.error !== undefined && <ErrorState message={list.error} onRetry={list.reload} />}
      {list.error !== undefined ? null
        : docs === undefined ? <Skeleton rows={6} />
        : docs.length === 0 ? <EmptyState>No documents{why !== '' ? why : ' yet'}.</EmptyState> : (
        <>
          <DataTable
            columns={[
              { key: 'no', label: 'No.', mono: true },
              { key: 'type', label: 'Type' },
              { key: 'client', label: 'Client' },
              { key: 'date', label: 'Date' },
              { key: 'status', label: 'Status' },
              { key: 'amount', label: 'Amount', numeric: true },
              { key: 'actions', label: '' },
            ]}
            onRowClick={(_row, i) => nav(`/documents/${docs[i]!.id}`)}
            rows={docs.map((d) => ({
              no: d.docNo ?? '— draft —',
              type: TYPE_LABEL[d.docType],
              client: d.clientName,
              date: d.docDate,
              status: <Badge tone={DOC_TONE[d.status]}>{d.status}</Badge>,
              amount: formatINR(d.payablePaise),
              actions: d.docType === 'PROFORMA' && d.docNo !== null
                && d.status !== 'cancelled' && d.status !== 'invoiced'
                ? (
                  // The whole <tr> navigates on click — without this guard the button
                  // click bubbles up, the page unmounts and the confirm never shows.
                  <span onClick={(e) => e.stopPropagation()}>
                    <Button
                      tone="primary"
                      onClick={() => setConverting({ id: d.id, docNo: d.docNo! })}
                    >
                      Convert & send
                    </Button>
                  </span>
                )
                : null,
            }))}
          />
          {converting !== undefined && (
            <ConfirmDialog
              open
              onClose={() => setConverting(undefined)}
              onConfirm={() => documentAction(converting.id, 'convert-and-send')
                .then((doc) => { toast.ok('Invoice issued & emailed'); nav(`/documents/${doc.id}`) })
                .catch((e: Error) => { toast.err(e.message); setConverting(undefined) })}
              title="Convert to invoice & send"
              body={`Convert ${converting.docNo} to a tax invoice, assign its number and email it to the client?`}
              confirmLabel="Convert & send"
            />
          )}
          <Toolbar>
            <Badge>Showing {from}–{to} of {data!.total}</Badge>
            <span style={{ flex: 1 }} />
            <button
              type="button" className="wf" disabled={data!.page <= 1}
              onClick={() => setPage((p) => Math.max(1, p - 1))}
            >
              ‹ Prev
            </button>
            <span style={{ fontSize: 12, opacity: 0.7 }}>Page {data!.page} / {totalPages}</span>
            <button
              type="button" className="wf" disabled={data!.page >= totalPages}
              onClick={() => setPage((p) => p + 1)}
            >
              Next ›
            </button>
          </Toolbar>
        </>
      )}
    </div>
  )
}
