<!-- =====================================================================
  App.vue — 根组件：编辑/演示模式切换、工具栏、三栏布局、弹窗
  ===================================================================== -->
<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { store } from './core/store'
import Toolbar from './components/editor/Toolbar.vue'
import ThumbBar from './components/editor/ThumbBar.vue'
import Canvas from './components/editor/Canvas.vue'
import PropsPanel from './components/editor/PropsPanel.vue'
import AiPanel from './components/ai/AiPanel.vue'
import SettingsModal from './components/modals/SettingsModal.vue'
import LibraryModal from './components/modals/LibraryModal.vue'
import TemplateModal from './components/modals/TemplateModal.vue'
import PresentMode from './components/present/PresentMode.vue'

/* ---------- 模式 ---------- */
const mode = ref<'editor' | 'present'>('editor')
const presentVisible = ref(false)
const presentStartIndex = ref(0)

/* ---------- 活动面板 tab ---------- */
const activeTab = ref<'props' | 'ai'>('props')
function switchTab(name: 'props' | 'ai') {
  activeTab.value = name
}

/* ---------- 弹窗 ---------- */
const settingsVisible = ref(false)
const libraryVisible = ref(false)
const templateVisible = ref(false)

/* ---------- toast ---------- */
const toastText = ref('')
const toastShow = ref(false)
let toastTimer: ReturnType<typeof setTimeout> | null = null
function toast(msg: string) {
  toastText.value = msg
  toastShow.value = true
  if (toastTimer) clearTimeout(toastTimer)
  toastTimer = setTimeout(() => { toastShow.value = false }, 2200)
}

/* ---------- AI busy 状态（禁用部分按钮） ---------- */
const aiBusy = ref(false)
const disabledActions = computed(() => aiBusy.value
  ? ['present', 'library', 'save', 'reset', 'add-slide', 'dup-slide', 'del-slide']
  : []
)
function onBusyChange(busy: boolean) { aiBusy.value = busy }

/* ---------- 工具栏动作 ---------- */
function onPresent() {
  presentStartIndex.value = store.currentIndex.value
  presentVisible.value = true
  mode.value = 'present'
  document.body.dataset.mode = 'present'
}
function onPresentExit() {
  presentVisible.value = false
  mode.value = 'editor'
  document.body.dataset.mode = 'editor'
}
function onSave() {
  if (store.getActiveLibId()) {
    store.saveToLibrary()
    toast('已更新到文库')
  } else {
    libraryVisible.value = true
  }
}
function openAi() { switchTab('ai') }

/* ---------- 导出/导入 ---------- */
function onExportJson() {
  const json = store.exportJSON()
  const blob = new Blob([json], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = 'u-ppt-export.json'
  a.click()
  URL.revokeObjectURL(url)
  toast('已导出 JSON')
}

function onImportJson() {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.json,application/json'
  input.onchange = () => {
    const file = input.files?.[0]
    if (!file) return
    const reader = new FileReader()
    reader.onload = () => {
      try {
        store.importJSON(reader.result as string)
        toast('已导入')
      } catch (e: any) {
        toast('导入失败：' + (e?.message || String(e)))
      }
    }
    reader.readAsText(file)
  }
  input.click()
}

function onExportPdf() {
  // 用浏览器打印 + @media print CSS 实现 PDF 导出
  // 演示模式的 slide-layer 已有 print 样式
  document.body.classList.add('printing')
  window.print()
  setTimeout(() => document.body.classList.remove('printing'), 500)
  toast('在打印对话框中选择「另存为 PDF」')
}

/* ---------- 全局快捷键（编辑模式） ---------- */
function onKey(e: KeyboardEvent) {
  if (document.body.dataset.mode === 'present') return
  const inField = /^(INPUT|TEXTAREA|SELECT)$/.test((e.target as HTMLElement).tagName) || (e.target as HTMLElement).isContentEditable

  if (e.key === 'Escape') {
    if (settingsVisible.value) { settingsVisible.value = false; return }
    if (libraryVisible.value) { libraryVisible.value = false; return }
  }

  if ((e.ctrlKey || e.metaKey) && (e.key === 'z' || e.key === 'Z')) {
    if (inField) return
    e.preventDefault()
    if (e.shiftKey ? store.redo() : store.undo()) toast(e.shiftKey ? '已重做' : '已撤销')
    return
  }
  if ((e.ctrlKey || e.metaKey) && (e.key === 'y' || e.key === 'Y')) {
    if (inField) return; e.preventDefault(); if (store.redo()) toast('已重做'); return
  }
  if ((e.ctrlKey || e.metaKey) && e.key === 's') {
    e.preventDefault(); if (!inField) toast('已自动保存到本地'); return
  }

  if (e.key === 'Delete' && !inField) {
    const id = store.getSelectedId()
    if (id) { e.preventDefault(); store.delElement(id) }
  }
}

onMounted(() => {
  document.addEventListener('keydown', onKey)
})
onUnmounted(() => {
  document.removeEventListener('keydown', onKey)
})
</script>

<template>
  <!-- ===================== 编辑模式 ===================== -->
  <div v-show="mode === 'editor'" class="app-editor">
    <Toolbar
      :disabled-actions="disabledActions"
      @present="onPresent"
      @open-library="libraryVisible = true"
      @open-settings="settingsVisible = true"
      @open-ai="openAi"
      @save="onSave"
      @open-templates="templateVisible = true"
      @export-json="onExportJson"
      @import-json="onImportJson"
      @export-pdf="onExportPdf"
    />

    <div class="editor-body">
      <!-- 左：缩略图 -->
      <ThumbBar />

      <!-- 中：画布 -->
      <Canvas />

      <!-- 右：Tabs（属性 / AI） -->
      <aside class="side-panel">
        <div class="panel-tabs">
          <button class="panel-tab" :class="{ active: activeTab === 'props' }" @click="switchTab('props')">🎨 属性</button>
          <button class="panel-tab" :class="{ active: activeTab === 'ai' }" @click="switchTab('ai')">🤖 AI 助手</button>
        </div>

        <PropsPanel v-show="activeTab === 'props'" />

        <AiPanel
          v-show="activeTab === 'ai'"
          @busy-change="onBusyChange"
          @toast="toast"
          @open-settings="settingsVisible = true"
          @switch-tab="(t: string) => switchTab(t as 'props' | 'ai')"
        />
      </aside>
    </div>
  </div>

  <!-- ===================== 演示模式 ===================== -->
  <PresentMode
    :visible="presentVisible"
    :start-index="presentStartIndex"
    @exit="onPresentExit"
  />

  <!-- ===================== 弹窗 ===================== -->
  <SettingsModal
    :visible="settingsVisible"
    @close="settingsVisible = false"
    @toast="toast"
  />
  <LibraryModal
    :visible="libraryVisible"
    @close="libraryVisible = false"
    @toast="toast"
    @switch-tab="(t: string) => switchTab(t as 'props' | 'ai')"
  />
  <TemplateModal
    :visible="templateVisible"
    @close="templateVisible = false"
    @toast="toast"
  />

  <!-- 轻提示 -->
  <div class="toast" :class="{ show: toastShow }">{{ toastText }}</div>
</template>
