import { useEffect, useState, useCallback } from 'react'
import { Link } from 'react-router-dom'
import { ArrowLeft, RefreshCw, Save, Trash2, Plus, ChevronDown, ChevronRight, MessageSquare, X } from 'lucide-react'
import {
  fetchEditRaw,
  putCombatLosses,
  patchKeyLocation,
  postSituationUpdate,
  deleteSituationUpdate,
  putForceSummary,
  putDisplayStats,
  putAnimationConfig,
  putCrawlerConfig,
  fetchFeedbackList,
  type EditRawData,
  type CombatLossesRow,
  type KeyLocationRow,
  type ForceSummaryRow,
  type DisplayStatsRow,
  type AnimationConfigRow,
  type CrawlerConfigRow,
  type FeedbackRow,
} from '@/api/edit'
import { fetchAndSetSituation } from '@/store/situationStore'
import { useStatsStore } from '@/store/statsStore'

const LOSS_FIELDS: { key: keyof CombatLossesRow; label: string }[] = [
  { key: 'bases_destroyed', label: '基地摧毁' },
  { key: 'bases_damaged', label: '基地受损' },
  { key: 'personnel_killed', label: '人员阵亡' },
  { key: 'personnel_wounded', label: '人员受伤' },
  { key: 'civilian_killed', label: '平民死亡' },
  { key: 'civilian_wounded', label: '平民受伤' },
  { key: 'aircraft', label: '飞机' },
  { key: 'warships', label: '军舰' },
  { key: 'armor', label: '装甲' },
  { key: 'vehicles', label: '车辆' },
  { key: 'drones', label: '无人机' },
  { key: 'missiles', label: '导弹' },
  { key: 'helicopters', label: '直升机' },
  { key: 'submarines', label: '潜艇' },
  { key: 'carriers', label: '航母' },
  { key: 'civilian_ships', label: '民船' },
  { key: 'airport_port', label: '机场/港口' },
]

const SUMMARY_FIELDS: { key: keyof ForceSummaryRow; label: string }[] = [
  { key: 'total_assets', label: '总资产' },
  { key: 'personnel', label: '人员' },
  { key: 'naval_ships', label: '舰艇' },
  { key: 'aircraft', label: '飞机' },
  { key: 'ground_units', label: '地面单位' },
  { key: 'uav', label: '无人机' },
  { key: 'missile_consumed', label: '导弹消耗' },
  { key: 'missile_stock', label: '导弹库存' },
]

const CATEGORIES = ['deployment', 'alert', 'intel', 'diplomatic', 'other'] as const
const SEVERITIES = ['low', 'medium', 'high', 'critical'] as const
const STATUS_OPTIONS = ['operational', 'damaged', 'attacked'] as const

function num(v: unknown): number {
  if (v === null || v === undefined) return 0
  const n = Number(v)
  return Number.isFinite(n) ? n : 0
}

export function EditDashboard() {
  const [data, setData] = useState<EditRawData | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [saving, setSaving] = useState<string | null>(null)
  const [openSections, setOpenSections] = useState<Set<string>>(new Set(['displayStats', 'losses', 'updates']))
  const [newUpdate, setNewUpdate] = useState({ category: 'other', summary: '', severity: 'medium' })
  const [feedbackOpen, setFeedbackOpen] = useState(false)
  const [feedbackList, setFeedbackList] = useState<FeedbackRow[]>([])
  const [feedbackLoading, setFeedbackLoading] = useState(false)
  const setStats = useStatsStore((s) => s.setStats)

  const load = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const raw = await fetchEditRaw()
      setData(raw)
    } catch (e) {
      setError(e instanceof Error ? e.message : '加载失败')
    } finally {
      setLoading(false)
    }
  }, [])

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

  const toggleSection = (id: string) => {
    setOpenSections((s) => {
      const next = new Set(s)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  const afterSave = async () => {
    await load()
    await fetchAndSetSituation()
  }

  const handleSaveLosses = async (side: 'us' | 'iran', row: CombatLossesRow | null) => {
    if (!row) return
    setSaving(`losses-${side}`)
    try {
      await putCombatLosses(side, row)
      await afterSave()
    } catch (e) {
      setError(e instanceof Error ? e.message : '保存失败')
    } finally {
      setSaving(null)
    }
  }

  const handleSaveKeyLocation = async (loc: KeyLocationRow, patch: Partial<KeyLocationRow>) => {
    setSaving(`loc-${loc.id}`)
    try {
      await patchKeyLocation(loc.id, patch)
      await afterSave()
    } catch (e) {
      setError(e instanceof Error ? e.message : '保存失败')
    } finally {
      setSaving(null)
    }
  }

  const handleAddUpdate = async () => {
    if (!newUpdate.summary.trim()) return
    setSaving('add-update')
    try {
      await postSituationUpdate({
        timestamp: new Date().toISOString(),
        category: newUpdate.category,
        summary: newUpdate.summary.trim(),
        severity: newUpdate.severity,
      })
      setNewUpdate({ category: 'other', summary: '', severity: 'medium' })
      await afterSave()
    } catch (e) {
      setError(e instanceof Error ? e.message : '添加失败')
    } finally {
      setSaving(null)
    }
  }

  const handleDeleteUpdate = async (id: string) => {
    if (!confirm('确定删除这条事件？')) return
    setSaving(`del-${id}`)
    try {
      await deleteSituationUpdate(id)
      await afterSave()
    } catch (e) {
      setError(e instanceof Error ? e.message : '删除失败')
    } finally {
      setSaving(null)
    }
  }

  const handleSaveForceSummary = async (side: 'us' | 'iran', row: ForceSummaryRow | null) => {
    if (!row) return
    setSaving(`summary-${side}`)
    try {
      await putForceSummary(side, row)
      await afterSave()
    } catch (e) {
      setError(e instanceof Error ? e.message : '保存失败')
    } finally {
      setSaving(null)
    }
  }

  const handleSaveDisplayStats = async (row: DisplayStatsRow) => {
    setSaving('displayStats')
    try {
      await putDisplayStats(row)
      await load()
      const res = await fetch('/api/stats', { cache: 'no-store' })
      if (res.ok) {
        const stats = await res.json()
        setStats(stats)
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : '保存失败')
    } finally {
      setSaving(null)
    }
  }

  const handleSaveAnimationConfig = async (row: AnimationConfigRow) => {
    setSaving('animationConfig')
    try {
      await putAnimationConfig({ strikeCutoffDays: row.strikeCutoffDays })
      await afterSave()
    } catch (e) {
      setError(e instanceof Error ? e.message : '保存失败')
    } finally {
      setSaving(null)
    }
  }

  const handleSaveCrawlerConfig = async (row: CrawlerConfigRow) => {
    setSaving('crawlerConfig')
    try {
      await putCrawlerConfig({ rssIntervalSec: row.rssIntervalSec })
      await load()
    } catch (e) {
      setError(e instanceof Error ? e.message : '保存失败')
    } finally {
      setSaving(null)
    }
  }

  const handleOpenFeedback = async () => {
    setFeedbackOpen(true)
    setFeedbackLoading(true)
    setFeedbackList([])
    try {
      const { list } = await fetchFeedbackList()
      setFeedbackList(list ?? [])
    } catch {
      setFeedbackList([])
    } finally {
      setFeedbackLoading(false)
    }
  }

  const handleClearDisplayStatsOverrides = async () => {
    if (!confirm('确定清除所有覆盖？将恢复为实时统计（在看=近2分钟访问数，看过=累计访问等）。')) return
    setSaving('displayStats')
    try {
      await putDisplayStats({ clearOverride: true })
      await load()
      const res = await fetch('/api/stats', { cache: 'no-store' })
      if (res.ok) {
        const stats = await res.json()
        setStats(stats)
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : '保存失败')
    } finally {
      setSaving(null)
    }
  }

  if (loading && !data) {
    return (
      <div className="flex min-h-screen items-center justify-center bg-military-dark text-military-text-secondary">
        <RefreshCw className="h-6 w-6 animate-spin" />
      </div>
    )
  }

  return (
    <div className="min-h-screen bg-military-dark font-orbitron text-military-text-primary">
      <header className="sticky top-0 z-10 flex flex-wrap items-center justify-between gap-2 border-b border-military-border bg-military-panel/95 px-4 py-3">
        <div className="flex items-center gap-4">
          <Link
            to="/"
            className="flex items-center gap-2 rounded border border-military-border px-3 py-1.5 text-sm text-military-text-secondary hover:bg-military-border/30 hover:text-military-text-primary"
          >
            <ArrowLeft className="h-4 w-4" />
            返回看板
          </Link>
          <span className="flex items-center gap-2 text-lg text-cyan-400">
            数据修正
          </span>
        </div>
        <button
          onClick={load}
          disabled={loading}
          className="flex items-center gap-2 rounded border border-military-border px-3 py-1.5 text-sm text-military-text-secondary hover:bg-military-border/30 disabled:opacity-50"
        >
          <RefreshCw className={`h-4 w-4 ${loading ? 'animate-spin' : ''}`} />
          刷新
        </button>
      </header>

      {error && (
        <div className="mx-4 mt-4 rounded border border-amber-600/50 bg-amber-950/30 px-4 py-2 text-amber-400">
          {error}
          <button type="button" className="ml-2 underline" onClick={() => setError(null)}>关闭</button>
        </div>
      )}

      <main className="max-w-4xl space-y-2 p-4">
        {/* 动画衰减参数 */}
        <section className="rounded border border-military-border bg-military-panel/80 overflow-hidden">
          <button
            onClick={() => toggleSection('animation')}
            className="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-military-border/20"
          >
            <span className="font-medium text-cyan-400">动画 / 衰减参数</span>
            {openSections.has('animation') ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
          </button>
          {openSections.has('animation') && data && (
            <div className="border-t border-military-border p-4 space-y-3 text-sm">
              <p className="text-military-text-secondary text-xs">
                衰减系数用于控制「打击脉冲」持续天数。超出该天数后，仅保留减弱的呼吸效果与标注。
              </p>
              <form
                className="flex flex-wrap items-center gap-3"
                onSubmit={(e) => {
                  e.preventDefault()
                  const form = e.currentTarget
                  const fd = new FormData(form)
                  const v = Number(fd.get('strikeCutoffDays') || 0)
                  const current: AnimationConfigRow = {
                    strikeCutoffDays: Number.isFinite(v) && v > 0 ? v : data.animationConfig?.strikeCutoffDays ?? 5,
                  }
                  handleSaveAnimationConfig(current)
                }}
              >
                <label className="flex items-center gap-2 text-xs text-military-text-secondary">
                  <span>衰减窗口（天）</span>
                  <input
                    type="number"
                    name="strikeCutoffDays"
                    min={1}
                    max={30}
                    defaultValue={data.animationConfig?.strikeCutoffDays ?? 5}
                    className="w-20 rounded border border-military-border bg-black/40 px-2 py-1 text-right text-xs text-military-text-primary"
                  />
                </label>
                <button
                  type="submit"
                  disabled={saving === 'animationConfig'}
                  className="inline-flex items-center gap-1 rounded border border-military-border px-3 py-1.5 text-xs text-military-text-secondary hover:bg-military-border/30 disabled:opacity-50"
                >
                  <Save className="h-3 w-3" />
                  保存
                </button>
              </form>
            </div>
          )}
        </section>

        {/* 爬虫配置：RSS 抓取间隔，爬虫从 DB 读取便于修订面板调整 */}
        <section className="rounded border border-military-border bg-military-panel/80 overflow-hidden">
          <button
            onClick={() => toggleSection('crawlerConfig')}
            className="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-military-border/20"
          >
            <span className="font-medium text-cyan-400">爬虫配置</span>
            {openSections.has('crawlerConfig') ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
          </button>
          {openSections.has('crawlerConfig') && data && (
            <div className="border-t border-military-border p-4 space-y-3 text-sm">
              <p className="text-military-text-secondary text-xs">
                RSS 抓取间隔（秒）：爬虫每轮抓取后等待该秒数再执行下一轮。范围 30–86400（1 分钟–24 小时）。修改后爬虫下次循环生效。
              </p>
              <form
                className="flex flex-wrap items-center gap-3"
                onSubmit={(e) => {
                  e.preventDefault()
                  const v = Number((e.currentTarget.querySelector('input[name="rssIntervalSec"]') as HTMLInputElement)?.value ?? 60)
                  const sec = Number.isFinite(v) && v >= 30 && v <= 86400 ? v : data.crawlerConfig?.rssIntervalSec ?? 60
                  handleSaveCrawlerConfig({ rssIntervalSec: sec })
                }}
              >
                <label className="flex items-center gap-2 text-xs text-military-text-secondary">
                  <span>抓取间隔（秒）</span>
                  <input
                    type="number"
                    name="rssIntervalSec"
                    min={30}
                    max={86400}
                    defaultValue={data.crawlerConfig?.rssIntervalSec ?? 60}
                    className="w-24 rounded border border-military-border bg-black/40 px-2 py-1 text-right text-xs text-military-text-primary"
                  />
                </label>
                <button
                  type="submit"
                  disabled={saving === 'crawlerConfig'}
                  className="inline-flex items-center gap-1 rounded border border-military-border px-3 py-1.5 text-xs text-military-text-secondary hover:bg-military-border/30 disabled:opacity-50"
                >
                  <Save className="h-3 w-3" />
                  保存
                </button>
              </form>
            </div>
          )}
        </section>

        {/* 看过、在看、分享、点赞、留言 */}
        <section className="rounded border border-military-border bg-military-panel/80 overflow-hidden">
          <div className="flex w-full items-center gap-2">
            <button
              onClick={() => toggleSection('displayStats')}
              className="flex flex-1 items-center justify-between px-4 py-3 text-left hover:bg-military-border/20"
            >
              <span className="font-medium text-cyan-400">看过 / 在看 / 分享 / 点赞 / 留言</span>
              {openSections.has('displayStats') ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
            </button>
            <button
              type="button"
              onClick={handleOpenFeedback}
              className="flex items-center gap-1.5 rounded border border-military-border px-2 py-1.5 text-xs text-military-text-secondary hover:bg-military-border/30 shrink-0"
            >
              <MessageSquare className="h-3.5 w-3.5" />
              查看留言数据
            </button>
          </div>
          {openSections.has('displayStats') && data && (
            <div className="border-t border-military-border p-4 space-y-3">
              <p className="text-military-text-secondary text-xs">
                {data.displayStats?.overrideEnabled
                  ? '当前看板显示为覆盖值。'
                  : '当前看板显示为实时统计。'}
                在看 = 近 2 分钟访问数，看过 = 累计访问。保存后开启覆盖；点「恢复实时统计」关闭覆盖。
              </p>
              <DisplayStatsForm
                row={data.displayStats ?? { overrideEnabled: false, viewers: 0, cumulative: 0, shareCount: 0, likeCount: 0, feedbackCount: 0 }}
                onSave={handleSaveDisplayStats}
                onClearOverrides={handleClearDisplayStatsOverrides}
                saving={saving === 'displayStats'}
              />
            </div>
          )}
        </section>

        {/* 战损 */}
        <section className="rounded border border-military-border bg-military-panel/80 overflow-hidden">
          <button
            onClick={() => toggleSection('losses')}
            className="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-military-border/20"
          >
            <span className="font-medium text-cyan-400">战损（美 / 伊）</span>
            {openSections.has('losses') ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
          </button>
          {openSections.has('losses') && data && (
            <div className="border-t border-military-border p-4 space-y-6">
              {(['us', 'iran'] as const).map((side) => {
                const row = data.combatLosses[side]
                if (!row) return <p key={side} className="text-military-text-secondary text-sm">暂无数据</p>
                return (
                  <LossForm
                    key={side}
                    side={side}
                    row={row}
                    onSave={(updated) => handleSaveLosses(side, updated)}
                    saving={saving === `losses-${side}`}
                  />
                )
              })}
            </div>
          )}
        </section>

        {/* 美军据点 */}
        <section className="rounded border border-military-border bg-military-panel/80 overflow-hidden">
          <button
            onClick={() => toggleSection('loc-us')}
            className="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-military-border/20"
          >
            <span className="font-medium text-military-us">美军据点</span>
            {openSections.has('loc-us') ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
          </button>
          {openSections.has('loc-us') && data && (
            <div className="border-t border-military-border p-4">
              <KeyLocationList
                list={data.keyLocations.us}
                onSave={handleSaveKeyLocation}
                savingId={saving}
              />
            </div>
          )}
        </section>

        {/* 伊朗据点 */}
        <section className="rounded border border-military-border bg-military-panel/80 overflow-hidden">
          <button
            onClick={() => toggleSection('loc-iran')}
            className="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-military-border/20"
          >
            <span className="font-medium text-military-iran">伊朗据点</span>
            {openSections.has('loc-iran') ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
          </button>
          {openSections.has('loc-iran') && data && (
            <div className="border-t border-military-border p-4">
              <KeyLocationList
                list={data.keyLocations.iran}
                onSave={handleSaveKeyLocation}
                savingId={saving}
              />
            </div>
          )}
        </section>

        {/* 事件脉络 */}
        <section className="rounded border border-military-border bg-military-panel/80 overflow-hidden">
          <button
            onClick={() => toggleSection('updates')}
            className="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-military-border/20"
          >
            <span className="font-medium text-cyan-400">事件脉络</span>
            {openSections.has('updates') ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
          </button>
          {openSections.has('updates') && data && (
            <div className="border-t border-military-border p-4 space-y-4">
              <div className="flex flex-wrap gap-2 items-end rounded border border-military-border/50 bg-military-dark/50 p-3">
                <select
                  value={newUpdate.category}
                  onChange={(e) => setNewUpdate((u) => ({ ...u, category: e.target.value }))}
                  className="rounded border border-military-border bg-military-panel px-2 py-1.5 text-sm"
                >
                  {CATEGORIES.map((c) => (
                    <option key={c} value={c}>{c}</option>
                  ))}
                </select>
                <select
                  value={newUpdate.severity}
                  onChange={(e) => setNewUpdate((u) => ({ ...u, severity: e.target.value }))}
                  className="rounded border border-military-border bg-military-panel px-2 py-1.5 text-sm"
                >
                  {SEVERITIES.map((s) => (
                    <option key={s} value={s}>{s}</option>
                  ))}
                </select>
                <input
                  type="text"
                  placeholder="摘要"
                  value={newUpdate.summary}
                  onChange={(e) => setNewUpdate((u) => ({ ...u, summary: e.target.value }))}
                  className="min-w-[200px] flex-1 rounded border border-military-border bg-military-panel px-2 py-1.5 text-sm"
                />
                <button
                  type="button"
                  onClick={handleAddUpdate}
                  disabled={saving === 'add-update' || !newUpdate.summary.trim()}
                  className="flex items-center gap-1 rounded border border-cyan-600 bg-cyan-950/50 px-3 py-1.5 text-sm text-cyan-400 hover:bg-cyan-900/40 disabled:opacity-50"
                >
                  <Plus className="h-4 w-4" />
                  添加
                </button>
              </div>
              <ul className="space-y-2 max-h-64 overflow-y-auto">
                {data.situationUpdates.map((u) => (
                  <li
                    key={u.id}
                    className="flex items-start gap-2 rounded border border-military-border/50 bg-military-dark/30 px-3 py-2 text-sm"
                  >
                    <span className="shrink-0 text-military-text-secondary text-xs">
                      {u.timestamp.slice(0, 19).replace('T', ' ')}
                    </span>
                    <span className="shrink-0 rounded bg-military-border/50 px-1.5 py-0.5 text-xs">{u.category}</span>
                    <span className="shrink-0 rounded bg-amber-900/40 px-1.5 py-0.5 text-xs">{u.severity}</span>
                    <span className="min-w-0 flex-1 truncate" title={u.summary}>{u.summary}</span>
                    <button
                      type="button"
                      onClick={() => handleDeleteUpdate(u.id)}
                      disabled={String(saving).startsWith('del-')}
                      className="shrink-0 rounded p-1 text-red-400 hover:bg-red-950/50 disabled:opacity-50"
                      title="删除"
                    >
                      <Trash2 className="h-4 w-4" />
                    </button>
                  </li>
                ))}
              </ul>
            </div>
          )}
        </section>

        {/* 军力概要 */}
        <section className="rounded border border-military-border bg-military-panel/80 overflow-hidden">
          <button
            onClick={() => toggleSection('summary')}
            className="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-military-border/20"
          >
            <span className="font-medium text-cyan-400">军力概要（美 / 伊）</span>
            {openSections.has('summary') ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
          </button>
          {openSections.has('summary') && data && (
            <div className="border-t border-military-border p-4 space-y-6">
              {(['us', 'iran'] as const).map((side) => {
                const row = data.forceSummary[side]
                if (!row) return <p key={side} className="text-military-text-secondary text-sm">暂无数据</p>
                return (
                  <ForceSummaryForm
                    key={side}
                    side={side}
                    row={row}
                    onSave={(updated) => handleSaveForceSummary(side, updated)}
                    saving={saving === `summary-${side}`}
                  />
                )
              })}
            </div>
          )}
        </section>
      </main>

      {/* 留言数据弹窗 */}
      {feedbackOpen && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4"
          onClick={() => setFeedbackOpen(false)}
          aria-modal="true"
          role="dialog"
        >
          <div
            className="max-h-[85vh] w-full max-w-2xl rounded border border-military-border bg-military-panel shadow-xl flex flex-col"
            onClick={(e) => e.stopPropagation()}
          >
            <div className="flex items-center justify-between border-b border-military-border px-4 py-3">
              <h3 className="font-medium text-cyan-400">留言数据</h3>
              <button
                type="button"
                onClick={() => setFeedbackOpen(false)}
                className="rounded p-1 text-military-text-secondary hover:bg-military-border/50 hover:text-military-text-primary"
                aria-label="关闭"
              >
                <X className="h-5 w-5" />
              </button>
            </div>
            <div className="flex-1 overflow-y-auto p-4">
              {feedbackLoading ? (
                <p className="text-military-text-secondary text-sm">加载中…</p>
              ) : feedbackList.length === 0 ? (
                <p className="text-military-text-secondary text-sm">暂无留言（若刚点击后即显示，可能是接口暂时不可用，请稍后重试）</p>
              ) : (
                <ul className="space-y-3">
                  {feedbackList.map((f) => (
                    <li
                      key={f.id}
                      className="rounded border border-military-border/50 bg-military-dark/30 px-3 py-2 text-sm"
                    >
                      <div className="flex flex-wrap items-center gap-2 text-xs text-military-text-secondary mb-1">
                        <span>#{f.id}</span>
                        <span>{f.created_at?.slice(0, 19).replace('T', ' ') ?? ''}</span>
                        {f.ip && <span>{f.ip}</span>}
                      </div>
                      <p className="text-military-text-primary whitespace-pre-wrap break-words">{f.content}</p>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

function LossForm({
  side,
  row,
  onSave,
  saving,
}: {
  side: 'us' | 'iran'
  row: CombatLossesRow
  onSave: (row: CombatLossesRow) => void
  saving: boolean
}) {
  const [edit, setEdit] = useState<CombatLossesRow>({ ...row })
  useEffect(() => {
    setEdit({ ...row })
  }, [row])
  const sideLabel = side === 'us' ? '美军' : '伊朗'
  return (
    <div className={`rounded border ${side === 'us' ? 'border-military-us/40' : 'border-military-iran/40'} bg-military-dark/50 p-4`}>
      <div className="mb-3 font-medium">{sideLabel}</div>
      <div className="grid grid-cols-2 gap-x-4 gap-y-2 sm:grid-cols-3">
        {LOSS_FIELDS.map(({ key, label }) => (
          <label key={key} className="flex items-center gap-2 text-sm">
            <span className="w-24 shrink-0 text-military-text-secondary">{label}</span>
            <input
              type="number"
              min={0}
              value={edit[key] ?? 0}
              onChange={(e) => setEdit((r) => ({ ...r, [key]: num(e.target.value) }))}
              className="w-20 rounded border border-military-border bg-military-panel px-2 py-1 text-right tabular-nums"
            />
          </label>
        ))}
      </div>
      <button
        type="button"
        onClick={() => onSave(edit)}
        disabled={saving}
        className="mt-3 flex items-center gap-1 rounded border border-cyan-600 bg-cyan-950/50 px-3 py-1.5 text-sm text-cyan-400 hover:bg-cyan-900/40 disabled:opacity-50"
      >
        <Save className="h-4 w-4" />
        保存
      </button>
    </div>
  )
}

function KeyLocationList({
  list,
  onSave,
  savingId,
}: {
  list: KeyLocationRow[]
  onSave: (loc: KeyLocationRow, patch: Partial<KeyLocationRow>) => void
  savingId: string | null
}) {
  if (list.length === 0) return <p className="text-military-text-secondary text-sm">暂无据点</p>
  return (
    <ul className="space-y-3">
      {list.map((loc) => (
        <KeyLocationRowEdit
          key={loc.id}
          loc={loc}
          onSave={onSave}
          saving={savingId === `loc-${loc.id}`}
        />
      ))}
    </ul>
  )
}

function KeyLocationRowEdit({
  loc,
  onSave,
  saving,
}: {
  loc: KeyLocationRow
  onSave: (loc: KeyLocationRow, patch: Partial<KeyLocationRow>) => void
  saving: boolean
}) {
  const [status, setStatus] = useState(loc.status ?? 'operational')
  const [damageLevel, setDamageLevel] = useState(num(loc.damage_level))
  useEffect(() => {
    setStatus(loc.status ?? 'operational')
    setDamageLevel(num(loc.damage_level))
  }, [loc.id, loc.status, loc.damage_level])
  const hasChange = status !== (loc.status ?? 'operational') || damageLevel !== num(loc.damage_level)
  return (
    <li className="flex flex-wrap items-center gap-2 rounded border border-military-border/50 bg-military-dark/30 px-3 py-2">
      <span className="font-medium min-w-0 truncate">{loc.name}</span>
      <select
        value={status}
        onChange={(e) => setStatus(e.target.value)}
        className="rounded border border-military-border bg-military-panel px-2 py-1 text-sm"
      >
        {STATUS_OPTIONS.map((s) => {
          return <option key={s} value={s}>{s}</option>
        })}
      </select>
      <label className="flex items-center gap-1 text-sm">
        <span className="text-military-text-secondary">损伤</span>
        <input
          type="number"
          min={0}
          max={3}
          value={damageLevel}
          onChange={(e) => setDamageLevel(num(e.target.value))}
          className="w-14 rounded border border-military-border bg-military-panel px-2 py-1 text-right"
        />
      </label>
      <button
        type="button"
        onClick={() => onSave(loc, { status, damage_level: damageLevel })}
        disabled={saving || !hasChange}
        className="flex items-center gap-1 rounded border border-cyan-600 bg-cyan-950/50 px-2 py-1 text-xs text-cyan-400 hover:bg-cyan-900/40 disabled:opacity-50"
      >
        <Save className="h-3 w-3" />
        保存
      </button>
      {saving && <span className="text-cyan-400 text-xs">保存中…</span>}
    </li>
  )
}

function ForceSummaryForm({
  side,
  row,
  onSave,
  saving,
}: {
  side: 'us' | 'iran'
  row: ForceSummaryRow
  onSave: (row: ForceSummaryRow) => void
  saving: boolean
}) {
  const [edit, setEdit] = useState<ForceSummaryRow>({ ...row })
  useEffect(() => {
    setEdit({ ...row })
  }, [row])
  const sideLabel = side === 'us' ? '美军' : '伊朗'
  return (
    <div className={`rounded border ${side === 'us' ? 'border-military-us/40' : 'border-military-iran/40'} bg-military-dark/50 p-4`}>
      <div className="mb-3 font-medium">{sideLabel}</div>
      <div className="grid grid-cols-2 gap-x-4 gap-y-2 sm:grid-cols-4">
        {SUMMARY_FIELDS.map(({ key, label }) => (
          <label key={key} className="flex items-center gap-2 text-sm">
            <span className="w-24 shrink-0 text-military-text-secondary">{label}</span>
            <input
              type="number"
              min={0}
              value={edit[key] ?? 0}
              onChange={(e) => setEdit((r) => ({ ...r, [key]: num(e.target.value) }))}
              className="w-20 rounded border border-military-border bg-military-panel px-2 py-1 text-right tabular-nums"
            />
          </label>
        ))}
      </div>
      <button
        type="button"
        onClick={() => onSave(edit)}
        disabled={saving}
        className="mt-3 flex items-center gap-1 rounded border border-cyan-600 bg-cyan-950/50 px-3 py-1.5 text-sm text-cyan-400 hover:bg-cyan-900/40 disabled:opacity-50"
      >
        <Save className="h-4 w-4" />
        保存
      </button>
    </div>
  )
}

const DISPLAY_STATS_FIELDS: { key: keyof DisplayStatsRow; label: string }[] = [
  { key: 'cumulative', label: '看过' },
  { key: 'viewers', label: '在看' },
  { key: 'shareCount', label: '分享' },
  { key: 'likeCount', label: '点赞' },
  { key: 'feedbackCount', label: '留言' },
]

function DisplayStatsForm({
  row,
  onSave,
  onClearOverrides,
  saving,
}: {
  row: DisplayStatsRow
  onSave: (row: DisplayStatsRow) => void
  onClearOverrides: () => void
  saving: boolean
}) {
  const [edit, setEdit] = useState<DisplayStatsRow>({ ...row })
  useEffect(() => {
    setEdit({ ...row })
  }, [row])
  return (
    <div className="rounded border border-military-border/50 bg-military-dark/50 p-4">
      <div className="grid grid-cols-2 gap-x-4 gap-y-3 sm:grid-cols-3 md:grid-cols-5">
        {DISPLAY_STATS_FIELDS.map(({ key, label }) => (
          <label key={key} className="flex items-center gap-2 text-sm">
            <span className="w-14 shrink-0 text-military-text-secondary">{label}</span>
            <input
              type="number"
              min={0}
              value={edit[key]}
              onChange={(e) => setEdit((r) => ({ ...r, [key]: num(e.target.value) }))}
              className="w-20 rounded border border-military-border bg-military-panel px-2 py-1 text-right tabular-nums"
            />
          </label>
        ))}
      </div>
      <div className="mt-3 flex flex-wrap gap-2">
        <button
          type="button"
          onClick={() => onSave(edit)}
          disabled={saving}
          className="flex items-center gap-1 rounded border border-cyan-600 bg-cyan-950/50 px-3 py-1.5 text-sm text-cyan-400 hover:bg-cyan-900/40 disabled:opacity-50"
        >
          <Save className="h-4 w-4" />
          保存
        </button>
        <button
          type="button"
          onClick={onClearOverrides}
          disabled={saving}
          className="rounded border border-military-border px-3 py-1.5 text-sm text-military-text-secondary hover:bg-military-border/30 disabled:opacity-50"
        >
          恢复实时统计
        </button>
      </div>
    </div>
  )
}
