import { useEffect, useMemo, useState } from 'react'
import { Navigate } from 'react-router-dom'
import { Button, Field, Notice, PageHeader } from '@sims/ui'
import { getTemplateSettings, previewSample, putTemplateSettings, role, uploadTemplateLogo } from '../api'
import { LivePreview } from '../components/LivePreview'

const COMPANY_FIELDS: { key: string; setting: string; label: string; area: boolean }[] = [
  { key: 'name', setting: 'company.name', label: 'Company name', area: false },
  { key: 'address', setting: 'company.address', label: 'Address', area: true },
  { key: 'gstin', setting: 'company.gstin', label: 'GSTIN', area: false },
  { key: 'stateCode', setting: 'company.state_code', label: 'State code', area: false },
  { key: 'phone', setting: 'company.phone', label: 'Phone', area: false },
  { key: 'email', setting: 'company.email', label: 'Email', area: false },
  { key: 'bank', setting: 'company.bank', label: 'Bank details', area: true },
]
const TEMPLATE_FIELDS: { key: string; setting: string; label: string; area: boolean }[] = [
  { key: 'terms', setting: 'template.terms', label: 'Default terms', area: true },
  { key: 'declaration', setting: 'template.declaration', label: 'GST declaration', area: true },
  { key: 'jurisdiction', setting: 'template.jurisdiction', label: 'Jurisdiction line', area: false },
  { key: 'footerNote', setting: 'template.footer_note', label: 'Footer note', area: false },
  { key: 'signatoryLabel', setting: 'template.signatory_label', label: 'Signatory label', area: false },
]
const DOC_TITLES: { type: string; setting: string; label: string }[] = [
  { type: 'INVOICE', setting: 'template.title_INVOICE', label: 'Invoice title' },
  { type: 'QUOTATION', setting: 'template.title_QUOTATION', label: 'Quotation title' },
  { type: 'PROFORMA', setting: 'template.title_PROFORMA', label: 'Proforma title' },
]

type Dict = Record<string, string>

/** Owner-only: all letterhead text data (company.* + template.*) with a live
 *  letterhead preview beside the form. One fixed layout — not a visual editor. */
export function DocumentTemplate() {
  const [company, setCompany] = useState<Dict>({})
  const [template, setTemplate] = useState<Dict>({})
  const [titles, setTitles] = useState<Dict>({})
  const [logo, setLogo] = useState('')
  const [commitNonce, setCommitNonce] = useState(0)
  const [msg, setMsg] = useState<{ tone: 'ok' | 'err'; text: string } | undefined>()
  const [saving, setSaving] = useState(false)

  const load = (s: Dict): void => {
    setCompany(Object.fromEntries(COMPANY_FIELDS.map((x) => [x.key, s[x.setting] ?? ''])))
    setTemplate(Object.fromEntries(TEMPLATE_FIELDS.map((x) => [x.key, s[x.setting] ?? ''])))
    setTitles(Object.fromEntries(DOC_TITLES.map((x) => [x.type, s[x.setting] ?? ''])))
    setLogo(s['template.logo'] ?? '')
  }
  useEffect(() => { getTemplateSettings().then(load).catch((e: Error) => setMsg({ tone: 'err', text: e.message })) }, [])

  // Logo excluded from the body — it is saved on pick and the preview reads it back.
  const previewBody = useMemo(() => JSON.stringify({ company, template, titles }), [company, template, titles])
  const commit = () => setCommitNonce((n) => n + 1)

  if (role() !== 'owner') return <Navigate to="/" replace />

  const save = () => {
    setSaving(true); setMsg(undefined)
    putTemplateSettings({ company, template, titles })
      .then((s) => { load(s); setMsg({ tone: 'ok', text: 'Saved. Every document uses the new template immediately.' }) })
      .catch((e: Error) => setMsg({ tone: 'err', text: e.message }))
      .finally(() => setSaving(false))
  }
  const onLogo = (file: File | undefined) => {
    if (file === undefined) return
    const reader = new FileReader()
    reader.onload = () => {
      uploadTemplateLogo(String(reader.result))
        .then((saved) => { setLogo(saved); commit(); setMsg({ tone: 'ok', text: 'Logo saved.' }) })
        .catch((e: Error) => setMsg({ tone: 'err', text: e.message }))
    }
    reader.readAsDataURL(file)
  }

  const textField = (dict: Dict, setDict: (u: (p: Dict) => Dict) => void) =>
    (x: { key: string; label: string; area: boolean }) => (
      <Field key={x.key} label={x.label}>
        {x.area
          ? <textarea className="wf" rows={2} style={{ width: '100%' }} value={dict[x.key] ?? ''} onChange={(e) => setDict((p) => ({ ...p, [x.key]: e.target.value }))} onBlur={commit} />
          : <input className="wf" style={{ width: '100%' }} value={dict[x.key] ?? ''} onChange={(e) => setDict((p) => ({ ...p, [x.key]: e.target.value }))} onBlur={commit} />}
      </Field>
    )

  return (
    <div style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>
      <div className="wf-page" style={{ flex: '0 0 520px', minWidth: 0, overflow: 'auto', height: 'calc(100vh - 140px)' }}>
        <PageHeader title="Document template" desc="Everything the letterhead prints — one fixed layout, all text editable. Changes apply to every document immediately." />
        {msg !== undefined && <Notice tone={msg.tone}>{msg.text}</Notice>}

        <h3>Company</h3>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>{COMPANY_FIELDS.map(textField(company, setCompany))}</div>

        <h3 style={{ marginTop: 18 }}>Logo</h3>
        <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
          <input type="file" accept="image/*" onChange={(e) => onLogo(e.target.files?.[0])} />
          {logo !== '' && <><img src={logo} alt="logo" style={{ maxHeight: 40 }} /><Button onClick={() => { uploadTemplateLogo('').then(() => { setLogo(''); commit() }).catch(() => { /* ignore */ }) }}>Remove</Button></>}
        </div>

        <h3 style={{ marginTop: 18 }}>Boilerplate text</h3>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>{TEMPLATE_FIELDS.map(textField(template, setTemplate))}</div>

        <h3 style={{ marginTop: 18 }}>Document titles (optional overrides)</h3>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {DOC_TITLES.map((t) => (
            <Field key={t.type} label={t.label}>
              <input className="wf" style={{ width: '100%' }} placeholder="built-in default" value={titles[t.type] ?? ''} onChange={(e) => setTitles((p) => ({ ...p, [t.type]: e.target.value }))} onBlur={commit} />
            </Field>
          ))}
        </div>

        <div style={{ marginTop: 14 }}><Button tone="primary" onClick={save}>{saving ? 'Saving…' : 'Save template'}</Button></div>
      </div>

      <div style={{ flex: 1, minWidth: 0, position: 'sticky', top: 12, height: 'calc(100vh - 140px)', background: 'var(--bg-sunken, #e9e9ee)', borderRadius: 8, padding: 12 }}>
        <div style={{ width: '100%', height: '100%', background: '#fff', borderRadius: 4, boxShadow: '0 1px 6px rgba(0,0,0,.15)', overflow: 'hidden' }}>
          <LivePreview
            body={previewBody}
            commitNonce={commitNonce}
            fetchPreview={(b, signal) => previewSample(JSON.parse(b), signal).then((r) => ({ html: r.html }))}
          />
        </div>
      </div>
    </div>
  )
}
