import { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useAtomValue } from 'jotai'
import type { CockpitSummary, PublishStatus } from '@shared/types'
import { useAppStore } from '@renderer/stores/useAppStore'
import { useBookStore } from '@renderer/stores/useBookStore'
import { useEditStore } from '@renderer/stores/useEditStore'
import { useOutlineStore } from '@renderer/stores/useOutlineStore'
import { useReferenceStore } from '@renderer/stores/useReferenceStore'
import { useSettingsStore } from '@renderer/stores/useSettingsStore'
import { useCockpitStore } from '@renderer/stores/useCockpitStore'
import { useWritingStatsStore } from '@renderer/stores/useWritingStatsStore'
import { usePomodoroStore, formatPomodoroTime } from '@renderer/stores/usePomodoroStore'
import { ipcCall } from '@renderer/lib/ipc-client'
import { TipTapEditor, flushEditorSave } from '@renderer/components/editor/TipTapEditor'
import { insertLandmarkInEditor } from '@renderer/lib/editor-commands'
import { RightPanel } from '@renderer/components/layout/RightPanel'
import { ReferencePanel } from '@renderer/components/reference/ReferencePanel'
import { OutlineTree } from '@renderer/components/outline/OutlineTree'
import { OutlineCompareView } from '@renderer/components/outline/OutlineCompareView'
import { SettingList } from '@renderer/components/setting/SettingList'
import { InspirationList } from '@renderer/components/inspiration/InspirationList'
import { VersionModal } from '@renderer/components/version/VersionModal'
import { LandmarkModal } from '@renderer/components/landmark/LandmarkModal'
import { CockpitModal } from '@renderer/components/cockpit/CockpitModal'
import { CharacterGraphModal } from '@renderer/components/graph/CharacterGraphModal'
import { ChapterBridgeModal } from '@renderer/components/bridge/ChapterBridgeModal'
import { TemplateQuickCreateModal } from '@renderer/components/chapter/TemplateQuickCreateModal'
import { ChapterMetaPanel } from '@renderer/components/chapter/ChapterMetaPanel'
import { VolumeContextMenu } from '@renderer/components/volume/VolumeContextMenu'
import { useReadModeStore } from '@renderer/stores/useReadModeStore'
import { ExportModal } from '@renderer/components/export/ExportModal'
import { useExportStore } from '@renderer/stores/useExportStore'
import {
  editorDirtyAtom,
  editorSavingAtom,
  lastSavedAtAtom,
  wordCountAtom
} from '@renderer/atoms/editorAtoms'

const PUBLISH_CYCLE: PublishStatus[] = ['draft', 'ready', 'published']

function nextPublishStatus(current: PublishStatus | undefined): PublishStatus {
  const idx = PUBLISH_CYCLE.indexOf(current ?? 'draft')
  return PUBLISH_CYCLE[(idx + 1) % PUBLISH_CYCLE.length]
}

function publishIcon(status: PublishStatus | undefined): string {
  if (status === 'ready') return '📦'
  if (status === 'published') return '✅'
  return '📝'
}

function useDocumentTitle(): string {
  const target = useEditStore((s) => s.target)
  const chapters = useBookStore((s) => s.chapters)
  const outlines = useBookStore((s) => s.outlines)
  const settings = useBookStore((s) => s.settings)
  const inspirations = useBookStore((s) => s.inspirations)

  return useMemo(() => {
    if (!target) return '—'
    if (target.kind === 'chapter') {
      return chapters.find((c) => c.id === target.id)?.title ?? '—'
    }
    if (target.kind === 'outline') {
      return outlines.find((o) => o.id === target.id)?.title ?? '—'
    }
    if (target.kind === 'setting') {
      return settings.find((s) => s.id === target.id)?.name ?? '—'
    }
    return inspirations.find((i) => i.id === target.id)?.title ?? '—'
  }, [target, chapters, outlines, settings, inspirations])
}

export function EditorLayout(): React.JSX.Element {
  const { t } = useTranslation()
  const showToast = useAppStore((s) => s.showToast)
  const setSidebarPanel = useAppStore((s) => s.setSidebarPanel)
  const activePanel = useAppStore((s) => s.sidebarPanel)
  const versionModalOpen = useAppStore((s) => s.versionModalOpen)
  const landmarksModalOpen = useAppStore((s) => s.landmarksModalOpen)
  const setVersionModalOpen = useAppStore((s) => s.setVersionModalOpen)
  const setLandmarksModalOpen = useAppStore((s) => s.setLandmarksModalOpen)
  const compareMode = useOutlineStore((s) => s.compareMode)
  const referenceOpen = useReferenceStore((s) => s.open)
  const setReferenceOpen = useReferenceStore((s) => s.setOpen)
  const {
    currentBookId,
    volumes,
    chapters,
    selectedChapterId,
    activeVolumeId,
    setSelectedChapter,
    setActiveVolume,
    refreshChapters
  } = useBookStore()
  const target = useEditStore((s) => s.target)
  const switchTarget = useEditStore((s) => s.switchTarget)
  const setTarget = useEditStore((s) => s.setTarget)
  const updateSchedule = useSettingsStore((s) => s.updateSchedule)
  const dailyWordGoal = useSettingsStore((s) => s.dailyWordGoal)
  const writingStats = useWritingStatsStore((s) => s.stats)
  const refreshWritingStats = useWritingStatsStore((s) => s.refresh)
  const pomodoroRunning = usePomodoroStore((s) => s.running)
  const pomodoroPaused = usePomodoroStore((s) => s.paused)
  const pomodoroRemaining = usePomodoroStore((s) => s.remainingSec)
  const pomodoroBookId = usePomodoroStore((s) => s.bookId)
  const pomodoroInit = usePomodoroStore((s) => s.init)
  const pomodoroStart = usePomodoroStore((s) => s.start)
  const pomodoroPause = usePomodoroStore((s) => s.pause)
  const pomodoroResume = usePomodoroStore((s) => s.resume)
  const pomodoroCancel = usePomodoroStore((s) => s.cancel)
  const bridgeChapterId = useCockpitStore((s) => s.bridgeChapterId)
  const clearBridgeChapter = useCockpitStore((s) => s.clearBridgeChapter)
  const updateChapterLocal = useBookStore((s) => s.updateChapterLocal)
  const settings = useBookStore((s) => s.settings)

  const dirty = useAtomValue(editorDirtyAtom)
  const saving = useAtomValue(editorSavingAtom)
  const lastSaved = useAtomValue(lastSavedAtAtom)
  const wordCount = useAtomValue(wordCountAtom)
  const documentTitle = useDocumentTitle()

  const [bridgeOpen, setBridgeOpen] = useState(false)
  const [templateModalOpen, setTemplateModalOpen] = useState(false)
  const [chapterMetaOpen, setChapterMetaOpen] = useState(false)
  const openReadMode = useReadModeStore((s) => s.openForVolume)
  const setTimelineModalOpen = useAppStore((s) => s.setTimelineModalOpen)
  const [volumeMenu, setVolumeMenu] = useState<{ volumeId: string; x: number; y: number } | null>(
    null
  )
  const [renamingChapterId, setRenamingChapterId] = useState<string | null>(null)
  const [renameDraft, setRenameDraft] = useState('')
  const [cockpitSummary, setCockpitSummary] = useState<CockpitSummary | null>(null)

  const bookMeta = useBookStore.getState().books.find((b) => b.id === currentBookId)
  const isChapterTarget = target?.kind === 'chapter'
  const chapterId = target?.kind === 'chapter' ? target.id : selectedChapterId
  const currentChapter = isChapterTarget && chapterId ? chapters.find((c) => c.id === chapterId) : null
  const characterSettings = settings.filter((s) => s.type === 'character')

  const handlePovChange = async (povCharacterId: string | null): Promise<void> => {
    if (!currentBookId || !chapterId) return
    const updated = await ipcCall(() =>
      window.electronAPI.chapter.update({
        bookId: currentBookId,
        chapterId,
        povCharacterId
      })
    )
    updateChapterLocal(updated)
  }

  useEffect(() => {
    void pomodoroInit()
  }, [pomodoroInit])

  useEffect(() => {
    if (!pomodoroRunning || !pomodoroBookId || !currentBookId) return
    if (pomodoroBookId === currentBookId) return
    void pomodoroCancel()
  }, [currentBookId, pomodoroRunning, pomodoroBookId, pomodoroCancel])

  useEffect(() => {
    if (!selectedChapterId) return
    if (
      target?.kind === 'setting' ||
      target?.kind === 'outline' ||
      target?.kind === 'inspiration'
    ) {
      return
    }
    if (target?.kind === 'chapter' && target.id === selectedChapterId) return
    setTarget({ kind: 'chapter', id: selectedChapterId })
  }, [selectedChapterId, setTarget, target?.kind, target?.id])

  useEffect(() => {
    if (!currentBookId || target?.kind !== 'chapter') return
    const chapterId = target.id
    void ipcCall(() => window.electronAPI.snapshot.startAutoSave(currentBookId, chapterId))
    return () => {
      void ipcCall(() => window.electronAPI.snapshot.stopAutoSave(currentBookId, chapterId))
    }
  }, [currentBookId, target?.kind, target?.id])

  useEffect(() => {
    if (!currentBookId) return
    void refreshWritingStats(currentBookId)
  }, [currentBookId, lastSaved, refreshWritingStats])

  useEffect(() => {
    if (!currentBookId) return
    void ipcCall(() =>
      window.electronAPI.cockpit.getSummary(currentBookId, activeVolumeId ?? undefined)
    ).then(setCockpitSummary)
  }, [currentBookId, activeVolumeId, chapters])

  useEffect(() => {
    if (bridgeChapterId) setBridgeOpen(true)
  }, [bridgeChapterId])

  useEffect(() => {
    if (!currentBookId || target?.kind !== 'chapter') return
    const chapterId = target.id
    void ipcCall(() => window.electronAPI.bridge.shouldPrompt(currentBookId, chapterId)).then(
      (should) => {
        if (should) setTimeout(() => setBridgeOpen(true), 500)
      }
    )
  }, [currentBookId, target?.kind, target?.id])

  const activeBridgeChapterId =
    bridgeChapterId ?? (target?.kind === 'chapter' ? target.id : selectedChapterId)

  const showStockWarning =
    updateSchedule !== 'none' &&
    cockpitSummary != null &&
    cockpitSummary.stockReadyCount < cockpitSummary.stockThreshold

  const handlePublishCycle = async (chapterId: string, e: React.MouseEvent): Promise<void> => {
    e.stopPropagation()
    if (!currentBookId) return
    const ch = chapters.find((c) => c.id === chapterId)
    if (!ch) return
    const next = nextPublishStatus(ch.publishStatus)
    const updated = await ipcCall(() =>
      window.electronAPI.chapter.setPublishStatus(currentBookId, chapterId, next)
    )
    updateChapterLocal(updated)
  }

  const handleSelectChapter = async (chapterId: string): Promise<void> => {
    setSelectedChapter(chapterId)
    await switchTarget({ kind: 'chapter', id: chapterId })
  }

  const handleNewChapter = async (): Promise<void> => {
    if (!currentBookId || !activeVolumeId) return
    await flushEditorSave()
    const ch = await ipcCall(() =>
      window.electronAPI.chapter.create(currentBookId, activeVolumeId, t('editor.newChapter'))
    )
    await refreshChapters()
    setSelectedChapter(ch.id)
    await switchTarget({ kind: 'chapter', id: ch.id })
  }

  const handleNewVolume = async (): Promise<void> => {
    if (!currentBookId) return
    const vol = await ipcCall(() =>
      window.electronAPI.volume.create(currentBookId, t('editor.newVolume'))
    )
    await refreshChapters()
    setActiveVolume(vol.id)
  }

  const commitChapterRename = async (chapterId: string): Promise<void> => {
    if (!currentBookId) return
    const ch = chapters.find((c) => c.id === chapterId)
    const title = renameDraft.trim()
    setRenamingChapterId(null)
    if (!ch || !title || title === ch.title) return
    const updated = await ipcCall(() =>
      window.electronAPI.chapter.update({ bookId: currentBookId, chapterId, title })
    )
    updateChapterLocal(updated)
  }

  const handleDeleteChapter = async (chapterId: string, e: React.MouseEvent): Promise<void> => {
    e.stopPropagation()
    if (!currentBookId) return
    const ch = chapters.find((c) => c.id === chapterId)
    if (!ch || !window.confirm(t('chapter.deleteConfirm', { title: ch.title }))) return
    await flushEditorSave()
    await ipcCall(() => window.electronAPI.chapter.delete(currentBookId, chapterId))
    await refreshChapters()
    if (selectedChapterId === chapterId) {
      const remaining = chapters.filter((c) => c.id !== chapterId)
      const next = remaining.find((c) => c.volumeId === ch.volumeId) ?? remaining[0]
      if (next) {
        setSelectedChapter(next.id)
        await switchTarget({ kind: 'chapter', id: next.id })
      }
    }
  }

  const [dragOverChapterId, setDragOverChapterId] = useState<string | null>(null)

  const handleChapterDropOnItem = async (
    draggedId: string,
    targetVolumeId: string,
    targetChapterId: string
  ): Promise<void> => {
    if (!currentBookId || draggedId === targetChapterId) return
    await flushEditorSave()
    const dragged = chapters.find((c) => c.id === draggedId)
    if (!dragged) return
    const volChapters = chapters
      .filter((c) => c.volumeId === targetVolumeId)
      .sort((a, b) => a.sortOrder - b.sortOrder)
    const targetIdx = volChapters.findIndex((c) => c.id === targetChapterId)
    if (dragged.volumeId === targetVolumeId) {
      const ids = volChapters.map((c) => c.id)
      const from = ids.indexOf(draggedId)
      if (from < 0) return
      ids.splice(from, 1)
      const insertAt = ids.indexOf(targetChapterId)
      ids.splice(insertAt, 0, draggedId)
      await ipcCall(() => window.electronAPI.chapter.reorder(currentBookId, targetVolumeId, ids))
    } else {
      await ipcCall(() =>
        window.electronAPI.chapter.moveToVolume(
          currentBookId,
          draggedId,
          targetVolumeId,
          Math.max(0, targetIdx)
        )
      )
    }
    await refreshChapters()
  }

  const handleChapterDropOnVolume = async (draggedId: string, targetVolumeId: string): Promise<void> => {
    if (!currentBookId) return
    await flushEditorSave()
    const dragged = chapters.find((c) => c.id === draggedId)
    if (!dragged) return
    const targetLen = chapters.filter((c) => c.volumeId === targetVolumeId).length
    if (dragged.volumeId === targetVolumeId) return
    await ipcCall(() =>
      window.electronAPI.chapter.moveToVolume(currentBookId, draggedId, targetVolumeId, targetLen)
    )
    await refreshChapters()
  }

  const handleInsertLandmark = async (): Promise<void> => {
    if (!currentBookId || target?.kind !== 'chapter') {
      showToast(t('landmark.chapterOnly'))
      return
    }
    const label = prompt(t('landmark.prompt'))
    if (!label?.trim()) return
    const isForeshadow = confirm(t('landmark.foreshadowConfirm'))
    const landmarkType = isForeshadow ? 'foreshadow' : 'todo'
    const syncKnowledge = isForeshadow && confirm(t('knowledge.syncFromLandmark'))
    insertLandmarkInEditor({ label: label.trim(), landmarkType })
    const bm = await ipcCall(() =>
      window.electronAPI.bookmark.create(currentBookId, target.id, 0, label.trim(), landmarkType)
    )
    if (syncKnowledge) {
      await ipcCall(() => window.electronAPI.knowledge.createFromBookmark(currentBookId, bm.id))
      showToast(t('knowledge.syncedFromLandmark'))
    } else {
      showToast(t('landmark.created'))
    }
  }

  const saveStatus = saving ? t('editor.saving') : dirty ? t('editor.unsaved') : t('editor.saved')
  const chapterOverThreshold =
    currentChapter?.wordCountThreshold != null &&
    wordCount.chapter > currentChapter.wordCountThreshold
  const volumeMenuVolume = volumeMenu
    ? volumes.find((v) => v.id === volumeMenu.volumeId)
    : null

  return (
    <div id="editor-layout" data-book-id={currentBookId ?? ''}>
      <div id="left-sidebar">
        <div className="sidebar-header">{bookMeta?.name ?? '—'}</div>
        <div className="sidebar-nav">
          {(['chapters', 'outline', 'setting', 'inspiration'] as const).map((panel) => (
            <button
              key={panel}
              type="button"
              data-testid={`sidebar-tab-${panel}`}
              className={`nav-btn ${activePanel === panel ? 'active' : ''}`}
              onClick={() => setSidebarPanel(panel)}
            >
              {panel === 'chapters' && t('sidebar.chapters')}
              {panel === 'outline' && t('sidebar.outline')}
              {panel === 'setting' && t('sidebar.settings')}
              {panel === 'inspiration' && t('sidebar.inspiration')}
            </button>
          ))}
        </div>
        <div className={`sidebar-panel ${activePanel === 'chapters' ? 'active' : ''}`}>
          {volumes.map((vol) => (
            <div key={vol.id}>
              <div
                className="vol-header"
                data-volume-id={vol.id}
                onClick={() => setActiveVolume(vol.id)}
                onContextMenu={(e) => {
                  e.preventDefault()
                  setVolumeMenu({ volumeId: vol.id, x: e.clientX, y: e.clientY })
                }}
                onDragOver={(e) => e.preventDefault()}
                onDrop={(e) => {
                  e.preventDefault()
                  const draggedId = e.dataTransfer.getData('application/x-bilin-chapter')
                  if (draggedId) void handleChapterDropOnVolume(draggedId, vol.id)
                }}
                style={{ color: activeVolumeId === vol.id ? 'var(--accent-light)' : undefined }}
              >
                {vol.name}
              </div>
              {chapters
                .filter((c) => c.volumeId === vol.id)
                .map((ch, idx) => (
                  <div
                    key={ch.id}
                    className={`chapter-item ${target?.kind === 'chapter' && target.id === ch.id ? 'active' : ''} ${dragOverChapterId === ch.id ? 'drag-over' : ''}`}
                    draggable
                    data-testid={`chapter-item-${ch.id}`}
                    title={
                      ch.summary?.trim() ||
                      ch.content.replace(/<[^>]+>/g, '').trim().slice(0, 80) ||
                      undefined
                    }
                    onDragStart={(e) => {
                      e.dataTransfer.setData('application/x-bilin-chapter', ch.id)
                      e.dataTransfer.effectAllowed = 'move'
                    }}
                    onDragOver={(e) => {
                      e.preventDefault()
                      setDragOverChapterId(ch.id)
                    }}
                    onDragLeave={() => setDragOverChapterId(null)}
                    onDrop={(e) => {
                      e.preventDefault()
                      setDragOverChapterId(null)
                      const draggedId = e.dataTransfer.getData('application/x-bilin-chapter')
                      if (draggedId) void handleChapterDropOnItem(draggedId, vol.id, ch.id)
                    }}
                    onClick={() => void handleSelectChapter(ch.id)}
                    onDoubleClick={(e) => {
                      e.stopPropagation()
                      setRenamingChapterId(ch.id)
                      setRenameDraft(ch.title)
                    }}
                    onKeyDown={(e) => e.key === 'Enter' && void handleSelectChapter(ch.id)}
                    role="button"
                    tabIndex={0}
                  >
                    <span>{idx + 1}.</span>
                    {renamingChapterId === ch.id ? (
                      <input
                        className="chapter-rename-input"
                        data-testid={`chapter-rename-${ch.id}`}
                        value={renameDraft}
                        autoFocus
                        onClick={(e) => e.stopPropagation()}
                        onChange={(e) => setRenameDraft(e.target.value)}
                        onBlur={() => void commitChapterRename(ch.id)}
                        onKeyDown={(e) => {
                          if (e.key === 'Enter') void commitChapterRename(ch.id)
                          if (e.key === 'Escape') setRenamingChapterId(null)
                        }}
                      />
                    ) : (
                      <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis' }}>
                        {ch.title}
                      </span>
                    )}
                    <button
                      type="button"
                      className="ch-delete-btn"
                      title={t('chapter.delete')}
                      data-testid={`chapter-delete-${ch.id}`}
                      onClick={(e) => void handleDeleteChapter(ch.id, e)}
                    >
                      ×
                    </button>
                    <button
                      type="button"
                      className="ch-publish-btn"
                      title={t(`publish.status.${ch.publishStatus ?? 'draft'}`)}
                      data-testid={`chapter-publish-${ch.id}`}
                      onClick={(e) => void handlePublishCycle(ch.id, e)}
                    >
                      {publishIcon(ch.publishStatus)}
                    </button>
                    <span className={`ch-badge ${ch.status === 'done' ? 'done' : 'draft'}`}>{ch.status}</span>
                  </div>
                ))}
            </div>
          ))}
          {activePanel === 'chapters' && (
            <div className="sidebar-footer">
              {selectedChapterId && currentBookId && (
                <button
                  type="button"
                  data-testid="chapter-extract-knowledge"
                  onClick={() =>
                    void ipcCall(() =>
                      window.electronAPI.knowledge.extractChapter(currentBookId, selectedChapterId)
                    )
                  }
                >
                  {t('knowledge.extractChapter')}
                </button>
              )}
              <button type="button" onClick={() => void handleNewChapter()}>
                + {t('editor.newChapter')}
              </button>
              <button
                type="button"
                data-testid="chapter-quick-new"
                style={{ marginTop: 6 }}
                onClick={() => setTemplateModalOpen(true)}
              >
                + {t('template.quickNew')}
              </button>
              <button
                type="button"
                data-testid="open-timeline"
                style={{ marginTop: 6 }}
                onClick={() => setTimelineModalOpen(true)}
              >
                🕐 {t('timeline.open')}
              </button>
              <button
                type="button"
                data-testid="chapter-read-mode"
                style={{ marginTop: 6 }}
                disabled={!activeVolumeId}
                onClick={() => {
                  if (!activeVolumeId) return
                  const idx = chapters
                    .filter((c) => c.volumeId === activeVolumeId)
                    .sort((a, b) => a.sortOrder - b.sortOrder)
                    .findIndex((c) => c.id === selectedChapterId)
                  openReadMode(activeVolumeId, Math.max(0, idx))
                }}
              >
                👁 {t('readMode.open')}
              </button>
              <button type="button" style={{ marginTop: 6 }} onClick={() => void handleNewVolume()}>
                + {t('editor.newVolume')}
              </button>
            </div>
          )}
        </div>
        <div className={`sidebar-panel ${activePanel === 'outline' ? 'active' : ''}`}>
          {activePanel === 'outline' && <OutlineTree />}
        </div>
        <div className={`sidebar-panel ${activePanel === 'setting' ? 'active' : ''}`}>
          {activePanel === 'setting' && <SettingList />}
        </div>
        <div className={`sidebar-panel ${activePanel === 'inspiration' ? 'active' : ''}`}>
          {activePanel === 'inspiration' && <InspirationList />}
        </div>
      </div>
      <div id="editor-area">
        {compareMode ? (
          <OutlineCompareView />
        ) : (
          <>
            <div id="editor-toolbar">
              <button
                type="button"
                className="tool-btn"
                title={t('export.title')}
                data-testid="open-export"
                disabled={!isChapterTarget}
                onClick={() => useExportStore.getState().openModal()}
              >
                📦
              </button>
              <button
                type="button"
                className="tool-btn"
                title={t('reference.title')}
                data-testid="open-reference"
                onClick={() => setReferenceOpen(true)}
              >
                📎
              </button>
              <button
                type="button"
                className="tool-btn"
                title={t('version.title')}
                data-testid="open-version"
                onClick={() => setVersionModalOpen(true)}
              >
                📜
              </button>
              <button
                type="button"
                className="tool-btn"
                title={t('landmark.insert')}
                data-testid="insert-landmark"
                onClick={() => void handleInsertLandmark()}
              >
                📌
              </button>
              <span className="editor-label">{documentTitle}</span>
            </div>
            <TipTapEditor
              key={target ? `${target.kind}:${target.id}` : 'none'}
              target={target}
              bookId={currentBookId}
            />
            <div id="editor-statusbar">
              <div className="pomodoro-control" data-testid="pomodoro-control">
                {!pomodoroRunning ? (
                  <button
                    type="button"
                    className="pomodoro-btn"
                    title={t('pomodoro.start')}
                    disabled={!currentBookId}
                    onClick={() => currentBookId && void pomodoroStart(currentBookId)}
                  >
                    ▶
                  </button>
                ) : (
                  <>
                    <button
                      type="button"
                      className="pomodoro-btn"
                      title={pomodoroPaused ? t('pomodoro.resume') : t('pomodoro.pause')}
                      onClick={() => void (pomodoroPaused ? pomodoroResume() : pomodoroPause())}
                    >
                      {pomodoroPaused ? '▶' : '⏸'}
                    </button>
                    <span className="pomodoro-time">{formatPomodoroTime(pomodoroRemaining)}</span>
                    <button
                      type="button"
                      className="pomodoro-btn"
                      title={t('pomodoro.cancel')}
                      onClick={() => void pomodoroCancel()}
                    >
                      ✕
                    </button>
                  </>
                )}
              </div>
              <span>{saveStatus}{lastSaved ? ` · ${lastSaved.toLocaleTimeString()}` : ''}</span>
              {dailyWordGoal > 0 && writingStats && (
                <span
                  className={`status-daily-goal ${
                    writingStats.goalProgress >= 1
                      ? 'goal-met'
                      : writingStats.goalProgress >= 0.8
                        ? 'goal-near'
                        : ''
                  }`}
                  data-testid="status-daily-goal"
                >
                  {t('status.dailyGoal', {
                    current: writingStats.todayWords,
                    goal: dailyWordGoal
                  })}
                </span>
              )}
              {showStockWarning && (
                <span className="status-stock-warning" data-testid="status-stock-warning">
                  {t('stock.warning', {
                    count: cockpitSummary!.stockReadyCount,
                    threshold: cockpitSummary!.stockThreshold
                  })}
                </span>
              )}
              {isChapterTarget ? (
                <>
                  <label className="status-pov-label">
                    {t('chapter.pov')}
                    <select
                      data-testid="chapter-pov-select"
                      value={currentChapter?.povCharacterId ?? ''}
                      onChange={(e) => void handlePovChange(e.target.value || null)}
                    >
                      <option value="">{t('analytics.povUnassigned')}</option>
                      {characterSettings.map((c) => (
                        <option key={c.id} value={c.id}>
                          {c.name}
                        </option>
                      ))}
                    </select>
                  </label>
                  <button
                    type="button"
                    className="btn btn-sm status-meta-btn"
                    data-testid="chapter-meta-open"
                    onClick={() => setChapterMetaOpen(true)}
                  >
                    {t('chapterMeta.open')}
                  </button>
                  {currentChapter?.publishStatus === 'published' && currentChapter.publishedAt && (
                    <span className="status-published-at" data-testid="status-published-at">
                      {t('chapterMeta.publishedAt', {
                        date: new Date(currentChapter.publishedAt).toLocaleString('zh-CN')
                      })}
                    </span>
                  )}
                  <span
                    className={chapterOverThreshold ? 'status-word-over-threshold' : undefined}
                    data-testid="status-chapter-words"
                  >
                    {t('status.chapter')}: {t('editor.words', { count: wordCount.chapter })}
                  </span>
                  <span>{t('status.volume')}: {t('editor.words', { count: wordCount.volume })}</span>
                  <span>{t('status.book')}: {t('editor.words', { count: wordCount.book })}</span>
                </>
              ) : (
                <span>{t('editor.words', { count: wordCount.chapter })}</span>
              )}
            </div>
          </>
        )}
      </div>
      <ReferencePanel />
      {!referenceOpen && <RightPanel />}
      <VersionModal
        open={versionModalOpen}
        onClose={() => setVersionModalOpen(false)}
        chapterId={chapterId}
      />
      <LandmarkModal open={landmarksModalOpen} onClose={() => setLandmarksModalOpen(false)} />
      <CockpitModal
        onOpenBridge={(chapterId) => {
          useCockpitStore.getState().openBridgeForChapter(chapterId)
          setBridgeOpen(true)
        }}
      />
      <CharacterGraphModal />
      <ChapterBridgeModal
        open={bridgeOpen}
        chapterId={activeBridgeChapterId}
        onClose={() => {
          setBridgeOpen(false)
          clearBridgeChapter()
        }}
      />
      <TemplateQuickCreateModal
        open={templateModalOpen}
        onClose={() => setTemplateModalOpen(false)}
      />
      <ChapterMetaPanel
        open={chapterMetaOpen}
        chapter={currentChapter}
        onClose={() => setChapterMetaOpen(false)}
      />
      {volumeMenu && volumeMenuVolume && currentBookId && (
        <VolumeContextMenu
          bookId={currentBookId}
          volume={volumeMenuVolume}
          hasChapters={chapters.some((c) => c.volumeId === volumeMenuVolume.id)}
          x={volumeMenu.x}
          y={volumeMenu.y}
          onOpenReadMode={() => openReadMode(volumeMenuVolume.id, 0)}
          onClose={() => setVolumeMenu(null)}
          onChanged={refreshChapters}
        />
      )}
      <ExportModal />
    </div>
  )
}
