import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Link } from 'react-router-dom'

// ── Constants ────────────────────────────────────────────────────────────────

const REPLY_FROM_OPTIONS = [
  { value: 'Verse by Verse with Nate <hello@versebyversewithnate.us>', label: 'hello@versebyversewithnate.us' },
  { value: 'Verse by Verse with Nate <nate@versebyversewithnate.us>', label: 'nate@versebyversewithnate.us' },
]

// ── Types ────────────────────────────────────────────────────────────────────

interface ContactSubmission {
  id: string
  submittedAt: string
  name: string
  email: string
  message: string
  messageType: 'question' | 'testimony' | 'topic' | 'general'
  subscribe: boolean
  archived?: boolean
  source?: 'contact-form' | 'download' | 'inbound-email'
  inboundTo?: string
  htmlBody?: string | null
  messageId?: string
}

interface ReplyDraft {
  submissionId: string | null
  recipientName: string
  recipientEmail: string
  subject: string
  message: string
  fromAddress: string
}

interface ReplyTemplate {
  id: string
  label: string
  subject: string
  message: string
}

interface ReplyHistoryItem {
  id: string
  submissionId: string
  toEmail: string
  toName: string
  fromEmail: string
  subject: string
  preview: string
  sentAt: string
}

interface ReplyConfig {
  fromEmail: string
  fromIdentity: string
  resendApiConfigured: boolean
  canSendReplies: boolean
  note: string
}

interface EmailSettings {
  signature: string
}

// ── Helpers ──────────────────────────────────────────────────────────────────

function extractSubject(message: string): string {
  const m = /^Subject:\s*(.+)/m.exec(message ?? '')
  return m ? m[1].trim() : ''
}

function extractBodyPreview(message: string): string {
  const afterSubject = message.replace(/^Subject:\s*.+\n+/m, '').trim()
  return afterSubject.slice(0, 200)
}

function formatDate(value: string | null | undefined): string {
  if (!value) return '—'
  const d = new Date(value)
  return Number.isNaN(d.getTime()) ? '—' : d.toLocaleString()
}

function formatShortDate(value: string | null | undefined): string {
  if (!value) return '—'
  const d = new Date(value)
  if (Number.isNaN(d.getTime())) return '—'
  const now = new Date()
  const sameDay = d.toDateString() === now.toDateString()
  if (sameDay) return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
  const sameYear = d.getFullYear() === now.getFullYear()
  if (sameYear) return d.toLocaleDateString([], { month: 'short', day: 'numeric' })
  return d.toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' })
}

function readIds(): Set<string> {
  try { return new Set(JSON.parse(localStorage.getItem('em-read-ids') ?? '[]') as string[]) }
  catch { return new Set() }
}

function persistReadId(id: string) {
  try {
    const next = [...readIds(), id].slice(-1000)
    localStorage.setItem('em-read-ids', JSON.stringify(next))
  } catch {}
}

// ── EmailClient ──────────────────────────────────────────────────────────────

function EmailClient({ onLogout }: { onLogout: () => void }) {
  const [submissions, setSubmissions] = useState<ContactSubmission[]>([])
  const [loadStatus, setLoadStatus] = useState<'loading' | 'ready' | 'error'>('loading')
  const [mailbox, setMailbox] = useState<'inbox' | 'archived'>('inbox')
  const [selectedId, setSelectedId] = useState<string | null>(null)
  const [search, setSearch] = useState('')
  const [localReadIds, setLocalReadIds] = useState<Set<string>>(readIds)
  const [replyDraft, setReplyDraft] = useState<ReplyDraft | null>(null)
  const [replySending, setReplySending] = useState(false)
  const [replyMsg, setReplyMsg] = useState('')
  const [templates, setTemplates] = useState<ReplyTemplate[]>([])
  const [history, setHistory] = useState<ReplyHistoryItem[]>([])
  const [config, setConfig] = useState<ReplyConfig | null>(null)
  const [templateStatus, setTemplateStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle')
  const [showTemplatesMgr, setShowTemplatesMgr] = useState(false)
  const [showHistory, setShowHistory] = useState(false)
  const [showSettings, setShowSettings] = useState(false)
  const [emailSettings, setEmailSettings] = useState<EmailSettings>({ signature: 'Grace and peace,\nVerse by Verse with Nate' })
  const [settingsSig, setSettingsSig] = useState('')
  const [settingsSaving, setSettingsSaving] = useState(false)
  const [settingsSaved, setSettingsSaved] = useState(false)
  const [actionMsg, setActionMsg] = useState('')
  const composeRef = useRef<HTMLTextAreaElement>(null)
  const listRef = useRef<HTMLElement>(null)

  // ── Load ──

  const loadAll = useCallback(async () => {
    try {
      const [subRes, tplRes, histRes, cfgRes, settingsRes] = await Promise.all([
        fetch('/api/admin-contact-submissions'),
        fetch('/api/admin-contact-reply-templates'),
        fetch('/api/admin-contact-reply-history'),
        fetch('/api/admin-reply-config'),
        fetch('/api/admin-email-settings'),
      ])
      if (!subRes.ok) throw new Error('submissions failed')
      const subData = await subRes.json() as { submissions?: ContactSubmission[] }
      setSubmissions(subData.submissions ?? [])
      setLoadStatus('ready')
      if (tplRes.ok) {
        const d = await tplRes.json() as { templates?: ReplyTemplate[] }
        setTemplates(d.templates ?? [])
      }
      if (histRes.ok) {
        const d = await histRes.json() as { items?: ReplyHistoryItem[] }
        setHistory(d.items ?? [])
      }
      if (cfgRes.ok) setConfig(await cfgRes.json() as ReplyConfig)
      if (settingsRes.ok) {
        const s = await settingsRes.json() as EmailSettings
        setEmailSettings(s)
      }
    } catch {
      setLoadStatus('error')
    }
  }, [])

  useEffect(() => { loadAll() }, [loadAll])

  // 30s poll for new messages
  useEffect(() => {
    const id = setInterval(async () => {
      try {
        const r = await fetch('/api/admin-contact-submissions')
        if (!r.ok) return
        const data = await r.json() as { submissions?: ContactSubmission[] }
        const fresh = data.submissions ?? []
        setSubmissions(prev => {
          const freshById = new Map(fresh.map(s => [s.id, s]))
          const existingIds = new Set(prev.map(s => s.id))
          const merged = prev.map(s => freshById.get(s.id) ?? s)
          const newOnes = fresh.filter(s => !existingIds.has(s.id))
          return newOnes.length > 0 ? [...newOnes, ...merged] : merged
        })
      } catch {}
    }, 30_000)
    return () => clearInterval(id)
  }, [])

  // ── Derived ──

  const filtered = useMemo(() => {
    const inMailbox = submissions.filter(s => mailbox === 'archived' ? s.archived === true : s.archived !== true)
    const q = search.trim().toLowerCase()
    if (!q) return inMailbox
    return inMailbox.filter(s => {
      const subj = extractSubject(s.message).toLowerCase()
      return (
        s.name.toLowerCase().includes(q) ||
        s.email.toLowerCase().includes(q) ||
        subj.includes(q) ||
        s.message.toLowerCase().includes(q)
      )
    })
  }, [submissions, mailbox, search])

  const selected = filtered.find(s => s.id === selectedId) ?? null

  const inboxCount = submissions.filter(s => s.archived !== true).length
  const unreadCount = submissions.filter(s => s.archived !== true && !localReadIds.has(s.id)).length

  // Auto-select first on mailbox switch or after actions
  useEffect(() => {
    if (filtered.length === 0) { setSelectedId(null); return }
    if (!selectedId || !filtered.some(s => s.id === selectedId)) {
      setSelectedId(filtered[0].id)
    }
  }, [filtered, selectedId])

  // Mark as read when selected
  useEffect(() => {
    if (!selectedId) return
    if (localReadIds.has(selectedId)) return
    persistReadId(selectedId)
    setLocalReadIds(prev => { const n = new Set(prev); n.add(selectedId); return n })
  }, [selectedId, localReadIds])

  // Auto-scroll selected into view in list
  useEffect(() => {
    if (!selectedId || !listRef.current) return
    const el = listRef.current.querySelector(`[data-id="${selectedId}"]`) as HTMLElement | null
    el?.scrollIntoView({ block: 'nearest' })
  }, [selectedId])

  // Focus compose textarea when reply opens
  useEffect(() => {
    if (replyDraft) setTimeout(() => composeRef.current?.focus(), 50)
  }, [replyDraft])

  // ── Keyboard nav ──

  useEffect(() => {
    function onKey(e: KeyboardEvent) {
      const tag = (e.target as Element).tagName.toLowerCase()
      if (tag === 'input' || tag === 'textarea' || tag === 'select') return
      const idx = filtered.findIndex(s => s.id === selectedId)
      if (e.key === 'ArrowDown' || e.key === 'j') {
        e.preventDefault()
        if (idx < filtered.length - 1) setSelectedId(filtered[idx + 1].id)
      } else if (e.key === 'ArrowUp' || e.key === 'k') {
        e.preventDefault()
        if (idx > 0) setSelectedId(filtered[idx - 1].id)
      } else if (e.key === 'r' && selected && !replyDraft) {
        openReply(selected)
      } else if (e.key === 'Escape' && replyDraft) {
        setReplyDraft(null)
      } else if (e.key === 'e' && selected) {
        handleArchive(selected.id, !(selected.archived === true))
      }
    }
    document.addEventListener('keydown', onKey)
    return () => document.removeEventListener('keydown', onKey)
  }, [filtered, selectedId, selected, replyDraft])

  // ── Actions ──

  async function handleArchive(id: string, archive: boolean) {
    const res = await fetch(`/api/admin-contact-submissions/${encodeURIComponent(id)}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ archived: archive }),
    })
    if (!res.ok) { flash('Failed to update.'); return }
    setSubmissions(prev => prev.map(s => s.id === id ? { ...s, archived: archive } : s))
    flash(archive ? 'Archived.' : 'Moved to inbox.')
  }

  async function handleDelete(id: string) {
    if (!confirm('Delete this message permanently?')) return
    const res = await fetch(`/api/admin-contact-submissions/${encodeURIComponent(id)}`, { method: 'DELETE' })
    if (!res.ok) { flash('Failed to delete.'); return }
    setSubmissions(prev => prev.filter(s => s.id !== id))
    flash('Message deleted.')
  }

  function flash(msg: string) {
    setActionMsg(msg)
    setTimeout(() => setActionMsg(''), 3000)
  }

  function openReply(submission: ContactSubmission) {
    const firstName = submission.name?.trim().split(/\s+/)[0] || 'there'
    const subject = extractSubject(submission.message)
    const inboundTo = submission.inboundTo ?? ''
    const defaultFrom = inboundTo.includes('nate@') ? REPLY_FROM_OPTIONS[1].value : REPLY_FROM_OPTIONS[0].value
    setReplyDraft({
      submissionId: submission.id,
      recipientName: submission.name,
      recipientEmail: submission.email,
      subject: subject ? `Re: ${subject}` : 'Re: Your message',
      message: '',
      fromAddress: defaultFrom,
    })
    setReplyMsg('')
    flash(`Composing reply to ${firstName}…`)
  }

  function openCompose() {
    setSelectedId(null)
    setReplyDraft({
      submissionId: null,
      recipientName: '',
      recipientEmail: '',
      subject: '',
      message: '',
      fromAddress: REPLY_FROM_OPTIONS[0].value,
    })
    setReplyMsg('')
  }

  function applyTemplate(templateId: string) {
    if (!replyDraft) return
    const tpl = templates.find(t => t.id === templateId)
    if (!tpl) return
    setReplyDraft({ ...replyDraft, message: tpl.message })
  }

  async function handleSend() {
    if (!replyDraft) return
    setReplySending(true)
    setReplyMsg('')

    try {
      if (replyDraft.submissionId) {
        // Reply to existing submission
        const res = await fetch(`/api/admin-contact-submissions/${encodeURIComponent(replyDraft.submissionId)}/reply`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            subject: replyDraft.subject,
            message: replyDraft.message,
            fromAddress: replyDraft.fromAddress,
          }),
        })
        if (!res.ok) {
          const d = await res.json().catch(() => ({})) as { message?: string }
          throw new Error(d.message ?? 'Failed to send.')
        }
      } else {
        // Compose new (no existing submission)
        const res = await fetch('/api/admin-email/compose', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            to: replyDraft.recipientEmail,
            toName: replyDraft.recipientName,
            subject: replyDraft.subject,
            message: replyDraft.message,
            fromAddress: replyDraft.fromAddress,
          }),
        })
        if (!res.ok) {
          const d = await res.json().catch(() => ({})) as { message?: string }
          throw new Error(d.message ?? 'Failed to send.')
        }
      }

      const sentFrom = replyDraft.fromAddress.match(/<([^>]+)>/)?.[1] ?? replyDraft.fromAddress
      setReplyMsg(`Sent to ${replyDraft.recipientEmail} from ${sentFrom}.`)
      setReplyDraft(null)

      // Refresh history
      fetch('/api/admin-contact-reply-history')
        .then(r => r.ok ? r.json() : null)
        .then(d => { if (d) setHistory((d as { items?: ReplyHistoryItem[] }).items ?? []) })
        .catch(() => {})
    } catch (err) {
      setReplyMsg(err instanceof Error ? err.message : 'Failed to send.')
    } finally {
      setReplySending(false)
    }
  }

  async function handleSaveTemplates() {
    setTemplateStatus('saving')
    try {
      const res = await fetch('/api/admin-contact-reply-templates', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ templates }),
      })
      if (!res.ok) throw new Error('Failed to save')
      setTemplateStatus('saved')
    } catch {
      setTemplateStatus('error')
    }
  }

  // ── Render ──

  return (
    <div className="em-app">
      {/* Header */}
      <header className="em-header">
        <div className="em-header-left">
          <span className="em-header-brand">✉ Email Center</span>
          {unreadCount > 0 && <span className="em-badge em-badge--alert">{unreadCount} new</span>}
        </div>
        <div className="em-header-actions">
          <button type="button" className="em-btn em-btn--primary" onClick={openCompose}>
            Compose
          </button>
          <Link to="/contacts" className="em-btn em-btn--ghost">Contacts</Link>
          <Link to="/calendar" className="em-btn em-btn--ghost">Calendar</Link>
          <Link to="/admin" className="em-btn em-btn--ghost">← Admin</Link>
          <button type="button" className="em-btn em-btn--ghost" onClick={onLogout}>Log Out</button>
        </div>
      </header>

      {/* Body */}
      <div className="em-body">
        {/* Sidebar */}
        <aside className="em-sidebar">
          {/* Search */}
          <div className="em-search-wrap">
            <input
              className="em-search"
              type="search"
              placeholder="Search…"
              value={search}
              onChange={e => setSearch(e.target.value)}
            />
          </div>

          {/* Mailbox tabs */}
          <div className="em-mailbox-tabs">
            <button
              type="button"
              className={`em-mailbox-tab${mailbox === 'inbox' ? ' em-mailbox-tab--active' : ''}`}
              onClick={() => { setMailbox('inbox'); setSearch('') }}
            >
              Inbox
              {inboxCount > 0 && (
                <span className={`em-tab-badge${unreadCount > 0 ? ' em-tab-badge--unread' : ''}`}>
                  {inboxCount}
                </span>
              )}
            </button>
            <button
              type="button"
              className={`em-mailbox-tab${mailbox === 'archived' ? ' em-mailbox-tab--active' : ''}`}
              onClick={() => { setMailbox('archived'); setSearch('') }}
            >
              Archived
            </button>
          </div>

          {/* List */}
          <section className="em-list" ref={listRef} aria-label="Messages">
            {loadStatus === 'loading' && <p className="em-list-empty">Loading…</p>}
            {loadStatus === 'error' && <p className="em-list-empty">Could not load messages.</p>}
            {loadStatus === 'ready' && filtered.length === 0 && (
              <p className="em-list-empty">{search ? 'No results.' : 'No messages here.'}</p>
            )}
            {filtered.map(item => {
              const subject = item.source === 'inbound-email' ? extractSubject(item.message) : ''
              const preview = item.source === 'inbound-email' ? extractBodyPreview(item.message) : item.message
              const isUnread = !localReadIds.has(item.id)
              return (
                <button
                  key={item.id}
                  data-id={item.id}
                  type="button"
                  className={`em-list-item${selectedId === item.id ? ' em-list-item--active' : ''}${isUnread ? ' em-list-item--unread' : ''}`}
                  onClick={() => setSelectedId(item.id)}
                >
                  {isUnread && <span className="em-unread-dot" aria-label="Unread" />}
                  <div className="em-list-item-head">
                    <strong className="em-list-item-name">{item.name}</strong>
                    <span className="em-list-item-date">{formatShortDate(item.submittedAt)}</span>
                  </div>
                  {subject && <div className="em-list-item-subject">{subject}</div>}
                  <div className="em-list-item-preview">{preview}</div>
                  {item.source === 'inbound-email' && (
                    <span className="em-source-badge em-source-badge--inbound">
                      {item.inboundTo?.includes('nate@') ? 'nate@' : 'hello@'}
                    </span>
                  )}
                </button>
              )
            })}
          </section>
        </aside>

        {/* Detail pane */}
        <main className="em-detail">
          {replyDraft && !replyDraft.submissionId ? (
            /* ── Compose New ── */
            <div className="em-compose-new">
              <div className="em-detail-header">
                <h2 className="em-detail-subject">New Message</h2>
              </div>
              <div className="em-compose-fields">
                <div className="em-compose-row">
                  <label className="em-compose-label">To</label>
                  <input
                    className="em-compose-input"
                    type="email"
                    placeholder="recipient@example.com"
                    value={replyDraft.recipientEmail}
                    onChange={e => setReplyDraft({ ...replyDraft, recipientEmail: e.target.value })}
                  />
                </div>
                <div className="em-compose-row">
                  <label className="em-compose-label">Name</label>
                  <input
                    className="em-compose-input"
                    type="text"
                    placeholder="Recipient name (optional)"
                    value={replyDraft.recipientName}
                    onChange={e => setReplyDraft({ ...replyDraft, recipientName: e.target.value })}
                  />
                </div>
                <div className="em-compose-row">
                  <label className="em-compose-label">From</label>
                  <select
                    className="em-compose-select"
                    value={replyDraft.fromAddress}
                    onChange={e => setReplyDraft({ ...replyDraft, fromAddress: e.target.value })}
                  >
                    {REPLY_FROM_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
                  </select>
                </div>
                <div className="em-compose-row">
                  <label className="em-compose-label">Subject</label>
                  <input
                    className="em-compose-input"
                    type="text"
                    value={replyDraft.subject}
                    onChange={e => setReplyDraft({ ...replyDraft, subject: e.target.value })}
                  />
                </div>
                {templates.length > 0 && (
                  <div className="em-compose-row">
                    <label className="em-compose-label">Template</label>
                    <select className="em-compose-select" defaultValue="" onChange={e => applyTemplate(e.target.value)}>
                      <option value="">Choose a template…</option>
                      {templates.map(t => <option key={t.id} value={t.id}>{t.label}</option>)}
                    </select>
                  </div>
                )}
                <textarea
                  ref={composeRef}
                  className="em-compose-body"
                  rows={12}
                  placeholder="Type your message…"
                  value={replyDraft.message}
                  onChange={e => setReplyDraft({ ...replyDraft, message: e.target.value })}
                />
                <div className="em-compose-signature">
                  <span className="em-compose-signature-text">{emailSettings.signature}</span>
                  <span className="em-compose-signature-note">auto-appended · <button type="button" className="em-sig-edit-link" onClick={() => { setSettingsSig(emailSettings.signature); setShowSettings(true) }}>edit signature</button></span>
                </div>
                <div className="em-compose-actions">
                  <button type="button" className="em-btn em-btn--primary" onClick={handleSend} disabled={replySending}>
                    {replySending ? 'Sending…' : 'Send'}
                  </button>
                  <button type="button" className="em-btn em-btn--ghost" onClick={() => setReplyDraft(null)}>Discard</button>
                </div>
                {replyMsg && <p className="em-status-msg">{replyMsg}</p>}
              </div>
            </div>
          ) : !selected ? (
            /* ── Empty state ── */
            <div className="em-empty-state">
              <div className="em-empty-icon">✉</div>
              <p>Select a message to read it.</p>
              <p className="em-empty-hint">↑ ↓ or j / k to navigate · r to reply · e to archive</p>
            </div>
          ) : (
            /* ── Message detail ── */
            <>
              <div className="em-detail-header">
                <div className="em-detail-meta-row">
                  <div className="em-detail-from">
                    <div className="em-detail-avatar">{(selected.name || '?')[0].toUpperCase()}</div>
                    <div>
                      <div className="em-detail-from-name">{selected.name}</div>
                      <div className="em-detail-from-email">{selected.email}</div>
                    </div>
                  </div>
                  <div className="em-detail-meta-right">
                    <div className="em-detail-date">{formatDate(selected.submittedAt)}</div>
                    {selected.source === 'inbound-email' && selected.inboundTo && (
                      <div className="em-detail-to">to: {selected.inboundTo}</div>
                    )}
                  </div>
                </div>
                <div className="em-detail-subject-row">
                  <h2 className="em-detail-subject">
                    {selected.source === 'inbound-email'
                      ? extractSubject(selected.message) || selected.messageType
                      : selected.messageType}
                  </h2>
                  <div className="em-detail-badges">
                    {selected.source && (
                      <span className={`em-source-badge em-source-badge--${selected.source}`}>
                        {selected.source === 'inbound-email' ? 'email' : selected.source === 'contact-form' ? 'contact form' : selected.source}
                      </span>
                    )}
                    {selected.subscribe && <span className="em-source-badge em-source-badge--subscribed">subscribed</span>}
                  </div>
                </div>
              </div>

              <div className="em-detail-body">
                {selected.htmlBody ? (
                  <iframe
                    srcDoc={selected.htmlBody}
                    sandbox="allow-same-origin"
                    className="em-detail-iframe"
                    onLoad={e => {
                      const f = e.currentTarget
                      const h = f.contentDocument?.documentElement?.scrollHeight
                      if (h) f.style.height = `${h + 24}px`
                    }}
                  />
                ) : (
                  <pre className="em-detail-plain">{
                    selected.source === 'inbound-email'
                      ? selected.message.replace(/^Subject:\s*.+\n+/m, '').trim()
                      : selected.message
                  }</pre>
                )}
              </div>

              <div className="em-detail-footer">
                <div className="em-detail-actions">
                  <button type="button" className="em-btn em-btn--primary" onClick={() => openReply(selected)}>
                    Reply
                  </button>
                  <button
                    type="button"
                    className="em-btn em-btn--secondary"
                    onClick={() => handleArchive(selected.id, !(selected.archived === true))}
                  >
                    {selected.archived ? 'Move to Inbox' : 'Archive'}
                  </button>
                  <button type="button" className="em-btn em-btn--danger" onClick={() => handleDelete(selected.id)}>
                    Delete
                  </button>
                </div>
                {actionMsg && !replyDraft && <p className="em-status-msg">{actionMsg}</p>}
              </div>

              {/* Inline reply composer */}
              {replyDraft && replyDraft.submissionId === selected.id && (
                <div className="em-reply-composer">
                  <div className="em-compose-header">
                    <span className="em-compose-header-label">Reply to {replyDraft.recipientName}</span>
                    <button type="button" className="em-compose-close" onClick={() => setReplyDraft(null)} aria-label="Close">×</button>
                  </div>
                  <div className="em-compose-fields">
                    <div className="em-compose-row em-compose-row--inline">
                      <label className="em-compose-label">From</label>
                      <select
                        className="em-compose-select"
                        value={replyDraft.fromAddress}
                        onChange={e => setReplyDraft({ ...replyDraft, fromAddress: e.target.value })}
                      >
                        {REPLY_FROM_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
                      </select>
                      {templates.length > 0 && (
                        <>
                          <label className="em-compose-label">Template</label>
                          <select className="em-compose-select" defaultValue="" onChange={e => applyTemplate(e.target.value)}>
                            <option value="">Choose…</option>
                            {templates.map(t => <option key={t.id} value={t.id}>{t.label}</option>)}
                          </select>
                        </>
                      )}
                    </div>
                    <div className="em-compose-row">
                      <label className="em-compose-label">Subject</label>
                      <input
                        className="em-compose-input"
                        type="text"
                        value={replyDraft.subject}
                        onChange={e => setReplyDraft({ ...replyDraft, subject: e.target.value })}
                      />
                    </div>
                    <textarea
                      ref={composeRef}
                      className="em-compose-body"
                      rows={7}
                      placeholder="Type your reply…"
                      value={replyDraft.message}
                      onChange={e => setReplyDraft({ ...replyDraft, message: e.target.value })}
                    />
                    <div className="em-compose-signature">
                      Grace and peace, · Verse by Verse with Nate
                      <span className="em-compose-signature-note">auto-appended</span>
                    </div>
                    <div className="em-compose-actions">
                      <button type="button" className="em-btn em-btn--primary" onClick={handleSend} disabled={replySending}>
                        {replySending ? 'Sending…' : 'Send Reply'}
                      </button>
                      <button type="button" className="em-btn em-btn--ghost" onClick={() => setReplyDraft(null)}>Cancel</button>
                      {replyMsg && <span className="em-status-msg em-status-msg--inline">{replyMsg}</span>}
                    </div>
                  </div>
                </div>
              )}
            </>
          )}
        </main>
      </div>

      {/* Templates manager — slide-up drawer */}
      {showTemplatesMgr && (
        <div className="em-drawer-overlay" onClick={e => { if (e.target === e.currentTarget) setShowTemplatesMgr(false) }}>
          <div className="em-drawer">
            <div className="em-drawer-header">
              <h3>Reply Templates</h3>
              <button type="button" className="em-compose-close" onClick={() => setShowTemplatesMgr(false)}>×</button>
            </div>
            <div className="em-drawer-body">
              {templates.length === 0 && <p className="em-list-empty">No templates yet.</p>}
              {templates.map((tpl, i) => (
                <div key={tpl.id} className="em-template-card">
                  <input
                    className="em-compose-input"
                    placeholder="Template label"
                    value={tpl.label}
                    onChange={e => setTemplates(prev => prev.map((t, j) => j === i ? { ...t, label: e.target.value } : t))}
                  />
                  <input
                    className="em-compose-input"
                    placeholder="Subject (optional)"
                    value={tpl.subject}
                    onChange={e => setTemplates(prev => prev.map((t, j) => j === i ? { ...t, subject: e.target.value } : t))}
                  />
                  <textarea
                    className="em-compose-body"
                    rows={4}
                    placeholder="Message body"
                    value={tpl.message}
                    onChange={e => setTemplates(prev => prev.map((t, j) => j === i ? { ...t, message: e.target.value } : t))}
                  />
                  <button
                    type="button"
                    className="em-btn em-btn--danger em-btn--sm"
                    onClick={() => setTemplates(prev => prev.filter((_, j) => j !== i))}
                  >
                    Remove
                  </button>
                </div>
              ))}
              <div className="em-drawer-actions">
                <button
                  type="button"
                  className="em-btn em-btn--ghost"
                  onClick={() => setTemplates(prev => [...prev, { id: Date.now().toString(36), label: '', subject: '', message: '' }])}
                >
                  Add Template
                </button>
                <button type="button" className="em-btn em-btn--primary" onClick={handleSaveTemplates} disabled={templateStatus === 'saving'}>
                  {templateStatus === 'saving' ? 'Saving…' : templateStatus === 'saved' ? 'Saved ✓' : 'Save Templates'}
                </button>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Sent history drawer */}
      {showHistory && (
        <div className="em-drawer-overlay" onClick={e => { if (e.target === e.currentTarget) setShowHistory(false) }}>
          <div className="em-drawer em-drawer--wide">
            <div className="em-drawer-header">
              <h3>Reply History</h3>
              <button type="button" className="em-compose-close" onClick={() => setShowHistory(false)}>×</button>
            </div>
            <div className="em-drawer-body">
              {history.length === 0 ? (
                <p className="em-list-empty">No replies sent yet.</p>
              ) : (
                <div className="em-history-list">
                  {history.map(item => (
                    <div key={item.id} className="em-history-item">
                      <div className="em-history-meta">
                        <span className="em-history-date">{formatDate(item.sentAt)}</span>
                        <span className="em-history-flow">from {item.fromEmail} → {item.toName} ({item.toEmail})</span>
                      </div>
                      <div className="em-history-subject">{item.subject}</div>
                      <div className="em-history-preview">{item.preview}</div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </div>
        </div>
      )}

      {/* Settings drawer */}
      {showSettings && (
        <div className="em-drawer-overlay" onClick={e => { if (e.target === e.currentTarget) setShowSettings(false) }}>
          <div className="em-drawer">
            <div className="em-drawer-header">
              <h3>Email Settings</h3>
              <button type="button" className="em-compose-close" onClick={() => setShowSettings(false)}>×</button>
            </div>
            <div className="em-drawer-body">
              <div className="em-settings-section">
                <label className="em-settings-label">
                  Outgoing Signature
                  <p className="em-settings-note">Appended to every reply and compose email you send.</p>
                  <textarea
                    className="em-compose-body em-settings-sig-textarea"
                    rows={4}
                    value={settingsSig}
                    onChange={e => { setSettingsSig(e.target.value); setSettingsSaved(false) }}
                    placeholder="Grace and peace,&#10;Verse by Verse with Nate"
                  />
                </label>
              </div>
              {config && (
                <div className="em-settings-section">
                  <p className="em-settings-label">
                    Email Configuration
                    <span className={`em-settings-status${config.canSendReplies ? ' em-settings-status--ok' : ' em-settings-status--warn'}`}>
                      {config.canSendReplies ? 'Configured' : 'Not configured'}
                    </span>
                  </p>
                  <p className="em-settings-note">{config.note}</p>
                  {config.fromEmail && <p className="em-settings-note">Reply-to: {config.fromEmail}</p>}
                </div>
              )}
            </div>
            <div className="em-drawer-actions">
              <button
                type="button"
                className="em-btn em-btn--primary"
                disabled={settingsSaving}
                onClick={async () => {
                  setSettingsSaving(true)
                  try {
                    const res = await fetch('/api/admin-email-settings', {
                      method: 'PUT',
                      headers: { 'Content-Type': 'application/json' },
                      body: JSON.stringify({ signature: settingsSig }),
                    })
                    if (res.ok) {
                      const data = await res.json() as { settings?: EmailSettings }
                      if (data.settings) setEmailSettings(data.settings)
                      setSettingsSaved(true)
                    }
                  } catch { /* silent */ }
                  setSettingsSaving(false)
                }}
              >
                {settingsSaving ? 'Saving…' : settingsSaved ? 'Saved ✓' : 'Save Settings'}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Footer toolbar */}
      <div className="em-footer-toolbar">
        {config && !config.canSendReplies && (
          <span className="em-footer-warn">⚠ RESEND_API_KEY not configured — sending is disabled</span>
        )}
        <button type="button" className="em-btn em-btn--ghost em-btn--sm" onClick={() => setShowTemplatesMgr(true)}>
          Templates
        </button>
        <button type="button" className="em-btn em-btn--ghost em-btn--sm" onClick={() => setShowHistory(true)}>
          Sent History
        </button>
        <button type="button" className="em-btn em-btn--ghost em-btn--sm" onClick={() => { setSettingsSig(emailSettings.signature); setShowSettings(true) }}>
          Settings
        </button>
        <span className="em-footer-hint">↑ ↓ navigate · r reply · e archive · Esc close</span>
      </div>
    </div>
  )
}

// ── Auth shell ───────────────────────────────────────────────────────────────

export default function EmailShell() {
  const [authStatus, setAuthStatus] = useState<'checking' | 'authenticated' | 'unauthenticated' | 'misconfigured'>('checking')
  const [password, setPassword] = useState('')
  const [errorMsg, setErrorMsg] = useState('')
  const [submitting, setSubmitting] = useState(false)
  const [totpRequired, setTotpRequired] = useState(false)
  const [pendingToken, setPendingToken] = useState('')
  const [totpCode, setTotpCode] = useState('')

  useEffect(() => {
    fetch('/api/admin-auth/status')
      .then(r => (r.ok ? r.json() : Promise.reject()))
      .then(data => {
        const d = data as { authenticated?: boolean; configured?: boolean }
        if (d.configured === false) { setAuthStatus('misconfigured'); return }
        setAuthStatus(d.authenticated ? 'authenticated' : 'unauthenticated')
      })
      .catch(() => setAuthStatus('unauthenticated'))
  }, [])

  async function handleLogin(e: React.FormEvent) {
    e.preventDefault()
    setSubmitting(true)
    setErrorMsg('')
    try {
      const res = await fetch('/api/admin-auth/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ password }),
      })
      const data = await res.json().catch(() => ({})) as { ok?: boolean; totpRequired?: boolean; pendingToken?: string; message?: string }
      if (!res.ok) { setErrorMsg(data.message ?? 'Login failed.'); setSubmitting(false); return }
      if (data.totpRequired && data.pendingToken) {
        setPendingToken(data.pendingToken); setTotpRequired(true); setPassword(''); setSubmitting(false); return
      }
      setAuthStatus('authenticated'); setPassword('')
    } catch {
      setErrorMsg('Login failed.')
    } finally {
      setSubmitting(false)
    }
  }

  async function handleTotpVerify(e: React.FormEvent) {
    e.preventDefault()
    setSubmitting(true)
    setErrorMsg('')
    try {
      const res = await fetch('/api/admin-auth/totp-verify', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ pendingToken, code: totpCode }),
      })
      if (!res.ok) {
        const d = await res.json().catch(() => ({})) as { message?: string }
        setErrorMsg(d.message ?? 'Invalid code.'); setSubmitting(false); return
      }
      setAuthStatus('authenticated'); setTotpCode('')
    } catch {
      setErrorMsg('Verification failed.')
    } finally {
      setSubmitting(false)
    }
  }

  async function handleLogout() {
    try { await fetch('/api/admin-auth/logout', { method: 'POST' }) } finally {
      setAuthStatus('unauthenticated'); setTotpRequired(false); setPendingToken('')
    }
  }

  if (authStatus === 'authenticated') return <EmailClient onLogout={handleLogout} />

  return (
    <main className="admin-auth-page" aria-label="Email sign in">
      <div className="admin-auth-card">
        <p className="eyebrow">Email Center</p>
        <h1>{authStatus === 'misconfigured' ? 'Not Configured' : 'Sign In'}</h1>
        {authStatus === 'checking' && <p className="admin-auth-note">Checking session…</p>}
        {authStatus === 'misconfigured' && (
          <p className="admin-auth-note">Set the ADMIN_PASSWORD environment variable to enable access.</p>
        )}
        {authStatus === 'unauthenticated' && !totpRequired && (
          <form className="admin-auth-form" onSubmit={handleLogin}>
            <label>Password
              <input type="password" value={password} onChange={e => setPassword(e.target.value)} autoComplete="current-password" required />
            </label>
            {errorMsg && <p className="admin-auth-error">{errorMsg}</p>}
            <button type="submit" className="btn-primary" disabled={submitting}>{submitting ? 'Signing In…' : 'Sign In'}</button>
            <Link to="/" className="btn-secondary">Back to Site</Link>
          </form>
        )}
        {authStatus === 'unauthenticated' && totpRequired && (
          <form className="admin-auth-form" onSubmit={handleTotpVerify}>
            <p className="admin-auth-note">Enter the 6-digit code from your authenticator app.</p>
            <label>Code
              <input type="text" inputMode="numeric" value={totpCode} onChange={e => setTotpCode(e.target.value)} autoComplete="one-time-code" placeholder="000000" autoFocus required />
            </label>
            {errorMsg && <p className="admin-auth-error">{errorMsg}</p>}
            <button type="submit" className="btn-primary" disabled={submitting}>{submitting ? 'Verifying…' : 'Verify'}</button>
            <button type="button" className="btn-secondary" onClick={() => { setTotpRequired(false); setPendingToken(''); setTotpCode(''); setErrorMsg('') }}>Back</button>
          </form>
        )}
      </div>
    </main>
  )
}
