import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import type { SiteContent, CustomLink, CustomBlock, ArchivedSeries, ArchivedSeriesResourceLink, ArchivedSeriesNote } from './App'
import { DEFAULTS } from './App'

interface Props {
  content: SiteContent
  onSave: (c: SiteContent) => void
  onLogout: () => void | Promise<void>
}

interface BackupPreview {
  filename: string
  sizeBytes: number
  createdAt: string | null
  reason: string
  adminUpdatedAt: string | null
  totalHits: number
  totalVisits: number
}

interface AdminStats {
  totalHits: number
  firstHitAt: string | null
  lastHitAt: string | null
  topPaths: Array<{ path: string; hits: number }>
  last7Days: Array<{ day: string; hits: number }>
  last30DaysTotal: number
  visitors: {
    totalVisits: number
    uniqueVisitors: number
    returningVisits: number
    firstVisitAt: string | null
    lastVisitAt: string | null
    topCountries: Array<{ name: string; hits: number }>
    topStates: Array<{ name: string; hits: number }>
    topCounties: Array<{ name: string; hits: number }>
    topCities: Array<{ name: string; hits: number }>
    recentVisits: Array<{
      at: string
      visitorId: string
      ip: string
      path: string
      country: string
      state: string
      county: string
      city: string
      returningVisitor: boolean
      visitCount: number
    }>
  }
  writeStatus: {
    hitStats: { ok: boolean; at: string | null; error: string | null }
    visitorStats: { ok: boolean; at: string | null; error: string | null }
    backups: { ok: boolean; at: string | null; error: string | null; file: string | null }
  }
  contactTotals: {
    totalSubmissions: number
    totalQuestions: number
  }
}

interface Question {
  id: string
  submittedAt: string
  firstName: string
  email: string
  question: string
  answer: string
  answeredAt: string | null
  isApproved: boolean
  approvedAt: string | null
}
type StringField = Exclude<keyof SiteContent, 'customLinks' | 'customBlocks' | 'archivedSeries'>

const FIELDS: { key: StringField; label: string; multiline?: boolean }[] = [
  { key: 'eyebrow', label: 'Hero Eyebrow Text' },
  { key: 'heroTagline', label: 'Hero Tagline' },
  { key: 'aboutShowHeading', label: 'About Show — Heading' },
  { key: 'aboutShowP1', label: 'About Show — Paragraph 1', multiline: true },
  { key: 'aboutShowP2', label: 'About Show — Paragraph 2', multiline: true },
  { key: 'aboutNate', label: 'About Nate', multiline: true },
  { key: 'seriesLabel', label: 'Series Label (e.g. "Now Playing")' },
  { key: 'seriesTitle', label: 'Series Title' },
  { key: 'seriesDescription', label: 'Series Description', multiline: true },
  { key: 'seriesImageUrl', label: 'Series Cover Image URL' },
  { key: 'seriesListenUrl', label: 'Series Listen URL' },
  { key: 'studyGuideTitle', label: 'Study Guide Title' },
  { key: 'studyGuideDescription', label: 'Study Guide Description', multiline: true },
  { key: 'studyGuideUrl', label: 'Study Guide URL (Amazon link)' },
  { key: 'shareHeading', label: 'Share Section — Heading' },
  { key: 'shareP', label: 'Share Section — Paragraph', multiline: true },
]

export default function AdminPage({ content, onSave, onLogout }: Props) {
  const [form, setForm] = useState<SiteContent>(content)
  const [status, setStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle')
  const [errorMsg, setErrorMsg] = useState('')
  const [adminTab, setAdminTab] = useState<'content' | 'stats' | 'questions'>('content')
  const [contentTab, setContentTab] = useState<'main' | 'custom'>('main')
  const [stats, setStats] = useState<AdminStats | null>(null)
  const [statsStatus, setStatsStatus] = useState<'loading' | 'ready' | 'error'>('loading')
  const [maintenanceMsg, setMaintenanceMsg] = useState('')
  const [backupFiles, setBackupFiles] = useState<BackupPreview[]>([])
  const [selectedBackup, setSelectedBackup] = useState('')
  const [selectedBackupPreview, setSelectedBackupPreview] = useState<BackupPreview | null>(null)

  const [questions, setQuestions] = useState<Question[]>([])
  const [answeredQuestions, setAnsweredQuestions] = useState<{ [key: string]: string }>({})
  const [editingQuestionId, setEditingQuestionId] = useState<string | null>(null)
  const [archiveLinkSelectionBySeries, setArchiveLinkSelectionBySeries] = useState<{ [key: string]: string }>({})

  useEffect(() => {
    fetch('/api/admin-stats')
      .then(r => (r.ok ? r.json() : Promise.reject(new Error('Failed to load stats'))))
      .then(data => {
        setStats(data as AdminStats)
        setStatsStatus('ready')
      })
      .catch(() => {
        setStatsStatus('error')
      })

    fetch('/api/admin-questions')
      .then(r => (r.ok ? r.json() : Promise.reject(new Error('Failed to load questions'))))
      .then(data => {
        setQuestions((data as { questions: Question[] }).questions ?? [])
      })
      .catch(() => {})
    fetch('/api/admin-stats/backups')
      .then(r => (r.ok ? r.json() : Promise.reject(new Error('Failed to load backups'))))
      .then(data => {
        const files = Array.isArray((data as { backups?: unknown }).backups) ? (data as { backups: BackupPreview[] }).backups : []
        setBackupFiles(files)
        if (files.length > 0) {
          setSelectedBackup(files[0].filename)
        }
      })
      .catch(() => {})
  }, [])

  useEffect(() => {
    if (!selectedBackup) {
      setSelectedBackupPreview(null)
      return
    }

    fetch('/api/admin-stats/backup-preview', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ filename: selectedBackup }),
    })
      .then(r => (r.ok ? r.json() : Promise.reject(new Error('Preview failed'))))
      .then(data => {
        const preview = (data as { preview?: BackupPreview }).preview ?? null
        setSelectedBackupPreview(preview)
      })
      .catch(() => {
        setSelectedBackupPreview(null)
      })
  }, [selectedBackup])

  async function reloadStats() {
    const r = await fetch('/api/admin-stats')
    if (!r.ok) throw new Error('Could not refresh stats')
    const data = await r.json()
    setStats(data as AdminStats)
    setStatsStatus('ready')
  }

  async function reloadBackups() {
    const r = await fetch('/api/admin-stats/backups')
    if (!r.ok) throw new Error('Could not refresh backups')
    const data = await r.json() as { backups?: BackupPreview[] }
    const files = Array.isArray(data.backups) ? data.backups : []
    setBackupFiles(files)
    const names = files.map(f => f.filename)
    if (files.length > 0 && !names.includes(selectedBackup)) {
      setSelectedBackup(files[0].filename)
    }
  }

  async function reloadContentFromServer() {
    const r = await fetch('/api/admin-content')
    if (!r.ok) return
    const data = await r.json() as { siteContent?: Partial<SiteContent> }
    if (data?.siteContent && typeof data.siteContent === 'object') {
      const next = { ...DEFAULTS, ...data.siteContent }
      setForm(next)
      onSave(next)
    }
  }

  function maskIp(ip: string) {
    if (!ip || ip === 'unknown') return 'unknown'
    if (ip.includes('.')) {
      const parts = ip.split('.')
      if (parts.length === 4) return `${parts[0]}.${parts[1]}.x.x`
    }
    if (ip.includes(':')) {
      const parts = ip.split(':')
      return `${parts.slice(0, 3).join(':')}:x:x`
    }
    return ip
  }

  async function handleExport() {
    try {
      const r = await fetch('/api/admin-stats/export')
      if (!r.ok) throw new Error('Export failed')
      const data = await r.json()
      const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
      const url = URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = `siteforge-admin-export-${new Date().toISOString().slice(0, 10)}.json`
      a.click()
      URL.revokeObjectURL(url)
      setMaintenanceMsg('Export downloaded.')
    } catch {
      setMaintenanceMsg('Export failed.')
    }
  }

  async function handlePrune() {
    const input = prompt('Keep how many days of analytics data?', '180')
    if (input === null) return
    const days = Number(input)
    if (!Number.isFinite(days) || days <= 0) {
      setMaintenanceMsg('Invalid retention days.')
      return
    }
    try {
      const r = await fetch('/api/admin-stats/prune', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ days }),
      })
      if (!r.ok) throw new Error('Prune failed')
      await reloadStats()
      setMaintenanceMsg(`Pruned analytics to ${Math.floor(days)} days.`)
    } catch {
      setMaintenanceMsg('Prune failed.')
    }
  }

  async function handleClear() {
    if (!confirm('Clear ALL analytics data now? This cannot be undone.')) return
    try {
      const r = await fetch('/api/admin-stats/clear', { method: 'POST' })
      if (!r.ok) throw new Error('Clear failed')
      await reloadStats()
      setMaintenanceMsg('All analytics data cleared.')
    } catch {
      setMaintenanceMsg('Clear failed.')
    }
  }

  async function handleBackupNow() {
    try {
      const r = await fetch('/api/admin-stats/backup', { method: 'POST' })
      if (!r.ok) throw new Error('Backup failed')
      await reloadStats()
      await reloadBackups()
      setMaintenanceMsg('Backup snapshot created.')
    } catch {
      setMaintenanceMsg('Backup failed.')
    }
  }

  async function handleRestoreBackup() {
    if (!selectedBackup) {
      setMaintenanceMsg('Select a backup first.')
      return
    }
    if (!confirm(`Restore backup ${selectedBackup}? This will overwrite current admin data and analytics.`)) return
    try {
      const r = await fetch('/api/admin-stats/restore', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ filename: selectedBackup }),
      })
      if (!r.ok) throw new Error('Restore failed')
      await reloadContentFromServer()
      await reloadStats()
      await reloadBackups()
      setMaintenanceMsg(`Restored from ${selectedBackup}. Content fields were refreshed from backup.`)
    } catch {
      setMaintenanceMsg('Restore failed.')
    }
  }

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

  function handleChange(key: StringField, value: string) {
    setForm(f => ({ ...f, [key]: value }))
  }

  function addLink() {
    setForm(f => ({
      ...f,
      customLinks: [
        ...(f.customLinks ?? []),
        { id: Date.now().toString(36), label: '', url: '', placement: 'platforms' as const },
      ],
    }))
  }

  function updateLink(id: string, field: keyof CustomLink, value: string) {
    setForm(f => ({
      ...f,
      customLinks: (f.customLinks ?? []).map(l => l.id === id ? { ...l, [field]: value } : l),
    }))
  }

  function removeLink(id: string) {
    setForm(f => ({ ...f, customLinks: (f.customLinks ?? []).filter(l => l.id !== id) }))
  }

  function addBlock() {
    setForm(f => ({
      ...f,
      customBlocks: [
        ...(f.customBlocks ?? []),
        { id: Date.now().toString(36), heading: '', body: '' },
      ],
    }))
  }

  function updateBlock(id: string, field: keyof CustomBlock, value: string) {
    setForm(f => ({
      ...f,
      customBlocks: (f.customBlocks ?? []).map(b => b.id === id ? { ...b, [field]: value } : b),
    }))
  }

  function removeBlock(id: string) {
    setForm(f => ({ ...f, customBlocks: (f.customBlocks ?? []).filter(b => b.id !== id) }))
  }

  function addArchivedSeries() {
    setForm(f => ({
      ...f,
      archivedSeries: [
        ...(f.archivedSeries ?? []),
        {
          id: Date.now().toString(36),
          label: 'Archived Study',
          title: '',
          description: '',
          imageUrl: '',
          listenUrl: '',
          studyGuideTitle: '',
          studyGuideDescription: '',
          studyGuideUrl: '',
          resourceLinks: [],
          notes: [],
        },
      ],
    }))
  }

  function updateArchivedSeries(id: string, field: keyof ArchivedSeries, value: string | ArchivedSeriesResourceLink[] | ArchivedSeriesNote[]) {
    setForm(f => ({
      ...f,
      archivedSeries: (f.archivedSeries ?? []).map(series => series.id === id ? { ...series, [field]: value } : series),
    }))
  }

  function removeArchivedSeries(id: string) {
    setForm(f => ({ ...f, archivedSeries: (f.archivedSeries ?? []).filter(series => series.id !== id) }))
  }

  function addArchivedSeriesLink(seriesId: string) {
    setForm(f => ({
      ...f,
      archivedSeries: (f.archivedSeries ?? []).map(series => series.id === seriesId
        ? {
            ...series,
            resourceLinks: [
              ...(series.resourceLinks ?? []),
              { id: `${seriesId}-${Date.now().toString(36)}`, label: '', url: '' },
            ],
          }
        : series),
    }))
  }

  function updateArchivedSeriesLink(seriesId: string, linkId: string, field: keyof ArchivedSeriesResourceLink, value: string) {
    setForm(f => ({
      ...f,
      archivedSeries: (f.archivedSeries ?? []).map(series => series.id === seriesId
        ? {
            ...series,
            resourceLinks: (series.resourceLinks ?? []).map(link => link.id === linkId ? { ...link, [field]: value } : link),
          }
        : series),
    }))
  }

  function removeArchivedSeriesLink(seriesId: string, linkId: string) {
    setForm(f => ({
      ...f,
      archivedSeries: (f.archivedSeries ?? []).map(series => series.id === seriesId
        ? { ...series, resourceLinks: (series.resourceLinks ?? []).filter(link => link.id !== linkId) }
        : series),
    }))
  }

  function addExistingCustomLinkToArchivedSeries(seriesId: string) {
    const selectedLinkId = archiveLinkSelectionBySeries[seriesId]
    if (!selectedLinkId) return

    const source = (form.customLinks ?? []).find(link => link.id === selectedLinkId)
    if (!source) return

    setForm(f => ({
      ...f,
      archivedSeries: (f.archivedSeries ?? []).map(series => {
        if (series.id !== seriesId) return series

        const alreadyExists = (series.resourceLinks ?? []).some(link =>
          link.url.trim().toLowerCase() === source.url.trim().toLowerCase(),
        )

        if (alreadyExists) return series

        return {
          ...series,
          resourceLinks: [
            ...(series.resourceLinks ?? []),
            {
              id: `${seriesId}-${Date.now().toString(36)}`,
              label: source.label,
              url: source.url,
            },
          ],
        }
      }),
    }))
  }

  function addAllExistingCustomLinksToArchivedSeries(seriesId: string) {
    setForm(f => ({
      ...f,
      archivedSeries: (f.archivedSeries ?? []).map(series => {
        if (series.id !== seriesId) return series

        const existingUrls = new Set(
          (series.resourceLinks ?? [])
            .map(link => link.url.trim().toLowerCase())
            .filter(Boolean),
        )

        const toAdd = (f.customLinks ?? [])
          .filter(link => link.url.trim().length > 0)
          .filter(link => !existingUrls.has(link.url.trim().toLowerCase()))
          .map(link => ({
            id: `${seriesId}-${Date.now().toString(36)}-${link.id}`,
            label: link.label,
            url: link.url,
          }))

        if (toAdd.length === 0) return series

        return {
          ...series,
          resourceLinks: [
            ...(series.resourceLinks ?? []),
            ...toAdd,
          ],
        }
      }),
    }))
  }

  function addArchivedSeriesNote(seriesId: string) {
    setForm(f => ({
      ...f,
      archivedSeries: (f.archivedSeries ?? []).map(series => series.id === seriesId
        ? {
            ...series,
            notes: [
              ...(series.notes ?? []),
              { id: `${seriesId}-note-${Date.now().toString(36)}`, heading: '', body: '' },
            ],
          }
        : series),
    }))
  }

  function updateArchivedSeriesNote(seriesId: string, noteId: string, field: keyof ArchivedSeriesNote, value: string) {
    setForm(f => ({
      ...f,
      archivedSeries: (f.archivedSeries ?? []).map(series => series.id === seriesId
        ? {
            ...series,
            notes: (series.notes ?? []).map(note => note.id === noteId ? { ...note, [field]: value } : note),
          }
        : series),
    }))
  }

  function removeArchivedSeriesNote(seriesId: string, noteId: string) {
    setForm(f => ({
      ...f,
      archivedSeries: (f.archivedSeries ?? []).map(series => series.id === seriesId
        ? { ...series, notes: (series.notes ?? []).filter(note => note.id !== noteId) }
        : series),
    }))
  }

  function archiveCurrentSeriesSnapshot() {
    const currentTitle = form.seriesTitle.trim()
    if (!currentTitle) {
      alert('Set a current series title first, then archive it.')
      return
    }

    const existing = (form.archivedSeries ?? []).some(
      series => series.title.trim().toLowerCase() === currentTitle.toLowerCase(),
    )

    if (existing && !confirm(`An archived series named "${currentTitle}" already exists. Create another snapshot anyway?`)) {
      return
    }

    const resourceLinks = (form.customLinks ?? [])
      .filter(link => link.placement === 'resources')
      .filter(link => link.label.trim().length > 0 || link.url.trim().length > 0)
      .map(link => ({
        id: `archive-link-${Date.now().toString(36)}-${link.id}`,
        label: link.label,
        url: link.url,
      }))

    const notes = (form.customBlocks ?? [])
      .filter(block => block.heading.trim().length > 0 || block.body.trim().length > 0)
      .map(block => ({
        id: `archive-note-${Date.now().toString(36)}-${block.id}`,
        heading: block.heading,
        body: block.body,
      }))

    const archived: ArchivedSeries = {
      id: `archive-${Date.now().toString(36)}`,
      label: form.seriesLabel?.trim() || 'Archived Study',
      title: form.seriesTitle,
      description: form.seriesDescription,
      imageUrl: form.seriesImageUrl,
      listenUrl: form.seriesListenUrl,
      studyGuideTitle: form.studyGuideTitle,
      studyGuideDescription: form.studyGuideDescription,
      studyGuideUrl: form.studyGuideUrl,
      resourceLinks,
      notes,
    }

    setForm(f => ({
      ...f,
      archivedSeries: [archived, ...(f.archivedSeries ?? [])],
    }))
    setContentTab('custom')
  }

  async function handleSave() {
    setStatus('saving')
    setErrorMsg('')
    try {
      const res = await fetch('/api/admin-content', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ siteContent: form }),
      })
      if (!res.ok) {
        const data = await res.json().catch(() => ({}))
        throw new Error((data as { message?: string }).message ?? 'Save failed')
      }
      onSave(form)
      setStatus('saved')
      setTimeout(() => setStatus('idle'), 3500)
    } catch (err) {
      setErrorMsg(err instanceof Error ? err.message : 'Unknown error')
      setStatus('error')
    }
  }

  function handleReset() {
    if (confirm('Reset all fields to defaults?')) {
      setForm(DEFAULTS)
      setStatus('idle')
    }
  }

  async function handleAnswerQuestion(questionId: string, answer: string) {
    if (!answer.trim()) return
    try {
      const res = await fetch(`/api/admin-questions/${questionId}/answer`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ answer: answer.trim() }),
      })
      if (!res.ok) throw new Error('Failed to answer question')
      setQuestions(qs =>
        qs.map(q =>
          q.id === questionId
            ? { ...q, answer: answer.trim(), answeredAt: new Date().toISOString() }
            : q
        )
      )
      setEditingQuestionId(null)
      setAnsweredQuestions(a => ({ ...a, [questionId]: '' }))
    } catch {
      alert('Failed to save answer')
    }
  }

  async function handleApproveQuestion(questionId: string, approved: boolean) {
    try {
      const res = await fetch(`/api/admin-questions/${questionId}/approve`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ approved }),
      })
      if (!res.ok) throw new Error('Failed to update question')
      setQuestions(qs =>
        qs.map(q =>
          q.id === questionId
            ? { ...q, isApproved: approved, approvedAt: approved ? new Date().toISOString() : null }
            : q
        )
      )
    } catch {
      alert('Failed to update question')
    }
  }

  async function handleDeleteQuestion(questionId: string) {
    if (!confirm('Delete this question permanently?')) return
    try {
      const res = await fetch(`/api/admin-questions/${questionId}`, { method: 'DELETE' })
      if (!res.ok) throw new Error('Failed to delete question')
      setQuestions(qs => qs.filter(q => q.id !== questionId))
    } catch {
      alert('Failed to delete question')
    }
  }
  return (
    <div className="admin-page">
      <div className="admin-header">
        <span className="admin-ornament">✦ &nbsp; ✦ &nbsp; ✦</span>
        <h1>Site Admin</h1>
        <p className="admin-sub">Verse by Verse with Nate</p>
        <div className="admin-header-actions">
          <Link to="/" className="admin-back">← Back to site</Link>
          <button type="button" className="btn-admin-logout" onClick={() => void onLogout()}>
            Log Out
          </button>
        </div>
      </div>

      <div className="admin-form-wrap">
        <div className="admin-top-tabs" role="tablist" aria-label="Admin sections">
          <button
            type="button"
            role="tab"
            aria-selected={adminTab === 'content'}
            className={`admin-tab ${adminTab === 'content' ? 'admin-tab--active' : ''}`}
            onClick={() => setAdminTab('content')}
          >
            Content
          </button>
          <button
            type="button"
            role="tab"
            aria-selected={adminTab === 'stats'}
            className={`admin-tab ${adminTab === 'stats' ? 'admin-tab--active' : ''}`}
            onClick={() => setAdminTab('stats')}
          >
            Site Stats
          </button>
          <button
            type="button"
            role="tab"
            aria-selected={adminTab === 'questions'}
            className={`admin-tab ${adminTab === 'questions' ? 'admin-tab--active' : ''}`}
            onClick={() => setAdminTab('questions')}
          >
            Questions ({questions.length})
          </button>
        </div>

        {adminTab === 'stats' && (
        <section className="admin-stats" aria-label="Site hit statistics">
          <div className="admin-stats-head">
            <h2>Site Hit Stats</h2>
            <p>Built-in page traffic and visitor intelligence from this server.</p>
          </div>
          {statsStatus === 'loading' && <p className="admin-stats-note">Loading stats...</p>}
          {statsStatus === 'error' && <p className="admin-stats-note admin-stats-note--err">Could not load stats right now.</p>}
          {statsStatus === 'ready' && stats && (
            <>
              <div className="admin-stats-grid">
                <article>
                  <h3>Total Hits</h3>
                  <p>{stats.totalHits.toLocaleString()}</p>
                </article>
                <article>
                  <h3>Last 30 Days</h3>
                  <p>{stats.last30DaysTotal.toLocaleString()}</p>
                </article>
                <article>
                  <h3>First Hit</h3>
                  <p>{formatDate(stats.firstHitAt)}</p>
                </article>
                <article>
                  <h3>Latest Hit</h3>
                  <p>{formatDate(stats.lastHitAt)}</p>
                </article>
              </div>

              <div className="admin-stats-lists">
                <div>
                  <h3>Top Paths</h3>
                  {stats.topPaths.length === 0 ? (
                    <p className="admin-stats-note">No hits tracked yet.</p>
                  ) : (
                    <ul>
                      {stats.topPaths.map(item => (
                        <li key={item.path}>
                          <span>{item.path}</span>
                          <strong>{item.hits.toLocaleString()}</strong>
                        </li>
                      ))}
                    </ul>
                  )}
                </div>
                <div>
                  <h3>Daily Hits (7 Days)</h3>
                  <ul>
                    {stats.last7Days.map(item => (
                      <li key={item.day}>
                        <span>{item.day}</span>
                        <strong>{item.hits.toLocaleString()}</strong>
                      </li>
                    ))}
                  </ul>
                </div>
              </div>

              <div className="admin-stats-head admin-stats-head--visitors">
                <h2>Visitor Details</h2>
                <p>IP, geography, and returning visitor behavior.</p>
              </div>

              <p className="admin-privacy-note">
                Privacy: visitor analytics only run after cookie consent. IPs below are masked.
              </p>

              <div className="admin-stats-grid">
                <article>
                  <h3>Total Visits</h3>
                  <p>{stats.visitors.totalVisits.toLocaleString()}</p>
                </article>
                <article>
                  <h3>Unique Visitors</h3>
                  <p>{stats.visitors.uniqueVisitors.toLocaleString()}</p>
                </article>
                <article>
                  <h3>Returning Visits</h3>
                  <p>{stats.visitors.returningVisits.toLocaleString()}</p>
                </article>
                <article>
                  <h3>Returning Rate</h3>
                  <p>
                    {stats.visitors.totalVisits > 0
                      ? `${Math.round((stats.visitors.returningVisits / stats.visitors.totalVisits) * 100)}%`
                      : '0%'}
                  </p>
                </article>
              </div>

              <div className="admin-stats-lists">
                <div>
                  <h3>Top Countries</h3>
                  <ul>
                    {stats.visitors.topCountries.map(item => (
                      <li key={item.name}>
                        <span>{item.name}</span>
                        <strong>{item.hits.toLocaleString()}</strong>
                      </li>
                    ))}
                  </ul>
                </div>
                <div>
                  <h3>Top States</h3>
                  <ul>
                    {stats.visitors.topStates.map(item => (
                      <li key={item.name}>
                        <span>{item.name}</span>
                        <strong>{item.hits.toLocaleString()}</strong>
                      </li>
                    ))}
                  </ul>
                </div>
                <div>
                  <h3>Top Counties</h3>
                  <ul>
                    {stats.visitors.topCounties.map(item => (
                      <li key={item.name}>
                        <span>{item.name}</span>
                        <strong>{item.hits.toLocaleString()}</strong>
                      </li>
                    ))}
                  </ul>
                </div>
                <div>
                  <h3>Top Cities</h3>
                  <ul>
                    {stats.visitors.topCities.map(item => (
                      <li key={item.name}>
                        <span>{item.name}</span>
                        <strong>{item.hits.toLocaleString()}</strong>
                      </li>
                    ))}
                  </ul>
                </div>
              </div>

              <div className="admin-visits-table-wrap">
                <h3>Recent Visitor Log</h3>
                {stats.visitors.recentVisits.length === 0 ? (
                  <p className="admin-stats-note">No visitor records yet.</p>
                ) : (
                  <div className="admin-visits-table-scroll">
                    <table className="admin-visits-table">
                      <thead>
                        <tr>
                          <th>Time</th>
                          <th>IP</th>
                          <th>Country</th>
                          <th>State</th>
                          <th>County</th>
                          <th>City</th>
                          <th>Path</th>
                          <th>Returning</th>
                          <th>Visit #</th>
                        </tr>
                      </thead>
                      <tbody>
                        {stats.visitors.recentVisits.map(row => (
                          <tr key={`${row.visitorId}-${row.at}`}>
                            <td>{formatDate(row.at)}</td>
                            <td>{maskIp(row.ip)}</td>
                            <td>{row.country}</td>
                            <td>{row.state}</td>
                            <td>{row.county}</td>
                            <td>{row.city}</td>
                            <td>{row.path}</td>
                            <td>{row.returningVisitor ? 'Yes' : 'No'}</td>
                            <td>{row.visitCount}</td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  </div>
                )}
              </div>

              <div className="admin-stats-head admin-stats-head--visitors">
                <h2>Contact Summary</h2>
                <p>Submission totals from the contact form.</p>
              </div>

              <div className="admin-stats-grid">
                <article>
                  <h3>Total Contact Messages</h3>
                  <p>{stats.contactTotals.totalSubmissions.toLocaleString()}</p>
                </article>
                <article>
                  <h3>Total Bible Questions</h3>
                  <p>{stats.contactTotals.totalQuestions.toLocaleString()}</p>
                </article>
              </div>

              <div className="admin-stats-head admin-stats-head--visitors">
                <h2>Data Management</h2>
                <p>Export, backup, or retain only recent analytics data.</p>
              </div>

              <div className="admin-stats-grid">
                <article>
                  <h3>Hit Stats Write</h3>
                  <p>{stats.writeStatus.hitStats.ok ? 'Healthy' : 'Error'}</p>
                  <p>{formatDate(stats.writeStatus.hitStats.at)}</p>
                </article>
                <article>
                  <h3>Visitor Stats Write</h3>
                  <p>{stats.writeStatus.visitorStats.ok ? 'Healthy' : 'Error'}</p>
                  <p>{formatDate(stats.writeStatus.visitorStats.at)}</p>
                </article>
                <article>
                  <h3>Backup Status</h3>
                  <p>{stats.writeStatus.backups.ok ? 'Healthy' : 'Error'}</p>
                  <p>{formatDate(stats.writeStatus.backups.at)}</p>
                </article>
                <article>
                  <h3>Latest Backup File</h3>
                  <p>{stats.writeStatus.backups.file ?? 'Not available yet'}</p>
                </article>
              </div>

              <div className="admin-actions admin-actions--maintenance">
                <button type="button" className="btn-admin-reset" onClick={handleExport}>Export JSON</button>
                <button type="button" className="btn-admin-reset" onClick={handleBackupNow}>Backup Now</button>
                <button type="button" className="btn-admin-reset" onClick={handlePrune}>Prune Old Data</button>
                <button type="button" className="btn-admin-remove" onClick={handleClear}>Clear Analytics</button>
              </div>

              <div className="admin-restore-row">
                <label htmlFor="restore-backup">Restore Backup</label>
                <select
                  id="restore-backup"
                  value={selectedBackup}
                  onChange={e => setSelectedBackup(e.target.value)}
                  disabled={backupFiles.length === 0}
                >
                  {backupFiles.length === 0 && <option value="">No backups found</option>}
                  {backupFiles.map(file => (
                    <option key={file.filename} value={file.filename}>{file.filename}</option>
                  ))}
                </select>
                <button type="button" className="btn-admin-reset" onClick={handleRestoreBackup} disabled={!selectedBackup}>
                  Restore Selected Backup
                </button>
              </div>
              {selectedBackupPreview && (
                <div className="admin-restore-preview">
                  <h3>Restore Preview</h3>
                  <p><strong>Backup:</strong> {selectedBackupPreview.filename}</p>
                  <p><strong>Created:</strong> {formatDate(selectedBackupPreview.createdAt)}</p>
                  <p><strong>Reason:</strong> {selectedBackupPreview.reason}</p>
                  <p><strong>Size:</strong> {(selectedBackupPreview.sizeBytes / 1024).toFixed(1)} KB</p>
                  <p><strong>Content Updated At:</strong> {formatDate(selectedBackupPreview.adminUpdatedAt)}</p>
                  <p><strong>Total Hits:</strong> {selectedBackupPreview.totalHits.toLocaleString()}</p>
                  <p><strong>Total Visits:</strong> {selectedBackupPreview.totalVisits.toLocaleString()}</p>
                </div>
              )}
              {maintenanceMsg && <p className="admin-stats-note">{maintenanceMsg}</p>}
            </>
          )}
        </section>
        )}

        {adminTab === 'content' && (
        <form
          className="admin-form"
          onSubmit={e => { e.preventDefault(); handleSave() }}
        >
          <div className="admin-tabs" role="tablist" aria-label="Content editor tabs">
            <button
              type="button"
              role="tab"
              aria-selected={contentTab === 'main'}
              className={`admin-tab ${contentTab === 'main' ? 'admin-tab--active' : ''}`}
              onClick={() => setContentTab('main')}
            >
              Main Content
            </button>
            <button
              type="button"
              role="tab"
              aria-selected={contentTab === 'custom'}
              className={`admin-tab ${contentTab === 'custom' ? 'admin-tab--active' : ''}`}
              onClick={() => setContentTab('custom')}
            >
              Custom Content
            </button>
          </div>

          {contentTab === 'main' && (
            <>
              <div className="admin-archive-helper">
                <h3>Archive Current Series</h3>
                <p>
                  Use this when you move from one study to the next. It creates a pre-filled archived entry
                  from the current series, study guide, custom resource links, and custom content blocks.
                </p>
                <button type="button" className="btn-admin-add" onClick={archiveCurrentSeriesSnapshot}>
                  + Archive Current Series Snapshot
                </button>
              </div>

              {FIELDS.map(({ key, label, multiline }) => (
                <div className="admin-field" key={key}>
                  <label htmlFor={`field-${key}`}>{label}</label>
                  {multiline ? (
                    <textarea
                      id={`field-${key}`}
                      value={form[key] as string}
                      onChange={e => handleChange(key, e.target.value)}
                      rows={4}
                    />
                  ) : (
                    <input
                      id={`field-${key}`}
                      type="text"
                      value={form[key] as string}
                      onChange={e => handleChange(key, e.target.value)}
                    />
                  )}
                </div>
              ))}
            </>
          )}

          {contentTab === 'custom' && (
            <>
              <div className="admin-content-summary">
                <div className="admin-summary-card">
                  <h3>Custom Links</h3>
                  <p>{(form.customLinks ?? []).length}</p>
                </div>
                <div className="admin-summary-card">
                  <h3>Custom Blocks</h3>
                  <p>{(form.customBlocks ?? []).length}</p>
                </div>
                <div className="admin-summary-card">
                  <h3>Archived Series</h3>
                  <p>{(form.archivedSeries ?? []).length}</p>
                </div>
              </div>

              <div className="admin-section-header">
                <h3>Custom Links</h3>
                <p>Add links to show in the platform buttons row, footer, or a dedicated "More Resources" section.</p>
              </div>
              {(form.customLinks ?? []).length === 0 && (
                <p className="admin-stats-note">No custom links yet.</p>
              )}
              {(form.customLinks ?? []).map(link => (
                <div key={link.id} className="admin-array-row">
                  <div className="admin-array-fields">
                    <div className="admin-field">
                      <label htmlFor={`link-label-${link.id}`}>Label</label>
                      <input
                        id={`link-label-${link.id}`}
                        type="text"
                        value={link.label}
                        placeholder="e.g. iHeart Radio"
                        onChange={e => updateLink(link.id, 'label', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`link-url-${link.id}`}>URL</label>
                      <input
                        id={`link-url-${link.id}`}
                        type="url"
                        value={link.url}
                        placeholder="https://..."
                        onChange={e => updateLink(link.id, 'url', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`link-placement-${link.id}`}>Show in</label>
                      <select
                        id={`link-placement-${link.id}`}
                        value={link.placement}
                        onChange={e => updateLink(link.id, 'placement', e.target.value)}
                      >
                        <option value="platforms">Platform Buttons (Listen section)</option>
                        <option value="footer">Footer Nav</option>
                        <option value="resources">More Resources Section</option>
                      </select>
                    </div>
                  </div>
                  <button type="button" className="btn-admin-remove" onClick={() => removeLink(link.id)}>
                    Remove
                  </button>
                </div>
              ))}
              <button type="button" className="btn-admin-add" onClick={addLink}>
                + Add Link
              </button>

              <div className="admin-section-header">
                <h3>Custom Content Blocks</h3>
                <p>Add extra text sections. They appear below the share/QR section on the site.</p>
              </div>
              {(form.customBlocks ?? []).length === 0 && (
                <p className="admin-stats-note">No custom content blocks yet.</p>
              )}
              {(form.customBlocks ?? []).map(block => (
                <div key={block.id} className="admin-array-row">
                  <div className="admin-array-fields">
                    <div className="admin-field">
                      <label htmlFor={`block-heading-${block.id}`}>Heading</label>
                      <input
                        id={`block-heading-${block.id}`}
                        type="text"
                        value={block.heading}
                        placeholder="Section heading"
                        onChange={e => updateBlock(block.id, 'heading', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`block-body-${block.id}`}>Body Text</label>
                      <textarea
                        id={`block-body-${block.id}`}
                        value={block.body}
                        rows={3}
                        placeholder="Write your content here…"
                        onChange={e => updateBlock(block.id, 'body', e.target.value)}
                      />
                    </div>
                  </div>
                  <button type="button" className="btn-admin-remove" onClick={() => removeBlock(block.id)}>
                    Remove
                  </button>
                </div>
              ))}
              <button type="button" className="btn-admin-add" onClick={addBlock}>
                + Add Content Block
              </button>

              <div className="admin-section-header">
                <h3>Archived Series Library</h3>
                <p>Move finished studies here so users can still access old resources after you switch the current series to something new.</p>
              </div>
              {(form.archivedSeries ?? []).length === 0 && (
                <p className="admin-stats-note">No archived series yet. When Titus is finished, add it here before switching the current series to Colossians.</p>
              )}
              {(form.archivedSeries ?? []).map(series => (
                <div key={series.id} className="admin-archive-card">
                  <div className="admin-archive-card-head">
                    <div>
                      <h4>{series.title || 'Untitled archived series'}</h4>
                      <p>{series.label || 'Archived Study'}</p>
                    </div>
                    <button type="button" className="btn-admin-remove" onClick={() => removeArchivedSeries(series.id)}>
                      Remove Series
                    </button>
                  </div>

                  <div className="admin-array-fields">
                    <div className="admin-field">
                      <label htmlFor={`archive-label-${series.id}`}>Label</label>
                      <input
                        id={`archive-label-${series.id}`}
                        type="text"
                        value={series.label}
                        placeholder="Archived Study"
                        onChange={e => updateArchivedSeries(series.id, 'label', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`archive-title-${series.id}`}>Series Title</label>
                      <input
                        id={`archive-title-${series.id}`}
                        type="text"
                        value={series.title}
                        placeholder="Study of Titus: Sound Doctrine"
                        onChange={e => updateArchivedSeries(series.id, 'title', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`archive-description-${series.id}`}>Description</label>
                      <textarea
                        id={`archive-description-${series.id}`}
                        value={series.description}
                        rows={4}
                        placeholder="Describe the archived study and why it still matters."
                        onChange={e => updateArchivedSeries(series.id, 'description', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`archive-image-${series.id}`}>Cover Image URL</label>
                      <input
                        id={`archive-image-${series.id}`}
                        type="text"
                        value={series.imageUrl}
                        placeholder="/images/titus-cover.png"
                        onChange={e => updateArchivedSeries(series.id, 'imageUrl', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`archive-listen-${series.id}`}>Listen URL</label>
                      <input
                        id={`archive-listen-${series.id}`}
                        type="url"
                        value={series.listenUrl}
                        placeholder="https://..."
                        onChange={e => updateArchivedSeries(series.id, 'listenUrl', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`archive-guide-title-${series.id}`}>Study Guide Title</label>
                      <input
                        id={`archive-guide-title-${series.id}`}
                        type="text"
                        value={series.studyGuideTitle}
                        placeholder="Companion Study Guide"
                        onChange={e => updateArchivedSeries(series.id, 'studyGuideTitle', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`archive-guide-description-${series.id}`}>Study Guide Description</label>
                      <textarea
                        id={`archive-guide-description-${series.id}`}
                        value={series.studyGuideDescription}
                        rows={3}
                        placeholder="Describe the archived guide or workbook."
                        onChange={e => updateArchivedSeries(series.id, 'studyGuideDescription', e.target.value)}
                      />
                    </div>
                    <div className="admin-field">
                      <label htmlFor={`archive-guide-url-${series.id}`}>Study Guide URL</label>
                      <input
                        id={`archive-guide-url-${series.id}`}
                        type="url"
                        value={series.studyGuideUrl}
                        placeholder="https://..."
                        onChange={e => updateArchivedSeries(series.id, 'studyGuideUrl', e.target.value)}
                      />
                    </div>
                  </div>

                  <div className="admin-archive-subsection">
                    <div className="admin-archive-subsection-head">
                      <h5>Archived Resource Links</h5>
                      <div className="admin-archive-subsection-actions">
                        <select
                          value={archiveLinkSelectionBySeries[series.id] ?? ''}
                          onChange={e => setArchiveLinkSelectionBySeries(prev => ({ ...prev, [series.id]: e.target.value }))}
                        >
                          <option value="">Pick existing custom link…</option>
                          {(form.customLinks ?? [])
                            .filter(link => link.url.trim().length > 0)
                            .map(link => (
                              <option key={`pick-${series.id}-${link.id}`} value={link.id}>
                                {link.label || link.url}
                              </option>
                            ))}
                        </select>
                        <button
                          type="button"
                          className="btn-admin-add"
                          onClick={() => addExistingCustomLinkToArchivedSeries(series.id)}
                          disabled={!archiveLinkSelectionBySeries[series.id]}
                        >
                          + Add Picked Link
                        </button>
                        <button
                          type="button"
                          className="btn-admin-add"
                          onClick={() => addAllExistingCustomLinksToArchivedSeries(series.id)}
                          disabled={(form.customLinks ?? []).filter(link => link.url.trim().length > 0).length === 0}
                        >
                          + Add All Custom Links
                        </button>
                        <button type="button" className="btn-admin-add" onClick={() => addArchivedSeriesLink(series.id)}>
                          + Add Blank Link
                        </button>
                      </div>
                    </div>
                    {(series.resourceLinks ?? []).length === 0 && (
                      <p className="admin-stats-note">No archived resource links yet.</p>
                    )}
                    {(series.resourceLinks ?? []).map(link => (
                      <div key={link.id} className="admin-array-row admin-array-row--nested">
                        <div className="admin-array-fields">
                          <div className="admin-field">
                            <label htmlFor={`archive-link-label-${link.id}`}>Label</label>
                            <input
                              id={`archive-link-label-${link.id}`}
                              type="text"
                              value={link.label}
                              placeholder="Episode guide"
                              onChange={e => updateArchivedSeriesLink(series.id, link.id, 'label', e.target.value)}
                            />
                          </div>
                          <div className="admin-field">
                            <label htmlFor={`archive-link-url-${link.id}`}>URL</label>
                            <input
                              id={`archive-link-url-${link.id}`}
                              type="url"
                              value={link.url}
                              placeholder="https://..."
                              onChange={e => updateArchivedSeriesLink(series.id, link.id, 'url', e.target.value)}
                            />
                          </div>
                        </div>
                        <button type="button" className="btn-admin-remove" onClick={() => removeArchivedSeriesLink(series.id, link.id)}>
                          Remove
                        </button>
                      </div>
                    ))}
                  </div>

                  <div className="admin-archive-subsection">
                    <div className="admin-archive-subsection-head">
                      <h5>Archived Notes / Blocks</h5>
                      <button type="button" className="btn-admin-add" onClick={() => addArchivedSeriesNote(series.id)}>
                        + Add Note Block
                      </button>
                    </div>
                    {(series.notes ?? []).length === 0 && (
                      <p className="admin-stats-note">No archived note blocks yet.</p>
                    )}
                    {(series.notes ?? []).map(note => (
                      <div key={note.id} className="admin-array-row admin-array-row--nested">
                        <div className="admin-array-fields">
                          <div className="admin-field">
                            <label htmlFor={`archive-note-heading-${note.id}`}>Heading</label>
                            <input
                              id={`archive-note-heading-${note.id}`}
                              type="text"
                              value={note.heading}
                              placeholder="Titus overview"
                              onChange={e => updateArchivedSeriesNote(series.id, note.id, 'heading', e.target.value)}
                            />
                          </div>
                          <div className="admin-field">
                            <label htmlFor={`archive-note-body-${note.id}`}>Body</label>
                            <textarea
                              id={`archive-note-body-${note.id}`}
                              value={note.body}
                              rows={3}
                              placeholder="Add archived notes, explanation, or links context."
                              onChange={e => updateArchivedSeriesNote(series.id, note.id, 'body', e.target.value)}
                            />
                          </div>
                        </div>
                        <button type="button" className="btn-admin-remove" onClick={() => removeArchivedSeriesNote(series.id, note.id)}>
                          Remove
                        </button>
                      </div>
                    ))}
                  </div>
                </div>
              ))}
              <button type="button" className="btn-admin-add" onClick={addArchivedSeries}>
                + Add Archived Series
              </button>
            </>
          )}

          <div className="admin-actions">
            <button
              type="submit"
              className="btn-admin-save"
              disabled={status === 'saving'}
            >
              {status === 'saving' ? 'Saving…' : 'Save Changes'}
            </button>
            <button
              type="button"
              className="btn-admin-reset"
              onClick={handleReset}
            >
              Reset to Defaults
            </button>
          </div>

          {status === 'saved' && (
            <p className="admin-status admin-status--ok">✓ Changes saved.</p>
          )}
          {status === 'error' && (
            <p className="admin-status admin-status--err">✗ {errorMsg}</p>
          )}
        </form>

        )}

        {adminTab === 'questions' && (
        <section className="admin-questions" aria-label="Q&A Management">
                  <div className="admin-stats-head">
                    <h2>Bible Questions & Answers</h2>
                    <p>Manage submitted questions, provide answers, and approve for public display.</p>
                  </div>

                  {questions.length === 0 ? (
                    <p className="admin-stats-note">No questions submitted yet.</p>
                  ) : (
                    <div className="admin-questions-list">
                      {questions.map(question => (
                        <div key={question.id} className="admin-question-card">
                          <div className="admin-question-header">
                            <div>
                              <p className="admin-question-meta">
                                <strong>{question.firstName}</strong> • {formatDate(question.submittedAt)}
                              </p>
                              <p className="admin-question-text"><strong>Q:</strong> {question.question}</p>
                            </div>
                            <div className="admin-question-status">
                              <span className={`admin-badge ${question.isApproved ? 'admin-badge--approved' : 'admin-badge--pending'}`}>
                                {question.isApproved ? 'Approved' : 'Pending'}
                              </span>
                              {question.answer && (
                                <span className="admin-badge admin-badge--answered">Answered</span>
                              )}
                            </div>
                          </div>

                          {question.answer && (
                            <div className="admin-question-answer">
                              <p><strong>A:</strong> {question.answer}</p>
                            </div>
                          )}

                          {editingQuestionId === question.id ? (
                            <div className="admin-question-editor">
                              <textarea
                                value={answeredQuestions[question.id] ?? question.answer ?? ''}
                                onChange={e => setAnsweredQuestions(a => ({ ...a, [question.id]: e.target.value }))}
                                rows={4}
                                placeholder="Type your answer here..."
                              />
                              <div className="admin-question-editor-actions">
                                <button
                                  type="button"
                                  className="btn-admin-save"
                                  onClick={() => handleAnswerQuestion(question.id, answeredQuestions[question.id] ?? '')}
                                >
                                  Save Answer
                                </button>
                                <button
                                  type="button"
                                  className="btn-admin-reset"
                                  onClick={() => setEditingQuestionId(null)}
                                >
                                  Cancel
                                </button>
                              </div>
                            </div>
                          ) : (
                            <div className="admin-question-actions">
                              <button
                                type="button"
                                className="btn-admin-reset"
                                onClick={() => {
                                  setEditingQuestionId(question.id)
                                  setAnsweredQuestions(a => ({ ...a, [question.id]: question.answer ?? '' }))
                                }}
                              >
                                {question.answer ? 'Edit Answer' : 'Add Answer'}
                              </button>
                              <button
                                type="button"
                                className={`btn-admin-${question.isApproved ? 'remove' : 'reset'}`}
                                onClick={() => handleApproveQuestion(question.id, !question.isApproved)}
                              >
                                {question.isApproved ? 'Unapprove' : 'Approve'}
                              </button>
                              <button
                                type="button"
                                className="btn-admin-remove"
                                onClick={() => handleDeleteQuestion(question.id)}
                              >
                                Delete
                              </button>
                            </div>
                          )}
                        </div>
                      ))}
                    </div>
                  )}
                </section>
        )}
      </div>
    </div>
  )
}
