'use client'

import { useState } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { renderTemplate, renderTemplateClean, sampleDataFor, TEMPLATE_SAMPLE_DATA, TEMPLATE_VARIABLES, TEMPLATE_VARIABLE_DESCRIPTIONS } from '@/lib/email-templates'
import { formatDateTime } from '@/lib/format'
import { EMAIL_CATEGORIES, STREAM_SENDERS } from '@/lib/domain/email-policy'
import { BackLink } from '@/components/app/back-link'

export interface TemplateRow {
  key: string
  name: string
  subject: string
  body: string
  recipients_note: string
  cc_rules: string
  trigger_note: string
  internal_notes: string
  cta_text: string
  footer: string
  support_contact: string
  version: number
  active: boolean
  updated_by: string | null
  updated_at: string | null
  template_id: string | null
  /** Created by "Duplicate" — lives only in the database. */
  is_custom: boolean
  /** Two streams (2026-09-22): transactional (info@) or updates (updates@); category decides preferences. */
  email_stream: 'transactional' | 'updates'
  category_key: string
  required: boolean
}

export interface VersionRow {
  id: string
  template_id: string
  subject: string
  body: string
  edited_by: string | null
  reason: string | null
  created_at: string
  version?: number | null
  previous_subject?: string | null
  previous_body?: string | null
}

/** Admin editor: template list · editor · live preview with sample data ·
 *  version history with restore · test-send (recorded; sending = backend). */
export function EmailTemplatesAdmin({
  templates,
  versions,
}: {
  templates: TemplateRow[]
  versions: VersionRow[]
}) {
  const router = useRouter()
  const [selectedKey, setSelectedKey] = useState(templates[0]?.key ?? '')
  const source = templates.find((t) => t.key === selectedKey) ?? templates[0]
  const [form, setForm] = useState<TemplateRow>(source)
  const [reason, setReason] = useState('')
  const [saving, setSaving] = useState(false)
  const [testTo, setTestTo] = useState('')
  const [testing, setTesting] = useState(false)
  const [showVars, setShowVars] = useState(false)

  function selectTemplate(key: string) {
    const t = templates.find((x) => x.key === key)
    if (!t) return
    setSelectedKey(key)
    setForm(t)
    setReason('')
  }

  const set = <K extends keyof TemplateRow>(k: K, v: TemplateRow[K]) =>
    setForm((f) => ({ ...f, [k]: v }))

  async function save() {
    setSaving(true)
    try {
      const res = await fetch('/api/admin/email-templates', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          key: form.key,
          name: form.name,
          subject: form.subject,
          body: form.body,
          recipients_note: form.recipients_note,
          cc_rules: form.cc_rules,
          trigger_note: form.trigger_note,
          internal_notes: form.internal_notes,
          cta_text: form.cta_text,
          footer: form.footer,
          support_contact: form.support_contact,
          email_stream: form.email_stream,
          category_key: form.category_key,
          required: form.required,
          active: form.active,
          reason,
        }),
      })
      const json = await res.json()
      if (!res.ok) toast.error(json.error ?? 'Could not save the template')
      else {
        toast.success(`Template saved — version ${json.version ?? ''} recorded`)
        setReason('')
        router.refresh()
      }
    } finally {
      setSaving(false)
    }
  }

  /** §33 Duplicate: same copy under a new key, saved as its own template. */
  function duplicate() {
    const suggested = `${form.key}_copy`
    const key = window.prompt('Key for the duplicated template (letters, digits, underscores):', suggested)?.trim()
    if (!key) return
    if (!/^[a-z0-9_]{3,80}$/.test(key)) return void toast.error('Use lowercase letters, digits and underscores.')
    if (templates.some((t) => t.key === key)) return void toast.error('That key already exists.')
    setSelectedKey(key)
    setForm({ ...form, key, name: `${form.name} (copy)`, template_id: null, version: 0, updated_at: null, updated_by: null, is_custom: true })
    toast.info('Duplicate loaded — edit and press Save to create it.')
  }

  /** §33 Send test email: rendered with sample data, missing rows omitted. */
  async function sendTest() {
    if (!testTo.trim()) return void toast.error('Enter an address for the test.')
    setTesting(true)
    try {
      const res = await fetch('/api/admin/email-templates/test', {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ key: form.key, subject: form.subject, body: form.body, to: testTo.trim(), footer: form.footer, support_contact: form.support_contact, cta_text: form.cta_text }),
      })
      const json = await res.json()
      if (!res.ok) toast.error(json.error ?? 'Could not send the test')
      else if (json.status === 'sent') toast.success(`Test sent to ${testTo.trim()}`)
      else if (json.status === 'failed') toast.error(`Provider refused the test: ${json.error}`)
      else toast.info('Test recorded — no email provider is configured in this environment.')
    } finally {
      setTesting(false)
    }
  }

  const tplVersions = versions.filter((v) => v.template_id === form.template_id)
  const sample = sampleDataFor(form.key)
  const previewData = { ...sample, company_footer: form.footer || TEMPLATE_SAMPLE_DATA.company_footer, support_email: form.support_contact || TEMPLATE_SAMPLE_DATA.support_email, approve_button: `${form.cta_text || 'Approve request'} → ${sample.approve_link}` }

  return (
    <div className="mx-auto max-w-6xl space-y-6 px-4 py-8">
      <BackLink />
      <div>
        <h1 className="text-2xl font-bold">Email Templates</h1>
        <p className="mt-1 text-sm text-neutral-500">
          System emails for the permit workflows — edit, preview with sample data, and keep
          version history. Sending activates with the email backend.
        </p>
      </div>

      <div className="grid gap-5 lg:grid-cols-[280px_1fr]">
        {/* Template list */}
        <div className="space-y-2">
          {templates.map((t) => (
            <button
              key={t.key}
              onClick={() => selectTemplate(t.key)}
              className={`w-full rounded-xl border p-3 text-left text-sm transition ${
                t.key === selectedKey
                  ? 'border-[#0f1b2d] bg-[#0f1b2d] text-white'
                  : 'bg-white hover:border-neutral-400'
              }`}
            >
              <p className="font-bold">{t.name}</p>
              <p className={`mt-0.5 text-xs ${t.key === selectedKey ? 'text-neutral-300' : 'text-neutral-500'}`}>
                {t.trigger_note}
              </p>
              <p className={`mt-1 text-[11px] ${t.key === selectedKey ? 'text-neutral-400' : 'text-neutral-400'}`}>
                {t.updated_at
                  ? `Last edited ${formatDateTime(t.updated_at)} by ${t.updated_by ?? '—'}`
                  : 'Default (never edited)'}
                {!t.active && ' · INACTIVE'}
                {t.version > 0 && ` · v${t.version}`}
                {t.is_custom && ' · custom'}
                {` · ${t.email_stream === 'updates' ? 'updates@' : 'info@'}`}
              </p>
            </button>
          ))}
          <p className="px-1 text-[11px] leading-relaxed text-neutral-400">
            More templates (reminders, permit-uploaded, route-attached, trip-completed, payment
            notifications) are added as their workflows connect. The Synchron order email address
            is configured with the email backend.
          </p>
          <p className="px-1 text-[11px] leading-relaxed text-neutral-400">
            Pilot invitation emails (initial invitation and follow-up) are managed in the{' '}
            <Link href="/admin/pilot-invitations" className="underline">Pilot Invitation Manager</Link>.
          </p>
        </div>

        {/* Editor + preview */}
        <div className="space-y-5">
          <Card>
            <CardContent className="space-y-4 pt-6">
              <div className="flex items-center justify-between">
                <h3 className="text-sm font-bold uppercase tracking-wide text-neutral-500">
                  Edit template
                </h3>
                <label className="flex cursor-pointer items-center gap-2 text-xs font-semibold">
                  <input
                    type="checkbox"
                    checked={form.active}
                    onChange={(e) => set('active', e.target.checked)}
                    className="h-4 w-4 accent-[#0f1b2d]"
                  />
                  Active
                </label>
              </div>
              <div className="space-y-2">
                <Label htmlFor="tpl_subject">Subject</Label>
                <Input
                  id="tpl_subject"
                  value={form.subject}
                  onChange={(e) => set('subject', e.target.value)}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="tpl_body">Body</Label>
                <Textarea
                  id="tpl_body"
                  rows={16}
                  value={form.body}
                  onChange={(e) => set('body', e.target.value)}
                  className="font-mono text-xs"
                />
              </div>
              <div className="grid gap-4 sm:grid-cols-2">
                <div className="space-y-2">
                  <Label htmlFor="tpl_cc">CC rules</Label>
                  <Input
                    id="tpl_cc"
                    value={form.cc_rules}
                    onChange={(e) => set('cc_rules', e.target.value)}
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="tpl_notes">Internal notes</Label>
                  <Input
                    id="tpl_notes"
                    value={form.internal_notes}
                    onChange={(e) => set('internal_notes', e.target.value)}
                    placeholder="Notes for the team (never sent)"
                  />
                </div>
              </div>
              {/* Stream + category (2026-09-22): the category fixes the stream; marketing can never go through info@. */}
              <div className="grid gap-4 rounded-lg border bg-neutral-50 p-3 sm:grid-cols-3">
                <div className="space-y-1">
                  <Label htmlFor="tpl_category" className="text-xs">Category</Label>
                  <select
                    id="tpl_category"
                    value={form.category_key}
                    onChange={(e) => { const c = EMAIL_CATEGORIES.find((x) => x.key === e.target.value); if (c) setForm((f) => ({ ...f, category_key: c.key, email_stream: c.stream, required: c.required })) }}
                    className="w-full rounded-md border bg-white px-2 py-1.5 text-sm"
                  >
                    <optgroup label="Transactional — info@">{EMAIL_CATEGORIES.filter((c) => c.stream === 'transactional').map((c) => <option key={c.key} value={c.key}>{c.label}</option>)}</optgroup>
                    <optgroup label="Updates — updates@">{EMAIL_CATEGORIES.filter((c) => c.stream === 'updates').map((c) => <option key={c.key} value={c.key}>{c.label}</option>)}</optgroup>
                  </select>
                </div>
                <div className="space-y-1">
                  <p className="text-xs font-medium">Stream · sender</p>
                  <p className="rounded-md border bg-white px-2 py-1.5 text-sm"><span className="font-semibold capitalize">{form.email_stream}</span> · {STREAM_SENDERS[form.email_stream].defaultFrom}</p>
                </div>
                <div className="space-y-1">
                  <p className="text-xs font-medium">Can recipients turn it off?</p>
                  <label className="flex items-center gap-2 rounded-md border bg-white px-2 py-1.5 text-sm">
                    <input type="checkbox" checked={form.required} disabled={form.email_stream === 'updates'} onChange={(e) => set('required', e.target.checked)} className="h-4 w-4" />
                    {form.email_stream === 'updates' ? 'Always optional (unsubscribe added)' : form.required ? 'Required — always sent' : 'Optional — honours preferences'}
                  </label>
                </div>
              </div>
              <div className="grid gap-4 sm:grid-cols-3">
                <div className="space-y-2">
                  <Label htmlFor="tpl_cta">CTA wording</Label>
                  <Input id="tpl_cta" value={form.cta_text} onChange={(e) => set('cta_text', e.target.value)} placeholder="Approve request" />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="tpl_support">Support contact</Label>
                  <Input id="tpl_support" value={form.support_contact} onChange={(e) => set('support_contact', e.target.value)} placeholder="support@heavyhaulagent.com" />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="tpl_footer">Footer</Label>
                  <Input id="tpl_footer" value={form.footer} onChange={(e) => set('footer', e.target.value)} placeholder="Used by {{company_footer}}" />
                </div>
              </div>
              {/* Variable palette */}
              <div>
                <div className="flex items-center gap-2">
                  <p className="text-[11px] font-bold uppercase text-neutral-400">Variables</p>
                  <button type="button" onClick={() => setShowVars((v) => !v)} className="text-[11px] font-semibold text-blue-700 hover:underline">
                    {showVars ? 'hide descriptions' : 'what do they mean?'}
                  </button>
                </div>
                {showVars && (
                  <dl className="mt-1.5 grid gap-x-4 gap-y-0.5 rounded-lg border bg-neutral-50 p-3 text-[11px] sm:grid-cols-2">
                    {TEMPLATE_VARIABLES.filter((v) => TEMPLATE_VARIABLE_DESCRIPTIONS[v]).map((v) => (
                      <div key={v} className="flex gap-2">
                        <dt className="shrink-0 font-mono text-neutral-700">{`{{${v}}}`}</dt>
                        <dd className="text-neutral-500">— {TEMPLATE_VARIABLE_DESCRIPTIONS[v]}</dd>
                      </div>
                    ))}
                  </dl>
                )}
                <div className="mt-1.5 flex flex-wrap gap-1">
                  {TEMPLATE_VARIABLES.map((v) => (
                    <button
                      key={v}
                      type="button"
                      onClick={() => {
                        navigator.clipboard.writeText(`{{${v}}}`)
                        toast.success(`{{${v}}} copied`)
                      }}
                      className="rounded-md bg-neutral-100 px-1.5 py-0.5 font-mono text-[10px] text-neutral-600 hover:bg-neutral-200"
                      title="Click to copy"
                    >
                      {`{{${v}}}`}
                    </button>
                  ))}
                </div>
              </div>
              <div className="flex flex-wrap items-end gap-2 border-t pt-4">
                <div className="min-w-56 flex-1 space-y-1">
                  <Label htmlFor="tpl_reason" className="text-xs">
                    Reason for change (optional)
                  </Label>
                  <Input
                    id="tpl_reason"
                    value={reason}
                    onChange={(e) => setReason(e.target.value)}
                    placeholder="e.g. clarified payment wording"
                  />
                </div>
                <Button onClick={save} disabled={saving}>
                  {saving ? 'Saving…' : 'Save template'}
                </Button>
                <Button variant="outline" onClick={duplicate}>Duplicate</Button>
                <div className="flex items-end gap-2">
                  <div className="space-y-1">
                    <Label htmlFor="tpl_test_to" className="text-xs">Test address</Label>
                    <Input id="tpl_test_to" value={testTo} onChange={(e) => setTestTo(e.target.value)} placeholder="you@company.com" className="w-52" />
                  </div>
                  <Button variant="outline" onClick={sendTest} disabled={testing}>{testing ? 'Sending…' : 'Send test email'}</Button>
                </div>
              </div>
            </CardContent>
          </Card>

          {/* Preview with sample data (doc §16) */}
          <Card>
            <CardContent className="pt-6">
              <h3 className="text-sm font-bold uppercase tracking-wide text-neutral-500">
                Preview <span className="font-normal normal-case text-neutral-400">(sample data)</span>
              </h3>
              <div className="mt-3 rounded-xl border bg-neutral-50 p-4 text-sm">
                <p className="text-xs text-neutral-500">
                  <span className="font-bold">To:</span>{' '}
                  {renderTemplate(form.recipients_note, TEMPLATE_SAMPLE_DATA)}
                </p>
                {form.cc_rules && (
                  <p className="mt-0.5 text-xs text-neutral-500">
                    <span className="font-bold">CC:</span> {form.cc_rules}
                  </p>
                )}
                <p className="mt-2 border-t pt-2 font-bold">
                  {renderTemplateClean(form.subject, previewData)}
                </p>
                <pre className="mt-2 whitespace-pre-wrap font-sans text-xs leading-relaxed text-neutral-700">
                  {renderTemplateClean(form.body, previewData)}
                </pre>
                <p className="mt-2 text-[10px] text-neutral-400">Rows whose variables have no value are omitted from the sent email (never “null” or an empty label).</p>
              </div>
            </CardContent>
          </Card>

          {/* Version history (doc §15) */}
          <Card>
            <CardContent className="pt-6">
              <h3 className="text-sm font-bold uppercase tracking-wide text-neutral-500">
                Version history
              </h3>
              {tplVersions.length === 0 ? (
                <p className="mt-3 rounded-lg border border-dashed p-4 text-xs text-neutral-500">
                  No saved versions yet{form.template_id ? '' : ' (template still on the code default)'}.
                  Every save records a restorable version.
                </p>
              ) : (
                <div className="mt-3 space-y-2">
                  {tplVersions.map((v) => (
                    <div
                      key={v.id}
                      className="flex items-center justify-between rounded-lg border bg-white p-3 text-xs"
                    >
                      <div className="min-w-0">
                        <p className="font-semibold">
                          {v.version ? <span className="mr-1.5 rounded bg-neutral-100 px-1.5 py-0.5 text-[10px]">v{v.version}</span> : null}
                          {formatDateTime(v.created_at)}
                          <span className="ml-1.5 font-normal text-neutral-500">
                            by {v.edited_by ?? '—'}
                          </span>
                          {v.reason && (
                            <span className="ml-1.5 font-normal italic text-neutral-400">
                              — {v.reason}
                            </span>
                          )}
                        </p>
                        <p className="mt-0.5 truncate text-neutral-500">{v.subject}</p>
                      </div>
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => {
                          setForm((f) => ({ ...f, subject: v.subject, body: v.body }))
                          toast.info('Version loaded into the editor — press Save to restore it.')
                        }}
                      >
                        Restore
                      </Button>
                    </div>
                  ))}
                </div>
              )}
              <p className="mt-2 text-[11px] text-neutral-400">
                <Badge variant="outline" className="mr-1 align-middle">§15</Badge>
                Every edit stores the version, editor, time, and reason — a bad edit can be
                restored in one click.
              </p>
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  )
}
