import { useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { formatINR, fromRupees } from '@sims/domain'
import { Badge, Button, DataTable, EmptyState, Field, Notice, PageHeader, StatCard, Stats, Toolbar } from '@sims/ui'
import {
  assignClientModule, getClient, getClientModules, getLedger, getModules,
  patchClient, patchClientModule, recordPayment,
  role, getRecurringPlans, createRecurringPlan, deactivateRecurringPlan,
  getAmc, createAmc, deactivateAmc, generateAmcRenewalInvoice,
  getInteractions, getInteractionTypes, createInteraction, updateInteraction,
  CLIENT_MODULE_STATUSES, CLIENT_STATUSES, KIND_LABEL, PAYMENT_MODES,
  type AmcPaidStatus, type ClientModule, type ClientModuleStatus, type ClientStatus,
  type InteractionType, type Kind, type Module, type Outcome, type PaymentMode,
} from '../api'
import { CLIENT_TONE, DOC_TONE, useData } from './Clients'

const inr = (p: number) => formatINR(p, { symbol: false })
const today = () => new Date().toISOString().slice(0, 10)

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' }

/** Client 360° — header, modules, documents, payments & dues (14-SPEC §Client registry). */
export function ClientDetail() {
  const id = useParams()['id'] ?? ''
  const nav = useNavigate()
  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 isOwner = role() === 'owner'
  const [actionErr, setActionErr] = useState<string | undefined>()

  const c = client.data
  if (client.error !== undefined) return <Notice tone="err">{client.error}</Notice>
  if (c === undefined) return <EmptyState>Loading…</EmptyState>

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

  return (
    <div className="wf-page">
      <PageHeader
        title={c.name} badge={c.code}
        desc={`State ${c.stateCode}${c.gstin !== undefined && c.gstin !== '' ? ` · GSTIN ${c.gstin}` : ''}${c.address !== '' ? ` · ${c.address}` : ''}`}
        actions={
          <select
            className="wf" value={c.status}
            onChange={(e) => {
              setActionErr(undefined)
              patchClient(id, { status: e.target.value as ClientStatus })
                .then(client.reload).catch((err: Error) => setActionErr(err.message))
            }}
          >
            {CLIENT_STATUSES.map((s) => <option key={s} value={s}>{s}</option>)}
          </select>
        }
      />
      <Toolbar>
        <Badge tone={CLIENT_TONE[c.status]}>{c.status}</Badge>
        {c.contacts.map((ct, i) => (
          <Badge key={i}>{[ct.name, ct.email, ct.phone].filter((x) => x !== undefined && x !== '').join(' · ')}</Badge>
        ))}
      </Toolbar>
      {actionErr !== undefined && <Notice tone="err">{actionErr}</Notice>}

      <h3>Modules</h3>
      {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 && <Notice tone="err">{cms.error}</Notice>}
      {cms.data === undefined || 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) : '—',
              }
            })}
          />
        )}

      <h3 style={{ marginTop: 20 }}>Documents</h3>
      {ledger.error !== undefined && <Notice tone="err">{ledger.error}</Notice>}
      {ledger.data === undefined || ledger.data.documents.length === 0
        ? <EmptyState>No documents yet — compose one from New Document.</EmptyState>
        : (
          <DataTable
            columns={[
              { key: 'no', label: 'No' }, { key: 'type', label: 'Type' },
              { key: 'date', label: 'Date' }, { key: 'payable', label: 'Payable', numeric: true },
              { key: 'status', label: 'Status' },
            ]}
            onRowClick={(_row, i) => nav(`/documents/${ledger.data!.documents[i]!.id}`)}
            rows={ledger.data.documents.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>,
            }))}
          />
        )}

      <h3 style={{ marginTop: 20 }}>Payments &amp; dues</h3>
      {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() }}
      />
      {ledger.data !== undefined && ledger.data.payments.length > 0 && (
        <DataTable
          columns={[
            { key: 'on', label: 'Received' }, { key: 'mode', label: 'Mode' },
            { key: 'ref', label: 'Reference' },
            { 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 && (
        <NewRecurringForm
          clientId={id}
          options={cms.data.filter((cm) => cm.active).map((cm) => ({
            id: cm.id, label: `${moduleName(cm.moduleId)} · ${KIND_LABEL[cm.kind]}`,
          }))}
          onDone={() => plans.reload()}
        />
      )}
      {plans.error !== undefined && <Notice tone="err">{plans.error}</Notice>}
      {plans.data === undefined || 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: plan.active ? (
                  <Button onClick={() => {
                    setActionErr(undefined)
                    deactivateRecurringPlan(plan.id)
                      .then(() => plans.reload()).catch((err: Error) => setActionErr(err.message))
                  }}>Deactivate</Button>
                ) : '—',
              }
            })}
          />
        )}

      <h3 style={{ marginTop: 20 }}>AMC contracts</h3>
      {isOwner && <NewAmcForm clientId={id} onDone={() => amc.reload()} />}
      {amc.error !== undefined && <Notice tone="err">{amc.error}</Notice>}
      {amc.data === undefined || 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 }}>
                  {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 onClick={() => {
                      setActionErr(undefined)
                      deactivateAmc(a.id)
                        .then(() => amc.reload()).catch((err: Error) => setActionErr(err.message))
                    }}>Deactivate</Button>
                  )}
                </div>
              ),
            }))}
          />
        )}

      <h3 style={{ marginTop: 20 }}>Interactions</h3>
      {types.data !== undefined && (
        <LogInteractionForm clientId={id} types={types.data} onDone={() => interactions.reload()} />
      )}
      {interactions.error !== undefined && <Notice tone="err">{interactions.error}</Notice>}
      {interactions.data === undefined || 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' },
            ]}
            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))
                  }}
                />
              ),
            }))}
          />
        )}
    </div>
  )
}

/** Owner-only: create a recurring plan on one of the client's modules. */
function NewRecurringForm(props: {
  clientId: string; options: { id: string; label: string }[]; onDone: () => void
}) {
  const [f, setF] = useState({ clientModuleId: '', cadence: 'monthly', amountRs: '', nextRun: today(), policy: 'manual' })
  const [error, setError] = useState<string | undefined>()
  const [saving, setSaving] = useState(false)
  const set = (k: keyof typeof f) => (e: { target: { value: string } }) =>
    setF((p) => ({ ...p, [k]: e.target.value }))

  const save = () => {
    if (f.clientModuleId === '') { setError('Pick a subscribed module'); return }
    const amount = f.amountRs === '' ? undefined : Number(f.amountRs)
    if (amount !== undefined && (!Number.isFinite(amount) || amount <= 0)) {
      setError('Amount must be a positive rupee value (or blank for the price book)'); return
    }
    setError(undefined)
    setSaving(true)
    createRecurringPlan(props.clientId, {
      clientModuleId: f.clientModuleId, cadence: f.cadence, nextRun: f.nextRun, policy: f.policy,
      ...(amount !== undefined ? { amountPaise: fromRupees(amount) } : {}),
    })
      .then(() => { setF({ clientModuleId: '', cadence: 'monthly', amountRs: '', nextRun: today(), policy: 'manual' }); props.onDone() })
      .catch((e: Error) => setError(e.message))
      .finally(() => setSaving(false))
  }

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 12, margin: '10px 0' }}>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'flex-end' }}>
        <Field label="Module">
          <select className="wf" value={f.clientModuleId} onChange={set('clientModuleId')}>
            <option value="">Module…</option>
            {props.options.map((o) => <option key={o.id} value={o.id}>{o.label}</option>)}
          </select>
        </Field>
        <Field label="Cadence">
          <select className="wf" value={f.cadence} onChange={set('cadence')}>
            <option value="monthly">monthly</option>
            <option value="yearly">yearly</option>
          </select>
        </Field>
        <Field label="Amount (₹, optional)"><input className="wf num" style={{ width: 120 }} value={f.amountRs} onChange={set('amountRs')} /></Field>
        <Field label="Next run"><input type="date" className="wf" value={f.nextRun} onChange={set('nextRun')} /></Field>
        <Field label="Policy">
          <select className="wf" value={f.policy} onChange={set('policy')}>
            <option value="manual">manual</option>
            <option value="auto">auto</option>
          </select>
        </Field>
        <Button tone="primary" onClick={save}>{saving ? 'Saving…' : 'New recurring plan'}</Button>
      </div>
      {error !== undefined && <Notice tone="err">{error}</Notice>}
    </div>
  )
}

/** Owner-only: create an AMC contract — amount entered in rupees, stored in paise. */
function NewAmcForm(props: { clientId: string; onDone: () => void }) {
  const [f, setF] = useState({ coverage: '', periodFrom: today(), periodTo: '', amountRs: '', reminderDays: '30' })
  const [error, setError] = useState<string | undefined>()
  const [saving, setSaving] = useState(false)
  const set = (k: keyof typeof f) => (e: { target: { value: string } }) =>
    setF((p) => ({ ...p, [k]: e.target.value }))

  const save = () => {
    const amount = Number(f.amountRs)
    if (!Number.isFinite(amount) || amount <= 0) { setError('Enter the contract amount in rupees'); return }
    if (f.periodTo === '') { setError('Pick the period end date'); return }
    const days = Number(f.reminderDays)
    if (!Number.isInteger(days) || days < 0) { setError('Reminder days must be a non-negative integer'); return }
    setError(undefined)
    setSaving(true)
    createAmc(props.clientId, {
      coverage: f.coverage, periodFrom: f.periodFrom, periodTo: f.periodTo,
      amountPaise: fromRupees(amount), renewalReminderDays: days,
    })
      .then(() => { setF({ coverage: '', periodFrom: today(), periodTo: '', amountRs: '', reminderDays: '30' }); props.onDone() })
      .catch((e: Error) => setError(e.message))
      .finally(() => setSaving(false))
  }

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 12, margin: '10px 0' }}>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'flex-end' }}>
        <Field label="Coverage"><input className="wf" value={f.coverage} onChange={set('coverage')} /></Field>
        <Field label="Period from"><input type="date" className="wf" value={f.periodFrom} onChange={set('periodFrom')} /></Field>
        <Field label="Period to"><input type="date" className="wf" value={f.periodTo} onChange={set('periodTo')} /></Field>
        <Field label="Amount (₹)"><input className="wf num" style={{ width: 120 }} value={f.amountRs} onChange={set('amountRs')} /></Field>
        <Field label="Reminder days"><input className="wf num" style={{ width: 80 }} value={f.reminderDays} onChange={set('reminderDays')} /></Field>
        <Button tone="primary" onClick={save}>{saving ? 'Saving…' : 'New AMC'}</Button>
      </div>
      {error !== undefined && <Notice tone="err">{error}</Notice>}
    </div>
  )
}

/** All roles: log a call / visit / training …; a follow-up date feeds the daily scan. */
function LogInteractionForm(props: { clientId: string; types: InteractionType[]; onDone: () => void }) {
  const [f, setF] = useState({ typeCode: '', onDate: today(), notes: '', outcome: '', followUpOn: '' })
  const [error, setError] = useState<string | undefined>()
  const [saving, setSaving] = useState(false)
  const set = (k: keyof typeof f) => (e: { target: { value: string } }) =>
    setF((p) => ({ ...p, [k]: e.target.value }))

  const save = () => {
    if (f.typeCode === '') { setError('Pick an interaction type'); return }
    setError(undefined)
    setSaving(true)
    createInteraction(props.clientId, {
      typeCode: f.typeCode, onDate: f.onDate, notes: f.notes,
      ...(f.outcome !== '' ? { outcome: f.outcome } : {}),
      ...(f.followUpOn !== '' ? { followUpOn: f.followUpOn } : {}),
    })
      .then(() => { setF({ typeCode: '', onDate: today(), notes: '', outcome: '', followUpOn: '' }); props.onDone() })
      .catch((e: Error) => setError(e.message))
      .finally(() => setSaving(false))
  }

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 12, margin: '10px 0' }}>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'flex-end' }}>
        <Field label="Type">
          <select className="wf" value={f.typeCode} onChange={set('typeCode')}>
            <option value="">Type…</option>
            {props.types.map((t) => <option key={t.code} value={t.code}>{t.label}</option>)}
          </select>
        </Field>
        <Field label="On"><input type="date" className="wf" value={f.onDate} onChange={set('onDate')} /></Field>
        <Field label="Outcome">
          <select className="wf" value={f.outcome} onChange={set('outcome')}>
            <option value="">—</option>
            <option value="positive">positive</option>
            <option value="neutral">neutral</option>
            <option value="negative">negative</option>
          </select>
        </Field>
        <Field label="Follow-up on"><input type="date" className="wf" value={f.followUpOn} onChange={set('followUpOn')} /></Field>
        <Button tone="primary" onClick={save}>{saving ? 'Logging…' : 'Log interaction'}</Button>
      </div>
      <div style={{ marginTop: 8 }}>
        <Field label="Notes"><textarea className="wf" rows={2} style={{ width: '100%' }} value={f.notes} onChange={set('notes')} /></Field>
      </div>
      {error !== undefined && <Notice tone="err">{error}</Notice>}
    </div>
  )
}

function AssignModuleForm(props: { modules: Module[]; onAssign: (moduleId: string, kind: Kind) => void }) {
  const [moduleId, setModuleId] = useState('')
  const mod = props.modules.find((m) => m.id === moduleId)
  const [kind, setKind] = useState<Kind | ''>('')
  return (
    <Toolbar>
      <select
        className="wf" value={moduleId}
        onChange={(e) => { setModuleId(e.target.value); setKind('') }}
      >
        <option value="">Assign module…</option>
        {props.modules.filter((m) => m.active).map((m) => <option key={m.id} value={m.id}>{m.name}</option>)}
      </select>
      {mod !== undefined && (
        <select className="wf" value={kind} onChange={(e) => setKind(e.target.value as Kind)}>
          <option value="">Kind…</option>
          {mod.allowedKinds.map((k) => <option key={k} value={k}>{KIND_LABEL[k]}</option>)}
        </select>
      )}
      <Button
        tone="primary"
        onClick={() => { if (moduleId !== '' && kind !== '') { props.onAssign(moduleId, kind); setModuleId(''); setKind('') } }}
      >
        Assign
      </Button>
    </Toolbar>
  )
}

function ClientModuleStatusSelect(props: {
  cm: ClientModule; onPatched: () => void; onError: (msg: string) => void
}) {
  return (
    <select
      className="wf" value={props.cm.status}
      onChange={(e) => {
        patchClientModule(props.cm.id, { status: e.target.value as ClientModuleStatus })
          .then(props.onPatched).catch((err: Error) => props.onError(err.message))
      }}
    >
      {CLIENT_MODULE_STATUSES.map((s) => <option key={s} value={s}>{s}</option>)}
    </select>
  )
}

function RowDate(props: {
  cm: ClientModule; field: 'installedOn' | 'completedOn' | 'trainedOn'
  onPatched: () => void; onError: (msg: string) => void
}) {
  return (
    <input
      type="date" className="wf" style={{ width: 140 }}
      value={props.cm[props.field] ?? ''}
      onChange={(e) => {
        patchClientModule(props.cm.id, { [props.field]: e.target.value !== '' ? e.target.value : null })
          .then(props.onPatched).catch((err: Error) => props.onError(err.message))
      }}
    />
  )
}

/**
 * Record a payment against the client — amounts entered in rupees, stored in
 * integer paise via fromRupees. Shared with DocumentView's "Record payment".
 */
export function PaymentForm(props: { clientId: string; onDone: () => void }) {
  const [f, setF] = useState({ amountRs: '', tdsRs: '', mode: 'bank' as PaymentMode, reference: '', receivedOn: today() })
  const [error, setError] = useState<string | undefined>()
  const [saving, setSaving] = useState(false)
  const set = (k: keyof typeof f) => (e: { target: { value: string } }) =>
    setF((p) => ({ ...p, [k]: e.target.value }))

  const save = () => {
    const amount = Number(f.amountRs)
    if (!Number.isFinite(amount) || amount <= 0) { setError('Enter a payment amount in rupees'); return }
    const tds = f.tdsRs === '' ? 0 : Number(f.tdsRs)
    if (!Number.isFinite(tds) || tds < 0) { setError('TDS must be a non-negative rupee amount'); return }
    setError(undefined)
    setSaving(true)
    recordPayment({
      clientId: props.clientId, receivedOn: f.receivedOn, mode: f.mode, reference: f.reference,
      amountPaise: fromRupees(amount), tdsPaise: fromRupees(tds),
    })
      .then(() => { setF({ amountRs: '', tdsRs: '', mode: 'bank', reference: '', receivedOn: today() }); props.onDone() })
      .catch((e: Error) => setError(e.message))
      .finally(() => setSaving(false))
  }

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 12, margin: '10px 0' }}>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'flex-end' }}>
        <Field label="Amount (₹)"><input className="wf num" style={{ width: 120 }} value={f.amountRs} onChange={set('amountRs')} /></Field>
        <Field label="TDS (₹)"><input className="wf num" style={{ width: 100 }} value={f.tdsRs} onChange={set('tdsRs')} /></Field>
        <Field label="Mode">
          <select className="wf" value={f.mode} onChange={set('mode')}>
            {PAYMENT_MODES.map((m) => <option key={m} value={m}>{m}</option>)}
          </select>
        </Field>
        <Field label="Reference"><input className="wf" value={f.reference} onChange={set('reference')} /></Field>
        <Field label="Received on"><input type="date" className="wf" value={f.receivedOn} onChange={set('receivedOn')} /></Field>
        <Button tone="primary" onClick={save}>{saving ? 'Recording…' : 'Record payment'}</Button>
      </div>
      {error !== undefined && <Notice tone="err">{error}</Notice>}
    </div>
  )
}
