'use client'

import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { CAMPAIGN_STATUS_LABELS, CARRIER_LEAD_TYPES, CARRIER_LEAD_TYPE_LABELS, LEAD_STAGES, LEAD_STAGE_LABELS, dailyAllowance, describeSegment, type SegmentFilters } from '@/lib/domain/broker-leads'
import type { CampaignInput, LeadCampaign, LeadSegment, LeadTemplate, LeadsSettings } from '@/lib/data/broker-leads'
import { BTN, BTN_DANGER, BTN_SOFT, CARD, INPUT, Pill, call, fmtDateTime, reason } from './shared'
import { useLeadKind } from './kind-context'

const STATUS_TONE: Record<string, 'neutral' | 'info' | 'success' | 'warn' | 'danger'> = { draft: 'neutral', running: 'success', paused: 'warn', stopped: 'danger', completed: 'info' }
const DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
const ZONES = ['lead', 'America/New_York', 'America/Chicago', 'America/Denver', 'America/Los_Angeles']

/* ------------------------------------------------------------- list */

export function CampaignsTab({ campaigns, templates, segments, settings, states, me }: { campaigns: LeadCampaign[]; templates: LeadTemplate[]; segments: LeadSegment[]; settings: LeadsSettings; states: string[]; me: { email: string; name: string } }) {
  const cfg = useLeadKind()
  const router = useRouter()
  const [editing, setEditing] = useState<LeadCampaign | 'new' | null>(null)
  const [open, setOpen] = useState<string | null>(null)
  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-center gap-2 text-xs">
        <p className="text-neutral-500">A campaign is a sequence (invitation → reminder → final note), an audience, a schedule and a throttle. Enrol, test, approve; the scheduler does the rest inside business hours.</p>
        <button onClick={() => setEditing('new')} className={`${BTN} ml-auto`}>New campaign</button>
      </div>
      <div className="grid gap-3 lg:grid-cols-2">
        {campaigns.map((c) => {
          const open_ = c.recipients.pending + c.recipients.scheduled
          return (
            <div key={c.id} className={CARD}>
              <div className="flex flex-wrap items-start justify-between gap-2">
                <div>
                  <p className="font-bold">{c.name} <Pill tone={STATUS_TONE[c.status]}>{CAMPAIGN_STATUS_LABELS[c.status]}</Pill></p>
                  <p className="mt-0.5 text-xs text-neutral-500">{c.steps.length} step{c.steps.length === 1 ? '' : 's'} · {c.audience_kind === 'leads' ? `${(c.audience as { lead_ids: string[] }).lead_ids?.length ?? 0} picked leads` : describeSegment(c.audience as SegmentFilters)} · {c.start_date ?? 'no start date'}{c.end_date ? ` → ${c.end_date}` : ''}</p>
                  {c.pause_reason && <p className="mt-1 text-xs text-amber-800">{c.pause_reason}</p>}
                </div>
                <div className="flex gap-1.5"><button onClick={() => setOpen(c.id)} className={BTN_SOFT}>Open</button>{(c.status === 'draft' || c.status === 'paused') && <button onClick={() => setEditing(c)} className={BTN_SOFT}>Edit</button>}</div>
              </div>
              <div className="mt-3 grid grid-cols-4 gap-2 text-center text-xs sm:grid-cols-8">
                {[['Enrolled', c.enrolled_count], ['Waiting', open_], ['Sent', c.sent_count], ['Delivered', c.delivered_count], ['Opened', c.open_count], ['Clicked', c.click_count], ['Signed up', c.signed_up_count], [cfg.kind === 'carrier' ? 'Active' : 'Confirmed', c.conversion_count]].map(([k, v]) => (
                  <div key={String(k)} className="rounded-lg bg-neutral-50 p-1.5"><p className="font-bold">{v}</p><p className="text-[10px] uppercase tracking-wide text-neutral-400">{k}</p></div>
                ))}
              </div>
              <p className="mt-2 text-[11px] text-neutral-500">Today&apos;s allowance {dailyAllowance({ daily_send_limit: c.daily_send_limit, ramp: c.ramp }, c.first_run_date ? Math.max(0, Math.round((Date.parse(new Date().toISOString().slice(0, 10)) - Date.parse(c.first_run_date)) / 86_400_000)) : 0)} · batches of {c.batch_size} · window {DAYS.filter((_, i) => c.send_window.days.includes(i)).join(' ')} {c.send_window.start_hour}:00–{c.send_window.end_hour}:00 {c.send_window.timezone === 'lead' ? 'in the lead’s time zone' : c.send_window.timezone} · {c.last_run_at ? `last run ${fmtDateTime(c.last_run_at)}` : 'never run'}</p>
            </div>
          )
        })}
        {campaigns.length === 0 && <div className={`${CARD} text-sm text-neutral-500 lg:col-span-2`}>No campaigns yet. Start with the recent, domain-matched leads: a 3-step sequence, 50 a day warming up to 300, business hours in the lead&apos;s time zone.</div>}
      </div>
      {editing && <CampaignEditor campaign={editing === 'new' ? null : editing} templates={templates} segments={segments} settings={settings} states={states} onClose={() => setEditing(null)} onSaved={() => { setEditing(null); router.refresh() }} />}
      {open && <CampaignDetail id={open} templates={templates} me={me} onClose={() => setOpen(null)} onChanged={() => router.refresh()} />}
    </div>
  )
}

/* ----------------------------------------------------------- editor */

function CampaignEditor({ campaign, templates, segments, settings, states, onClose, onSaved }: { campaign: LeadCampaign | null; templates: LeadTemplate[]; segments: LeadSegment[]; settings: LeadsSettings; states: string[]; onClose: () => void; onSaved: () => void }) {
  const cfg = useLeadKind()
  const carrier = cfg.kind === 'carrier'
  const active = templates.filter((t) => t.active)
  const [form, setForm] = useState<CampaignInput>(campaign ? {
    name: campaign.name, description: campaign.description, steps: campaign.steps.map((s) => ({ template_key: s.template_key, delay_days: s.delay_days })), audience_kind: campaign.audience_kind, audience: campaign.audience,
    send_window: campaign.send_window, batch_size: campaign.batch_size, ramp: campaign.ramp, frequency_cap_days: campaign.frequency_cap_days, daily_send_limit: campaign.daily_send_limit, start_date: campaign.start_date, end_date: campaign.end_date,
  } : {
    name: '', description: '', steps: [{ template_key: active.find((t) => t.key === cfg.templateKeys.invitation)?.key ?? active[0]?.key ?? '', delay_days: 0 }, { template_key: active.find((t) => t.key === cfg.templateKeys.reminder)?.key ?? '', delay_days: 7 }, { template_key: active.find((t) => t.key === cfg.templateKeys.finalNotice)?.key ?? '', delay_days: 14 }].filter((s) => s.template_key),
    audience_kind: 'segment', audience: carrier ? { stages: ['not_invited'], source_active: true } : { stages: ['not_invited'], mailbox_type: ['person'] }, send_window: settings.default_send_window, batch_size: settings.default_batch_size, ramp: settings.default_ramp,
    frequency_cap_days: settings.default_frequency_cap_days, daily_send_limit: settings.default_daily_limit, start_date: new Date().toISOString().slice(0, 10), end_date: null,
  })
  const [preview, setPreview] = useState<{ matching: number; eligible: number; blocked: Record<string, number> } | null>(null)
  const [busy, setBusy] = useState(false)
  const locked = !!campaign && campaign.status !== 'draft'
  const f = form.audience as SegmentFilters
  const setAud = (patch: Partial<SegmentFilters>) => setForm({ ...form, audience: { ...f, ...patch } })
  const toggleList = (key: 'stages' | 'states' | 'domain_check' | 'mailbox_type' | 'lead_type', v: string) => { const cur = (f[key] as string[] | undefined) ?? []; const next = cur.includes(v) ? cur.filter((x) => x !== v) : [...cur, v]; setAud({ [key]: next.length ? next : undefined } as Partial<SegmentFilters>) }
  useEffect(() => {
    const h = setTimeout(async () => { try { setPreview(await call(`${cfg.apiBase}/campaigns`, { op: 'preview', id: campaign?.id, audience_kind: form.audience_kind, audience: form.audience })) } catch { setPreview(null) } }, 400)
    return () => clearTimeout(h)
  }, [form.audience, form.audience_kind, campaign?.id, cfg.apiBase])
  async function save() {
    setBusy(true)
    try {
      if (campaign) await call(`${cfg.apiBase}/campaigns`, { op: 'update', id: campaign.id, ...form })
      else await call(`${cfg.apiBase}/campaigns`, { op: 'create', ...form })
      toast.success(campaign ? 'Campaign updated.' : 'Campaign created as a draft. Open it to enrol the audience, send a test and start it.')
      onSaved()
    } catch (e) { toast.error(e instanceof Error ? e.message : 'Could not save.') } finally { setBusy(false) }
  }
  return (
    <Dialog open onOpenChange={(o) => !o && onClose()}>
      <DialogContent className="max-h-[92vh] overflow-y-auto sm:max-w-3xl">
        <DialogHeader><DialogTitle>{campaign ? `Edit ${campaign.name}` : 'New campaign'}</DialogTitle><DialogDescription>{locked ? 'People are already enrolled: the sequence and audience are fixed; schedule and throttle can still change.' : 'Who, what, when, how many.'}</DialogDescription></DialogHeader>
        <div className="space-y-4 text-sm">
          <div className="grid gap-2 sm:grid-cols-2">
            <label className="text-xs font-semibold text-neutral-600">Name<input className={`${INPUT} mt-1 block w-full`} value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="Wave 1 — recent, domain-matched" /></label>
            <label className="text-xs font-semibold text-neutral-600">Notes<input className={`${INPUT} mt-1 block w-full`} value={form.description ?? ''} onChange={(e) => setForm({ ...form, description: e.target.value })} placeholder="optional" /></label>
          </div>

          <section className={CARD}>
            <p className="text-xs font-bold uppercase tracking-wide text-neutral-400">Sequence</p>
            <p className="mt-1 text-xs text-neutral-500">Each step stops automatically once the lead signs up, confirms, clicks through and converts, unsubscribes or bounces.</p>
            {form.steps.map((s, i) => (
              <div key={i} className="mt-2 flex flex-wrap items-center gap-2 text-xs">
                <span className="w-14 font-semibold">Step {i + 1}</span>
                <select disabled={locked} className={INPUT} value={s.template_key} onChange={(e) => setForm({ ...form, steps: form.steps.map((x, j) => (j === i ? { ...x, template_key: e.target.value } : x)) })}>{active.map((t) => <option key={t.key} value={t.key}>{t.name}</option>)}</select>
                {i > 0 && <span>after <input disabled={locked} type="number" min={0} max={120} className={`${INPUT} w-16`} value={s.delay_days} onChange={(e) => setForm({ ...form, steps: form.steps.map((x, j) => (j === i ? { ...x, delay_days: Number(e.target.value) } : x)) })} /> days</span>}
                {!locked && form.steps.length > 1 && <button onClick={() => setForm({ ...form, steps: form.steps.filter((_, j) => j !== i) })} className={BTN_SOFT}>Remove</button>}
              </div>
            ))}
            {!locked && form.steps.length < 6 && <button onClick={() => setForm({ ...form, steps: [...form.steps, { template_key: active[0]?.key ?? '', delay_days: 7 }] })} className={`${BTN_SOFT} mt-2`}>Add step</button>}
          </section>

          <section className={CARD}>
            <p className="text-xs font-bold uppercase tracking-wide text-neutral-400">Audience</p>
            {form.audience_kind === 'leads' ? <p className="mt-1 text-xs">{(form.audience as { lead_ids: string[] }).lead_ids?.length ?? 0} hand-picked leads.</p> : (
              <>
                <div className="mt-2 flex flex-wrap gap-2 text-xs">
                  <select disabled={locked} className={INPUT} value="" onChange={(e) => { const s = segments.find((x) => x.id === e.target.value); if (s) setForm({ ...form, audience: s.filters }) }}><option value="">Load a saved segment…</option>{segments.map((s) => <option key={s.id} value={s.id}>{s.name}</option>)}</select>
                  <input disabled={locked} className={`${INPUT} w-48`} placeholder="search words" value={f.q ?? ''} onChange={(e) => setAud({ q: e.target.value || undefined })} />
                  {!carrier && <label className="flex items-center gap-1">Active since <input disabled={locked} type="date" className={INPUT} value={f.last_seen_after ?? ''} onChange={(e) => setAud({ last_seen_after: e.target.value || undefined })} /></label>}
                  {carrier ? <label className="flex items-center gap-1"><input disabled={locked} type="checkbox" checked={!!f.source_active} onChange={(e) => setAud({ source_active: e.target.checked || undefined })} /> still active in Synchron</label> : <label className="flex items-center gap-1"><input disabled={locked} type="checkbox" checked={!!f.has_last_name} onChange={(e) => setAud({ has_last_name: e.target.checked || undefined })} /> has last name</label>}
                  <label className="flex items-center gap-1"><input disabled={locked} type="checkbox" checked={!!f.never_emailed} onChange={(e) => setAud({ never_emailed: e.target.checked || undefined })} /> never emailed</label>
                </div>
                <div className="mt-2 flex flex-wrap gap-1.5 text-[11px]">
                  {LEAD_STAGES.filter((s) => ['not_invited', 'invited', 'opened', 'clicked'].includes(s)).map((s) => <button key={s} disabled={locked} onClick={() => toggleList('stages', s)} className={`rounded-full border px-2 py-0.5 font-semibold ${f.stages?.includes(s) ? 'border-[#0f1b2d] bg-[#0f1b2d] text-white' : 'bg-white text-neutral-600'}`}>{LEAD_STAGE_LABELS[s]}</button>)}
                  {carrier && CARRIER_LEAD_TYPES.map((t) => <button key={t} disabled={locked} onClick={() => toggleList('lead_type', t)} className={`rounded-full border px-2 py-0.5 font-semibold ${f.lead_type?.includes(t) ? 'border-[#0f1b2d] bg-[#0f1b2d] text-white' : 'bg-white text-neutral-600'}`}>{CARRIER_LEAD_TYPE_LABELS[t].toLowerCase()}</button>)}
                  {!carrier && (['matches_brokerage', 'differs_from_brokerage', 'brokerage_email_unknown'] as const).map((d) => <button key={d} disabled={locked} onClick={() => toggleList('domain_check', d)} className={`rounded-full border px-2 py-0.5 font-semibold ${f.domain_check?.includes(d) ? 'border-[#0f1b2d] bg-[#0f1b2d] text-white' : 'bg-white text-neutral-600'}`}>{{ matches_brokerage: 'email matches brokerage', differs_from_brokerage: 'email differs', brokerage_email_unknown: 'brokerage email unknown' }[d]}</button>)}
                  {!carrier && (['person', 'role'] as const).map((m) => <button key={m} disabled={locked} onClick={() => toggleList('mailbox_type', m)} className={`rounded-full border px-2 py-0.5 font-semibold ${f.mailbox_type?.includes(m) ? 'border-[#0f1b2d] bg-[#0f1b2d] text-white' : 'bg-white text-neutral-600'}`}>{m === 'person' ? 'people' : 'role mailboxes'}</button>)}
                  {!carrier && <select disabled={locked} className={`${INPUT} py-0.5`} value="" onChange={(e) => e.target.value && toggleList('states', e.target.value)}><option value="">+ state</option>{states.map((s) => <option key={s} value={s}>{s}</option>)}</select>}
                  {(f.states ?? []).map((s) => <button key={s} disabled={locked} onClick={() => toggleList('states', s)} className="rounded-full border border-[#0f1b2d] bg-[#0f1b2d] px-2 py-0.5 font-semibold text-white">{s} ×</button>)}
                  <input disabled={locked} className={`${INPUT} w-40 py-0.5`} placeholder="tags, comma separated" value={(f.tags ?? []).join(', ')} onChange={(e) => setAud({ tags: e.target.value.split(',').map((t) => t.trim()).filter(Boolean) })} />
                </div>
                <p className="mt-2 text-xs text-neutral-600">{describeSegment(f)}</p>
              </>
            )}
            <p className="mt-2 text-xs font-semibold">{preview ? <>{preview.matching} match · <span className="text-green-700">{preview.eligible} can be emailed</span>{Object.keys(preview.blocked).length ? <span className="text-neutral-500"> · excluded: {Object.entries(preview.blocked).map(([k, v]) => `${v} ${reason(k)}`).join(', ')}</span> : null}</> : 'Counting…'}</p>
          </section>

          <section className={CARD}>
            <p className="text-xs font-bold uppercase tracking-wide text-neutral-400">Schedule &amp; throttle</p>
            <div className="mt-2 grid gap-3 text-xs sm:grid-cols-3">
              <label className="font-semibold text-neutral-600">Start date<input type="date" className={`${INPUT} mt-1 block w-full`} value={form.start_date ?? ''} onChange={(e) => setForm({ ...form, start_date: e.target.value || null })} /></label>
              <label className="font-semibold text-neutral-600">End date (optional)<input type="date" className={`${INPUT} mt-1 block w-full`} value={form.end_date ?? ''} onChange={(e) => setForm({ ...form, end_date: e.target.value || null })} /></label>
              <label className="font-semibold text-neutral-600">Daily limit<input type="number" min={1} max={5000} className={`${INPUT} mt-1 block w-full`} value={form.daily_send_limit} onChange={(e) => setForm({ ...form, daily_send_limit: Number(e.target.value) })} /></label>
              <label className="font-semibold text-neutral-600">Batch per run (hourly)<input type="number" min={1} max={500} className={`${INPUT} mt-1 block w-full`} value={form.batch_size} onChange={(e) => setForm({ ...form, batch_size: Number(e.target.value) })} /></label>
              <label className="font-semibold text-neutral-600">Frequency cap (days between emails to one lead, across campaigns)<input type="number" min={0} max={90} className={`${INPUT} mt-1 block w-full`} value={form.frequency_cap_days} onChange={(e) => setForm({ ...form, frequency_cap_days: Number(e.target.value) })} /></label>
              <div className="font-semibold text-neutral-600">Warm-up ramp
                <div className="mt-1 flex items-center gap-1"><label className="flex items-center gap-1 font-normal"><input type="checkbox" checked={!!form.ramp} onChange={(e) => setForm({ ...form, ramp: e.target.checked ? settings.default_ramp ?? { start: 50, step: 50, max: 300 } : null })} /> on</label>
                  {form.ramp && <>start <input type="number" min={1} className={`${INPUT} w-16`} value={form.ramp.start} onChange={(e) => setForm({ ...form, ramp: { ...form.ramp!, start: Number(e.target.value) } })} /> +<input type="number" min={0} className={`${INPUT} w-14`} value={form.ramp.step} onChange={(e) => setForm({ ...form, ramp: { ...form.ramp!, step: Number(e.target.value) } })} />/day to <input type="number" min={1} className={`${INPUT} w-16`} value={form.ramp.max} onChange={(e) => setForm({ ...form, ramp: { ...form.ramp!, max: Number(e.target.value) } })} /></>}
                </div>
              </div>
            </div>
            <div className="mt-3 flex flex-wrap items-center gap-2 text-xs">
              <span className="font-semibold text-neutral-600">Send window</span>
              {DAYS.map((d, i) => <button key={d} onClick={() => { const days = form.send_window.days ?? []; const next = days.includes(i) ? days.filter((x) => x !== i) : [...days, i]; setForm({ ...form, send_window: { ...form.send_window, days: next.length ? next : days } }) }} className={`rounded-full border px-2 py-0.5 font-semibold ${form.send_window.days?.includes(i) ? 'border-[#0f1b2d] bg-[#0f1b2d] text-white' : 'bg-white text-neutral-600'}`}>{d}</button>)}
              <input type="number" min={0} max={23} className={`${INPUT} w-16`} value={form.send_window.start_hour} onChange={(e) => setForm({ ...form, send_window: { ...form.send_window, start_hour: Number(e.target.value) } })} />:00 to <input type="number" min={1} max={24} className={`${INPUT} w-16`} value={form.send_window.end_hour} onChange={(e) => setForm({ ...form, send_window: { ...form.send_window, end_hour: Number(e.target.value) } })} />:00
              <select className={INPUT} value={form.send_window.timezone ?? 'lead'} onChange={(e) => setForm({ ...form, send_window: { ...form.send_window, timezone: e.target.value } })}>{ZONES.map((z) => <option key={z} value={z}>{z === 'lead' ? "in the lead's time zone (by state)" : z}</option>)}</select>
            </div>
          </section>
        </div>
        <DialogFooter><button onClick={onClose} className={BTN_SOFT}>Cancel</button><button onClick={save} disabled={busy || !form.name.trim() || form.steps.length === 0} className={BTN}>{busy ? 'Saving…' : campaign ? 'Save changes' : 'Create draft'}</button></DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

/* ----------------------------------------------------------- detail */

function CampaignDetail({ id, templates, me, onClose, onChanged }: { id: string; templates: LeadTemplate[]; me: { email: string; name: string }; onClose: () => void; onChanged: () => void }) {
  const cfg = useLeadKind()
  const [d, setD] = useState<{ campaign: LeadCampaign; problems: string[] } | null>(null)
  const [busy, setBusy] = useState(false)
  const [testTo, setTestTo] = useState(me.email)
  const load = () => fetch(`${cfg.apiBase}/campaigns?id=${id}`).then((r) => (r.ok ? r.json() : null)).then((j) => { if (j) setD(j) })
  useEffect(() => { let on = true; fetch(`${cfg.apiBase}/campaigns?id=${id}`).then((r) => (r.ok ? r.json() : null)).then((j) => { if (on && j) setD(j) }); return () => { on = false } }, [id, cfg.apiBase])
  const act = async (body: Record<string, unknown>, msg: (r: Record<string, unknown>) => string) => {
    setBusy(true)
    try { const r = await call(`${cfg.apiBase}/campaigns`, body); toast.success(msg(r)); await load(); onChanged() } catch (e) { toast.error(e instanceof Error ? e.message : 'Failed.') } finally { setBusy(false) }
  }
  const c = d?.campaign
  return (
    <Dialog open onOpenChange={(o) => !o && onClose()}>
      <DialogContent className="max-h-[92vh] overflow-y-auto sm:max-w-2xl">
        {!c ? <p className="text-sm text-neutral-500">Loading…</p> : (
          <>
            <DialogHeader><DialogTitle className="flex items-center gap-2">{c.name} <Pill tone={STATUS_TONE[c.status]}>{CAMPAIGN_STATUS_LABELS[c.status]}</Pill></DialogTitle><DialogDescription>{c.description || describeSegment(c.audience as SegmentFilters)}{c.approved_by ? ` · started by ${c.approved_by} ${fmtDateTime(c.approved_at)}` : ''}</DialogDescription></DialogHeader>
            <div className="grid grid-cols-3 gap-2 text-center text-xs sm:grid-cols-6">
              {[['Enrolled', c.enrolled_count], ['Pending', c.recipients.pending], ['Scheduled', c.recipients.scheduled], ['Done', c.recipients.done], ['Converted', c.recipients.converted], ['Stopped', c.recipients.stopped], ['Skipped', c.recipients.skipped], ['Sent', c.sent_count], ['Delivered', c.delivered_count], ['Opened', c.open_count], ['Clicked', c.click_count], ['Bounced', c.bounce_count]].map(([k, v]) => (
                <div key={String(k)} className="rounded-lg bg-neutral-50 p-1.5"><p className="font-bold">{v}</p><p className="text-[10px] uppercase tracking-wide text-neutral-400">{k}</p></div>
              ))}
            </div>
            <div className={`${CARD} text-xs`}>
              <p className="font-bold uppercase tracking-wide text-neutral-400">Sequence</p>
              {c.steps.map((s) => <p key={s.step} className="mt-1">Step {s.step}: <span className="font-semibold">{templates.find((t) => t.key === s.template_key)?.name ?? s.template_key}</span>{s.step > 1 ? ` — ${s.delay_days} days after the previous step` : ''}</p>)}
              <p className="mt-2 text-neutral-500">Daily limit {c.daily_send_limit}{c.ramp ? ` (warm-up ${c.ramp.start} +${c.ramp.step}/day to ${c.ramp.max})` : ''} · batches of {c.batch_size} per hourly run · one email per lead every {c.frequency_cap_days} days · {DAYS.filter((_, i) => c.send_window.days.includes(i)).join(' ')} {c.send_window.start_hour}:00–{c.send_window.end_hour}:00 {c.send_window.timezone === 'lead' ? 'lead time zone' : c.send_window.timezone}</p>
              {c.last_run_summary && <p className="mt-1 text-neutral-500">Last run {fmtDateTime(c.last_run_at)}: {String(c.last_run_summary.sent ?? 0)} sent, {String(c.last_run_summary.rescheduled ?? 0)} waiting for a window, {String(c.last_run_summary.stopped ?? 0)} stopped, {String(c.last_run_summary.skipped ?? 0)} skipped{Number(c.last_run_summary.failed ?? 0) ? `, ${String(c.last_run_summary.failed)} failed` : ''}.</p>}
            </div>
            {d!.problems.length > 0 && c.status === 'draft' && <ul className="rounded-lg bg-amber-50 p-3 text-xs text-amber-900">{d!.problems.map((p) => <li key={p}>• {p}</li>)}</ul>}
            <div className="flex flex-wrap items-center gap-2 text-xs">
              {(c.status === 'draft' || c.status === 'paused' || c.status === 'running') && <button disabled={busy} onClick={() => act({ op: 'enroll', id }, (r) => `${r.added} added (${r.enrolled} enrolled of ${r.matching} matching).`)} className={BTN_SOFT}>{c.enrolled_count ? 'Enrol new matches' : 'Enrol audience'}</button>}
              <span className="flex items-center gap-1"><input className={`${INPUT} w-52`} value={testTo} onChange={(e) => setTestTo(e.target.value)} placeholder="test address" /><button disabled={busy || !c.steps[0]} onClick={() => act({ op: 'test_send', id, template_key: c.steps[0].template_key, to: testTo }, () => `Test sent to ${testTo}.`)} className={BTN_SOFT}>Send test (step 1)</button></span>
              {(c.status === 'draft' || c.status === 'paused') && <button disabled={busy || (c.status === 'draft' && d!.problems.length > 0)} onClick={() => act({ op: c.status === 'draft' ? 'approve' : 'resume', id }, () => 'Campaign running. It sends on the next scheduler pass, inside its window.')} className={BTN}>{c.status === 'draft' ? 'Approve & start' : 'Resume'}</button>}
              {c.status === 'running' && <button disabled={busy} onClick={() => act({ op: 'pause', id }, () => 'Paused.')} className={BTN_SOFT}>Pause</button>}
              {(c.status === 'running' || c.status === 'paused') && <button disabled={busy} onClick={() => { if (confirm('Stop this campaign for good? Waiting recipients are released; nothing more is sent.')) void act({ op: 'stop', id }, () => 'Stopped.') }} className={BTN_DANGER}>Stop</button>}
              {c.status === 'draft' && <button disabled={busy} onClick={() => { if (confirm('Delete this draft?')) void act({ op: 'delete', id }, () => 'Deleted.').then(onClose) }} className={BTN_DANGER}>Delete draft</button>}
              <button disabled={busy} onClick={() => act({ op: 'duplicate', id }, () => 'Copied as a new draft.')} className={`${BTN_SOFT} ml-auto`}>Duplicate</button>
            </div>
          </>
        )}
      </DialogContent>
    </Dialog>
  )
}
