import { useState } from 'react'
import { Link, useNavigate, useParams, useSearchParams } from 'react-router-dom'
import { formatINR } from '@sims/domain'
import {
  Badge, Button, ConfirmDialog, DataTable, EmptyState, ErrorState, RecordHeader, Skeleton,
  StatCard, Stats, Tabs, Toolbar, useToast,
} from '@sims/ui'
import {
  assignClientModule, getClient, getClientModules, getLedger, getModules,
  patchClient, revealDbPassword, role, isManagerial, getEmployees, setClientOwner,
  getRecurringPlans, deactivateRecurringPlan,
  getAmc, deactivateAmc, generateAmcRenewalInvoice,
  getInteractions, getInteractionTypes, updateInteraction,
  getClientAwsUsage,
  CLIENT_STATUSES, KIND_LABEL,
  type AmcContract, type AmcPaidStatus, type Client, type ClientStatus, type Interaction,
  type Outcome, type RecurringPlan,
} from '../api'
import { CLIENT_TONE, DOC_TONE, useData } from './Clients'
import {
  AccountOwnerSelect, AmcDialog, AssignModuleForm, ClientModuleStatusSelect,
  InteractionDialog, PaymentForm, PlanDialog, RowDate,
} from './client-forms'
import { ClientFormDialog } from '../components/ClientFormDialog'
import { PulseRibbon } from '../components/PulseRibbon'
import { type PulseEvent } from '../pulse'

const inr = (p: number) => formatINR(p, { symbol: false })

const AMC_TONE: Record<AmcPaidStatus, 'ok' | 'warn' | 'err'> = { paid: 'ok', unpaid: 'err', unbilled: 'warn' }
const OUTCOME_TONE: Record<Outcome, 'ok' | 'warn' | 'err'> = { positive: 'ok', neutral: 'warn', negative: 'err' }

const TAB_KEYS = ['overview', 'modules', 'documents', 'payments', 'amc', 'interactions', 'aws'] as const
type TabKey = (typeof TAB_KEYS)[number]

/** One pending confirmation — replaces the browser confirm() popup with the styled dialog
 *  (same pattern as DocumentView Task 5). */
interface Confirm { title: string; body: string; label: string; tone?: 'danger'; run: () => void | Promise<void> }

/** Client 360° — record header, KPIs, pulse ribbon (Task 10), tabbed sections. */
export function ClientDetail() {
  const id = useParams()['id'] ?? ''
  const nav = useNavigate()
  const [sp, setSp] = useSearchParams()
  const client = useData(() => getClient(id), [id])
  const modules = useData(getModules, [])
  const cms = useData(() => getClientModules(id), [id])
  const ledger = useData(() => getLedger(id), [id])
  const plans = useData(() => getRecurringPlans(id), [id])
  const amc = useData(() => getAmc(id), [id])
  const interactions = useData(() => getInteractions(id), [id])
  const types = useData(getInteractionTypes, [])
  const awsUsage = useData(() => getClientAwsUsage(id), [id])
  const employees = useData(() => getEmployees(), [])
  const isOwner = role() === 'owner'
  const canRoute = isManagerial()
  const toast = useToast()
  const [actionErr, setActionErr] = useState<string | undefined>()
  const [editing, setEditing] = useState(false)
  const [amcDialog, setAmcDialog] = useState<{ initial?: AmcContract } | undefined>()
  const [planDialog, setPlanDialog] = useState<{ initial?: RecurringPlan } | undefined>()
  const [interactionDialog, setInteractionDialog] = useState<{ initial?: Interaction } | undefined>()
  const [confirm, setConfirm] = useState<Confirm | undefined>()

  const rawTab = sp.get('tab') ?? 'overview'
  const tab: TabKey = (TAB_KEYS as readonly string[]).includes(rawTab) ? (rawTab as TabKey) : 'overview'
  const setTab = (k: string) => setSp(k === 'overview' ? {} : { tab: k }, { replace: true })

  const c = client.data
  if (client.error !== undefined) return <ErrorState message={client.error} onRetry={client.reload} />
  if (c === undefined) return <div className="wf-page"><Skeleton rows={6} /></div>

  const moduleName = (moduleId: string) =>
    modules.data?.find((m) => m.id === moduleId)?.name ?? moduleId

  const docs = ledger.data?.documents ?? []
  const openDocs = docs.filter((d) => d.status === 'draft' || d.status === 'sent' || d.status === 'part_paid')
  const activeModules = (cms.data ?? []).filter((m) => m.active)
  const lastInteraction = interactions.data?.[0]?.onDate

  const todayIso = new Date().toISOString().slice(0, 10)
  const DOC_PULSE_TONE: Record<string, PulseEvent['tone']> = {
    paid: 'ok', part_paid: 'warn', lost: 'err', cancelled: 'err',
  }
  const pulseEvents: PulseEvent[] = [
    ...docs.map((d): PulseEvent => ({
      id: `doc:${d.id}`, lane: 0, date: d.docDate,
      label: `${d.docType} ${d.docNo ?? '(draft)'} — ${formatINR(d.payablePaise)} · ${d.status}`,
      tone: DOC_PULSE_TONE[d.status] ?? 'accent',
    })),
    ...(ledger.data?.payments ?? []).map((p): PulseEvent => ({
      id: `pay:${p.id}`, lane: 1, date: p.receivedOn,
      label: `Payment ${formatINR(p.amountPaise)} · ${p.mode}`, tone: 'ok',
    })),
    ...(interactions.data ?? []).map((i): PulseEvent => ({
      id: `int:${i.id}`, lane: 2, date: i.onDate,
      label: `${i.outcome !== null ? i.outcome + ' · ' : ''}${types.data?.find((t) => t.code === i.typeCode)?.label ?? i.typeCode}${i.notes !== '' ? ` — ${i.notes.slice(0, 60)}` : ''}`,
      tone: i.outcome === 'negative' ? 'err' : i.outcome === 'positive' ? 'ok' : 'warn',
    })),
    ...(amc.data ?? []).flatMap((a): PulseEvent[] => [
      { id: `amc-from:${a.id}`, lane: 3, date: a.periodFrom, label: `AMC starts — ${a.coverage !== '' ? a.coverage : 'contract'}`, tone: 'accent' },
      { id: `amc-to:${a.id}`, lane: 3, date: a.periodTo, label: `AMC renewal — ${a.paidStatus}`, tone: a.paidStatus === 'unpaid' ? 'err' : 'warn' },
    ]),
    ...activeModules.filter((cm) => cm.nextRenewal !== null).map((cm): PulseEvent => ({
      id: `ren:${cm.id}`, lane: 3, date: cm.nextRenewal!,
      label: `${moduleName(cm.moduleId)} renews`, tone: 'warn',
    })),
  ]
  const openPulse = (ev: PulseEvent) => {
    if (ev.id.startsWith('doc:')) nav(`/documents/${ev.id.slice(4)}`)
    else if (ev.id.startsWith('pay:')) setTab('payments')
    else if (ev.id.startsWith('int:')) setTab('interactions')
    else setTab('amc')
  }

  return (
    <div className="wf-page">
      <div className="wf-crumbs"><Link to="/clients">Clients</Link><span>/</span><span>{c.code}</span></div>
      <RecordHeader
        name={c.name}
        status={<Badge tone={CLIENT_TONE[c.status]}>{c.status}</Badge>}
        meta={
          <>
            <span className="mono">{c.code}</span>
            <span>· State {c.stateCode}</span>
            {c.gstin !== undefined && c.gstin !== '' && <span className="mono">· {c.gstin}</span>}
            {c.contacts[0] !== undefined && (
              <span>· {[c.contacts[0].name, c.contacts[0].email, c.contacts[0].phone].filter((x) => x !== undefined && x !== '').join(' · ')}</span>
            )}
          </>
        }
        actions={
          <>
            <Button onClick={() => setEditing(true)}>Edit</Button>
            <select
              className="wf" style={{ width: 'auto' }} value={c.status}
              onChange={(e) => {
                setActionErr(undefined)
                patchClient(id, { status: e.target.value as ClientStatus })
                  .then(() => { toast.ok('Status updated'); client.reload() })
                  .catch((err: Error) => setActionErr(err.message))
              }}
            >
              {CLIENT_STATUSES.map((s) => <option key={s} value={s}>{s}</option>)}
            </select>
            <Button onClick={() => setTab('interactions')}>Log call</Button>
            <Button onClick={() => setTab('payments')}>Record payment</Button>
            <Button tone="primary" onClick={() => nav('/documents/new')}>New document</Button>
          </>
        }
      />
      {canRoute && employees.data !== undefined && (
        <Toolbar>
          <AccountOwnerSelect
            ownerId={c.ownerId}
            employees={employees.data.employees}
            onChange={(ownerId) => {
              setActionErr(undefined)
              setClientOwner(id, ownerId)
                .then(() => { toast.ok('Owner updated'); client.reload() })
                .catch((err: Error) => setActionErr(err.message))
            }}
          />
        </Toolbar>
      )}
      {actionErr !== undefined && <ErrorState message={actionErr} />}
      <SupportCard client={c} onChanged={() => client.reload()} />
      <ClientFormDialog
        open={editing}
        onClose={() => setEditing(false)}
        initial={c}
        onSaved={() => client.reload()}
      />

      <Tabs
        active={tab}
        onChange={setTab}
        tabs={[
          { key: 'overview', label: 'Overview' },
          { key: 'modules', label: 'Modules', count: (cms.data ?? []).length },
          { key: 'documents', label: 'Documents', count: docs.length },
          { key: 'payments', label: 'Payments & plans', count: (ledger.data?.payments ?? []).length },
          { key: 'amc', label: 'AMC', count: (amc.data ?? []).length },
          { key: 'interactions', label: 'Interactions', count: (interactions.data ?? []).length },
          { key: 'aws', label: 'AWS', count: (awsUsage.data ?? []).length },
        ]}
      />

      {tab === 'overview' && (
        <>
          <Stats>
            <StatCard label="Active modules" value={String(activeModules.length)} />
            <StatCard label="Advance on account" value={ledger.data !== undefined ? formatINR(ledger.data.advancePaise) : '…'} hint="unallocated payments" />
            <StatCard label="Open documents" value={String(openDocs.length)} hint={`${docs.length} total`} />
            <StatCard label="Last interaction" value={lastInteraction ?? '—'} />
          </Stats>
          <PulseRibbon events={pulseEvents} todayIso={todayIso} onOpen={openPulse} />
          <h3 style={{ marginTop: 18 }}>Recent documents</h3>
          {docs.length === 0 ? <EmptyState>No documents yet.</EmptyState> : (
            <DataTable
              columns={[
                { key: 'no', label: 'No', mono: true }, { key: 'type', label: 'Type' },
                { key: 'date', label: 'Date' }, { key: 'payable', label: 'Payable', numeric: true },
                { key: 'status', label: 'Status' },
              ]}
              onRowClick={(_row, i) => nav(`/documents/${docs[i]!.id}`)}
              rows={docs.slice(0, 5).map((d) => ({
                no: d.docNo ?? 'draft', type: d.docType, date: d.docDate,
                payable: inr(d.payablePaise),
                status: <Badge tone={DOC_TONE[d.status]}>{d.status}</Badge>,
              }))}
            />
          )}
          {docs.length > 5 && (
            <Toolbar><Button onClick={() => setTab('documents')}>All {docs.length} documents →</Button></Toolbar>
          )}
        </>
      )}

      {tab === 'modules' && (
        <>
          {modules.data !== undefined && (
            <AssignModuleForm
              modules={modules.data}
              onAssign={(moduleId, kind) => {
                setActionErr(undefined)
                assignClientModule(id, { moduleId, kind })
                  .then(() => { cms.reload(); ledger.reload() })
                  .catch((err: Error) => setActionErr(err.message))
              }}
            />
          )}
          {cms.error !== undefined && <ErrorState message={cms.error} onRetry={cms.reload} />}
          {cms.data === undefined && cms.error === undefined ? <Skeleton />
            : (cms.data ?? []).length === 0 ? <EmptyState>No modules assigned yet.</EmptyState> : (
              <DataTable
                columns={[
                  { key: 'module', label: 'Module' }, { key: 'kind', label: 'Kind' },
                  { key: 'status', label: 'Status' },
                  { key: 'installed', label: 'Installed' }, { key: 'completed', label: 'Completed' },
                  { key: 'trained', label: 'Trained' },
                  { key: 'billed', label: 'Billed', numeric: true },
                  { key: 'settled', label: 'Settled', numeric: true },
                ]}
                rows={(cms.data ?? []).map((cm) => {
                  const paid = ledger.data?.modulePaid.find((mp) => mp.moduleId === cm.moduleId)
                  return {
                    module: moduleName(cm.moduleId),
                    kind: KIND_LABEL[cm.kind],
                    status: <ClientModuleStatusSelect cm={cm} onPatched={() => cms.reload()} onError={setActionErr} />,
                    installed: <RowDate cm={cm} field="installedOn" onPatched={() => cms.reload()} onError={setActionErr} />,
                    completed: <RowDate cm={cm} field="completedOn" onPatched={() => cms.reload()} onError={setActionErr} />,
                    trained: <RowDate cm={cm} field="trainedOn" onPatched={() => cms.reload()} onError={setActionErr} />,
                    billed: paid !== undefined ? inr(paid.billedPaise) : '—',
                    settled: paid !== undefined ? inr(paid.settledPaise) : '—',
                  }
                })}
              />
            )}
        </>
      )}

      {tab === 'documents' && (
        <>
          {ledger.error !== undefined && <ErrorState message={ledger.error} onRetry={ledger.reload} />}
          {ledger.data === undefined && ledger.error === undefined ? <Skeleton />
            : docs.length === 0 ? <EmptyState>No documents yet — compose one from New Document.</EmptyState> : (
              <DataTable
                columns={[
                  { key: 'no', label: 'No', mono: true }, { key: 'type', label: 'Type' },
                  { key: 'date', label: 'Date' }, { key: 'payable', label: 'Payable', numeric: true },
                  { key: 'status', label: 'Status' },
                ]}
                onRowClick={(_row, i) => nav(`/documents/${docs[i]!.id}`)}
                rows={docs.map((d) => ({
                  no: d.docNo ?? <Badge tone="warn">draft</Badge>,
                  type: d.docType, date: d.docDate,
                  payable: inr(d.payablePaise),
                  status: <Badge tone={DOC_TONE[d.status]}>{d.status}</Badge>,
                }))}
              />
            )}
        </>
      )}

      {tab === 'payments' && (
        <>
          {ledger.data !== undefined && (
            <Stats>
              <StatCard label="Advance on account" value={formatINR(ledger.data.advancePaise)} hint="unallocated payments" />
            </Stats>
          )}
          <PaymentForm clientId={id} onDone={() => { ledger.reload(); cms.reload(); amc.reload() }} />
          {ledger.data !== undefined && ledger.data.payments.length > 0 && (
            <DataTable
              columns={[
                { key: 'on', label: 'Received' }, { key: 'mode', label: 'Mode' },
                { key: 'ref', label: 'Reference', mono: true },
                { key: 'amount', label: 'Amount', numeric: true },
                { key: 'tds', label: 'TDS', numeric: true },
              ]}
              rows={ledger.data.payments.map((p) => ({
                on: p.receivedOn, mode: p.mode, ref: p.reference !== '' ? p.reference : '—',
                amount: inr(p.amountPaise), tds: p.tdsPaise > 0 ? inr(p.tdsPaise) : '—',
              }))}
            />
          )}
          <h3 style={{ marginTop: 20 }}>Recurring plans</h3>
          {isOwner && cms.data !== undefined && (
            <Toolbar>
              <Button tone="primary" onClick={() => setPlanDialog({})}>New recurring plan</Button>
            </Toolbar>
          )}
          {plans.error !== undefined && <ErrorState message={plans.error} onRetry={plans.reload} />}
          {plans.data === undefined && plans.error === undefined ? <Skeleton />
            : (plans.data ?? []).length === 0 ? <EmptyState>No recurring plans.</EmptyState> : (
              <DataTable
                columns={[
                  { key: 'module', label: 'Module' }, { key: 'cadence', label: 'Cadence' },
                  { key: 'amount', label: 'Amount', numeric: true }, { key: 'next', label: 'Next run' },
                  { key: 'policy', label: 'Policy' }, { key: 'active', label: 'Active' }, { key: 'act', label: '' },
                ]}
                rows={(plans.data ?? []).map((plan) => {
                  const cm = cms.data?.find((x) => x.id === plan.clientModuleId)
                  return {
                    module: cm !== undefined ? moduleName(cm.moduleId) : '—',
                    cadence: plan.cadence,
                    amount: plan.amountPaise !== null ? inr(plan.amountPaise) : 'price book',
                    next: plan.nextRun,
                    policy: <Badge tone={plan.policy === 'auto' ? 'accent' : 'warn'}>{plan.policy}</Badge>,
                    active: plan.active ? 'yes' : 'no',
                    act: (
                      <div style={{ display: 'flex', gap: 6 }}>
                        {isOwner && <Button onClick={() => setPlanDialog({ initial: plan })}>Edit</Button>}
                        {plan.active && (
                          <Button tone="danger" onClick={() => setConfirm({
                            title: 'Deactivate recurring plan',
                            body: `Deactivate the ${plan.cadence} recurring plan${cm !== undefined ? ` for ${moduleName(cm.moduleId)}` : ''}?`,
                            label: 'Deactivate',
                            tone: 'danger',
                            run: () => deactivateRecurringPlan(plan.id).then(() => { toast.ok('Plan deactivated'); plans.reload() }),
                          })}>Deactivate</Button>
                        )}
                      </div>
                    ),
                  }
                })}
              />
            )}
          <PlanDialog
            open={planDialog !== undefined}
            onClose={() => setPlanDialog(undefined)}
            clientId={id}
            options={(cms.data ?? []).filter((cm) => cm.active).map((cm) => ({
              id: cm.id, label: `${moduleName(cm.moduleId)} · ${KIND_LABEL[cm.kind]}`,
            }))}
            initial={planDialog?.initial}
            onDone={() => plans.reload()}
          />
        </>
      )}

      {tab === 'amc' && (
        <>
          {isOwner && (
            <Toolbar>
              <Button tone="primary" onClick={() => setAmcDialog({})}>New AMC</Button>
            </Toolbar>
          )}
          {amc.error !== undefined && <ErrorState message={amc.error} onRetry={amc.reload} />}
          {amc.data === undefined && amc.error === undefined ? <Skeleton />
            : (amc.data ?? []).length === 0 ? <EmptyState>No AMC contracts.</EmptyState> : (
              <DataTable
                columns={[
                  { key: 'coverage', label: 'Coverage' }, { key: 'period', label: 'Period' },
                  { key: 'amount', label: 'Amount', numeric: true },
                  { key: 'days', label: 'Reminder days', numeric: true },
                  { key: 'paid', label: 'Paid' }, { key: 'act', label: '' },
                ]}
                rows={(amc.data ?? []).map((a) => ({
                  coverage: a.coverage !== '' ? a.coverage : '—',
                  period: `${a.periodFrom} → ${a.periodTo}`,
                  amount: inr(a.amountPaise),
                  days: a.renewalReminderDays,
                  paid: <Badge tone={AMC_TONE[a.paidStatus]}>{a.paidStatus}</Badge>,
                  act: (
                    <div style={{ display: 'flex', gap: 6 }}>
                      {isOwner && <Button onClick={() => setAmcDialog({ initial: a })}>Edit</Button>}
                      {a.paidStatus !== 'unpaid' && (
                        <Button tone="primary" onClick={() => {
                          setActionErr(undefined)
                          generateAmcRenewalInvoice(a.id)
                            .then((doc) => nav(`/documents/${doc.id}`)).catch((err: Error) => setActionErr(err.message))
                        }}>Generate renewal invoice</Button>
                      )}
                      {a.active && (
                        <Button tone="danger" onClick={() => setConfirm({
                          title: 'Deactivate AMC contract',
                          body: `Deactivate the AMC contract${a.coverage !== '' ? ` "${a.coverage}"` : ''} (${a.periodFrom} → ${a.periodTo})? This does not affect existing invoices.`,
                          label: 'Deactivate',
                          tone: 'danger',
                          run: () => deactivateAmc(a.id).then(() => { toast.ok('AMC deactivated'); amc.reload() }),
                        })}>Deactivate</Button>
                      )}
                    </div>
                  ),
                }))}
              />
            )}
          <AmcDialog
            open={amcDialog !== undefined}
            onClose={() => setAmcDialog(undefined)}
            clientId={id}
            initial={amcDialog?.initial}
            onDone={() => amc.reload()}
          />
        </>
      )}

      {tab === 'interactions' && (
        <>
          <Toolbar>
            <Button tone="primary" onClick={() => setInteractionDialog({})}>Log interaction</Button>
          </Toolbar>
          {interactions.error !== undefined && <ErrorState message={interactions.error} onRetry={interactions.reload} />}
          {interactions.data === undefined && interactions.error === undefined ? <Skeleton />
            : (interactions.data ?? []).length === 0 ? <EmptyState>No interactions logged yet.</EmptyState> : (
              <DataTable
                columns={[
                  { key: 'on', label: 'Date' }, { key: 'type', label: 'Type' },
                  { key: 'notes', label: 'Notes' }, { key: 'outcome', label: 'Outcome' },
                  { key: 'follow', label: 'Follow-up' }, { key: 'act', label: '' },
                ]}
                rows={(interactions.data ?? []).map((i) => ({
                  on: i.onDate,
                  type: types.data?.find((t) => t.code === i.typeCode)?.label ?? i.typeCode,
                  notes: i.notes !== '' ? i.notes : '—',
                  outcome: i.outcome !== null ? <Badge tone={OUTCOME_TONE[i.outcome]}>{i.outcome}</Badge> : '—',
                  follow: (
                    <input
                      type="date" className="wf" style={{ width: 140 }}
                      value={i.followUpOn ?? ''}
                      onChange={(e) => {
                        setActionErr(undefined)
                        updateInteraction(i.id, { followUpOn: e.target.value !== '' ? e.target.value : null })
                          .then(() => interactions.reload()).catch((err: Error) => setActionErr(err.message))
                      }}
                    />
                  ),
                  act: <Button onClick={() => setInteractionDialog({ initial: i })}>Edit</Button>,
                }))}
              />
            )}
          <InteractionDialog
            open={interactionDialog !== undefined}
            onClose={() => setInteractionDialog(undefined)}
            clientId={id}
            types={types.data ?? []}
            initial={interactionDialog?.initial}
            onDone={() => interactions.reload()}
          />
        </>
      )}

      {tab === 'aws' && (
        <>
          {awsUsage.error !== undefined && <ErrorState message={awsUsage.error} onRetry={awsUsage.reload} />}
          {awsUsage.data === undefined && awsUsage.error === undefined ? <Skeleton />
            : (awsUsage.data ?? []).length === 0 ? <EmptyState>No AWS usage recorded for this client.</EmptyState> : (
              <DataTable
                columns={[
                  { key: 'month', label: 'Month', mono: true }, { key: 'storage', label: 'Storage GB', numeric: true },
                  { key: 'transfer', label: 'Transfer GB', numeric: true }, { key: 'cost', label: 'Cost', numeric: true },
                  { key: 'source', label: 'Source' },
                ]}
                rows={(awsUsage.data ?? []).map((u) => ({
                  month: u.month, storage: u.storageGb, transfer: u.transferGb, cost: inr(u.costPaise), source: u.source,
                }))}
              />
            )}
        </>
      )}

      {confirm !== undefined && (
        <ConfirmDialog
          open
          onClose={() => setConfirm(undefined)}
          onConfirm={confirm.run}
          title={confirm.title}
          body={confirm.body}
          confirmLabel={confirm.label}
          {...(confirm.tone !== undefined ? { tone: confirm.tone } : {})}
        />
      )}
    </div>
  )
}

/**
 * Support-access card (D18 WS-F): the fields the old APEX book carried on every
 * client row — AnyDesk id (44× referenced there), OS, district/sector — plus the
 * encrypted DB password: shown as ••••, revealed only by owner/manager, and every
 * reveal is audited server-side. Setting/updating it rides PATCH (managerial).
 */
function SupportCard(props: { client: Client; onChanged: () => void }) {
  const toast = useToast()
  const managerial = isManagerial()
  const c = props.client
  const [revealed, setRevealed] = useState<string | undefined>()
  const [settingPw, setSettingPw] = useState(false)
  const [pw, setPw] = useState('')
  const [busy, setBusy] = useState(false)

  const copy = (text: string, what: string) => {
    navigator.clipboard.writeText(text).then(() => toast.ok(`${what} copied`)).catch(() => toast.err('Copy failed'))
  }
  const reveal = () => {
    if (busy) return
    setBusy(true)
    revealDbPassword(c.id)
      .then((p) => setRevealed(p))
      .catch((e: Error) => toast.err(e.message))
      .finally(() => setBusy(false))
  }
  const savePw = () => {
    if (busy || pw === '') return
    setBusy(true)
    patchClient(c.id, { dbPassword: pw })
      .then(() => { toast.ok('DB password stored (encrypted)'); setSettingPw(false); setPw(''); setRevealed(undefined); props.onChanged() })
      .catch((e: Error) => toast.err(e.message))
      .finally(() => setBusy(false))
  }

  const cell = (label: string, value: string | undefined, mono = false, copyable = false) => (
    <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6, marginRight: 18 }}>
      <span style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: 0.5, opacity: 0.6 }}>{label}</span>
      <span className={mono ? 'mono' : undefined}>{value ?? '—'}</span>
      {copyable && value !== undefined && <Button onClick={() => copy(value, label)}>Copy</Button>}
    </span>
  )

  return (
    <div className="wf-card" style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 8, padding: '10px 14px' }}>
      {cell('AnyDesk', c.anydesk, true, true)}
      {cell('OS', c.os)}
      {cell('District', c.district)}
      {cell('Sector', c.sector)}
      {/* Typed contact rows (spec §5): whatsapp/secretary contacts surface here by label. */}
      {c.contacts
        .filter((ct) => ct.role === 'whatsapp' || ct.role === 'secretary')
        .map((ct, i) => {
          const num = ct.phone ?? ct.email
          return (
            <span key={i} style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6, marginRight: 18 }}>
              <span style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: 0.5, opacity: 0.6 }}>
                {ct.role === 'whatsapp' ? 'WhatsApp' : 'Secretary'}
              </span>
              <span>{[ct.name, num].filter((x) => x !== undefined && x !== '').join(' · ')}</span>
              {num !== undefined && num !== '' && (
                <Button onClick={() => copy(num, ct.role === 'whatsapp' ? 'WhatsApp number' : 'Secretary contact')}>Copy</Button>
              )}
            </span>
          )
        })}
      <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6 }}>
        <span style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: 0.5, opacity: 0.6 }}>DB password</span>
        {revealed !== undefined
          ? <><span className="mono">{revealed}</span><Button onClick={() => copy(revealed, 'DB password')}>Copy</Button><Button onClick={() => setRevealed(undefined)}>Hide</Button></>
          : c.hasDbPassword
            ? <><span className="mono">••••••••</span>{managerial && <Button onClick={reveal}>{busy ? '…' : 'Reveal'}</Button>}</>
            : <span style={{ opacity: 0.6 }}>not set</span>}
        {managerial && !settingPw && <Button onClick={() => setSettingPw(true)}>{c.hasDbPassword ? 'Update' : 'Set…'}</Button>}
        {managerial && settingPw && (
          <>
            <input className="wf mono" type="password" style={{ width: 160 }} placeholder="DB password"
              value={pw} onChange={(e) => setPw(e.target.value)} />
            <Button tone="primary" onClick={savePw}>{busy ? 'Saving…' : 'Save'}</Button>
            <Button onClick={() => { setSettingPw(false); setPw('') }}>Cancel</Button>
          </>
        )}
      </span>
    </div>
  )
}
