<!-- =====================================================================
  Toolbar.vue — 顶部工具栏
  信息架构分层：高频创作动作直接暴露；文件域（库/存取/导出）收进「文件」菜单
  ===================================================================== -->
<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { store } from '../../core/store'
import { themes } from '../../core/sample'
import { appConfirm } from '../../core/dialog'
import Icon from '../common/Icon.vue'

const emit = defineEmits<{
  (e: 'present'): void
  (e: 'open-library'): void
  (e: 'open-settings'): void
  (e: 'save'): void
  (e: 'open-templates'): void
  (e: 'export-json'): void
  (e: 'import-json'): void
  (e: 'import-materials'): void
  (e: 'export-pdf'): void
  (e: 'home'): void
  (e: 'share'): void
}>()

const themeKeys = Object.keys(themes)
const currentTheme = ref(store.getTheme())

// store 主题变化时同步下拉
watch(() => store.theme.value, (v) => { currentTheme.value = v })

function onThemeChange() {
  store.setTheme(currentTheme.value)
}

async function action(a: string) {
  switch (a) {
    case 'add-slide': store.addSlide(store.getCurrentIndex()); break
    case 'dup-slide': store.dupSlide(); break
    case 'del-slide':
      if (await appConfirm('删除这页幻灯片？', '第 ' + (store.getCurrentIndex() + 1) + ' 页，可用 Ctrl+Z 撤销', { danger: true, okText: '删除' })) {
        store.delSlide()
      }
      break
    case 'reset':
      if (await appConfirm('重置为内置示例？', '当前编辑内容将丢失（可用 Ctrl+Z 撤销）', { danger: true })) {
        store.reset()
      }
      break
    case 'present': emit('present'); break
    case 'library': emit('open-library'); break
    case 'save': emit('save'); break
    case 'settings': emit('open-settings'); break
  }
}

/* ---------- 文件菜单（低频动作收纳） ---------- */
const fileMenuOpen = ref(false)
const fileMenuBtn = ref<HTMLElement>()

function toggleFileMenu() {
  fileMenuOpen.value = !fileMenuOpen.value
}

function fileAction(a: string) {
  fileMenuOpen.value = false
  switch (a) {
    case 'library': emit('open-library'); break
    case 'save': emit('save'); break
    case 'export-json': emit('export-json'); break
    case 'import-materials': emit('import-materials'); break
    case 'import-json': emit('import-json'); break
    case 'export-pdf': emit('export-pdf'); break
    case 'share': emit('share'); break
    case 'reset': action('reset'); break
  }
}

function onDocClick(e: MouseEvent) {
  if (fileMenuOpen.value && fileMenuBtn.value && !fileMenuBtn.value.contains(e.target as Node)) {
    fileMenuOpen.value = false
  }
}
function onKeydown(e: KeyboardEvent) {
  if (e.key === 'Escape' && fileMenuOpen.value) fileMenuOpen.value = false
}

onMounted(() => {
  document.addEventListener('mousedown', onDocClick)
  document.addEventListener('keydown', onKeydown)
})
onUnmounted(() => {
  document.removeEventListener('mousedown', onDocClick)
  document.removeEventListener('keydown', onKeydown)
})

defineProps<{ disabledActions?: string[] }>()
</script>

<template>
  <header class="toolbar">
    <button class="brand" title="返回首页" @click="emit('home')">
      <span class="logo">▦</span>
      <span class="name">u-ppt</span>
      <span class="sub">在线演示工具</span>
    </button>

    <div class="tools">
      <!-- 高频：页面操作 -->
      <button class="btn tool-add" data-action="add-slide" title="新建幻灯片" :disabled="disabledActions?.includes('add-slide')" @click="action('add-slide')"><Icon name="plus" :size="14" /> 幻灯片</button>
      <button class="btn" data-action="templates" title="从模板新建页" @click="emit('open-templates')"><Icon name="clipboard" :size="14" /> 模板</button>
      <span class="sep"></span>
      <button class="btn icon-only" data-action="dup-slide" title="复制当前页" :disabled="disabledActions?.includes('dup-slide')" @click="action('dup-slide')"><Icon name="clipboard" :size="15" /></button>
      <button class="btn icon-only danger-hover" data-action="del-slide" title="删除当前页" :disabled="disabledActions?.includes('del-slide')" @click="action('del-slide')"><Icon name="trash" :size="15" /></button>
      <span class="sep"></span>

      <!-- 主题 -->
      <label class="theme-select">
        主题
        <select v-model="currentTheme" @change="onThemeChange">
          <option v-for="k in themeKeys" :key="k" :value="k">{{ themes[k].name }}</option>
        </select>
      </label>
      <span class="sep"></span>

      <!-- 保存：高频动作常驻工具栏 -->
      <button class="btn" data-action="save" title="保存到文库 (Ctrl+S)" :disabled="disabledActions?.includes('save')" @click="action('save')"><Icon name="save" :size="14" /> 保存</button>

      <!-- 低频：文件域收进菜单 -->
      <div class="file-menu" ref="fileMenuBtn">
        <button class="btn" data-action="file-menu" :class="{ active: fileMenuOpen }" @click="toggleFileMenu">
          <Icon name="folder" :size="14" /> 文件 <span class="chevron" :class="{ open: fileMenuOpen }">▾</span>
        </button>
        <Transition name="menu-pop">
          <div v-if="fileMenuOpen" class="file-dropdown" role="menu">
            <button class="menu-item" role="menuitem" @click="fileAction('library')">
              <span class="mi-icon"><Icon name="folder" :size="15" /></span><span class="mi-label">文库</span><span class="mi-hint">我的演示</span>
            </button>
            <button class="menu-item" role="menuitem" @click="fileAction('import-materials')">
              <span class="mi-icon"><Icon name="folder-open" :size="15" /></span><span class="mi-label">导入资料</span><span class="mi-hint">图片 / 文档 / 目录</span>
            </button>
            <button class="menu-item" role="menuitem" @click="fileAction('import-json')">
              <span class="mi-icon"><Icon name="download" :size="15" /></span><span class="mi-label">导入 JSON</span>
            </button>
            <button class="menu-item" role="menuitem" @click="fileAction('export-json')">
              <span class="mi-icon"><Icon name="upload" :size="15" /></span><span class="mi-label">导出 JSON</span>
            </button>
            <button class="menu-item" role="menuitem" @click="fileAction('export-pdf')">
              <span class="mi-icon"><Icon name="printer" :size="15" /></span><span class="mi-label">导出 PDF</span><span class="mi-hint">打印 / 另存</span>
            </button>
            <button class="menu-item" role="menuitem" @click="fileAction('share')">
              <span class="mi-icon"><Icon name="link" :size="15" /></span><span class="mi-label">生成分享链接</span><span class="mi-hint">公开只读 · 云端</span>
            </button>
            <div class="menu-sep"></div>
            <button class="menu-item danger" role="menuitem" :disabled="disabledActions?.includes('reset')" @click="fileAction('reset')">
              <span class="mi-icon"><Icon name="rotate" :size="15" /></span><span class="mi-label">重置为示例</span>
            </button>
          </div>
        </Transition>
      </div>

      <!-- 终端动作 -->
      <button class="btn primary" data-action="present" title="开始演示 (F5)" :disabled="disabledActions?.includes('present')" @click="action('present')"><Icon name="play" :size="13" /> 演示</button>
      <button class="btn ghost icon-only" data-action="settings" title="设置（AI / 云存储 / 中继）" @click="action('settings')"><Icon name="settings" :size="16" /></button>
    </div>
  </header>
</template>

<style scoped>
/* 品牌区按钮化：去掉 button 默认外观，保留原有视觉，hover 轻反馈 */
.brand { border: none; background: transparent; padding: 0; font: inherit; text-align: left; cursor: pointer; }
.brand:hover { opacity: .8; }

/* 新建幻灯片：创作起点，给主色轻底强调 */
.tool-add { background: var(--ui-primary-soft); border-color: transparent; color: var(--ui-primary); font-weight: 500; }
.tool-add:hover { background: #e0e7ff; }
.tool-add:disabled { opacity: .5; }

/* 纯图标按钮：删除/复制降为图标，减文字噪音 */
.btn.icon-only { width: 36px; padding: 0; justify-content: center; font-size: 16px; }
.btn.danger-hover:hover { color: var(--ui-danger); border-color: var(--ui-danger); background: rgba(225, 29, 72, .05); }

/* ---------- 文件菜单 ---------- */
.file-menu { position: relative; display: inline-flex; }
.file-menu .btn.active { background: var(--ui-hover); border-color: var(--ui-primary); }
.chevron { font-size: 16px; margin-left: 2px; opacity: .6; transition: transform .15s; }
.chevron.open { transform: rotate(180deg); }

.file-dropdown {
  position: absolute; top: calc(100% + 6px); left: 0;
  width: max-content; min-width: 216px;
  background: var(--ui-panel);
  border: 1px solid var(--ui-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 5px;
  z-index: 100;
}
.menu-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 7px 10px;
  border: none; background: transparent;
  border-radius: var(--radius-sm);
  font-size: 13px; color: var(--ui-text);
  text-align: left; cursor: pointer;
  white-space: nowrap;
}
.menu-item:hover { background: var(--ui-hover); }
.menu-item:disabled { opacity: .45; cursor: not-allowed; background: transparent; }
.menu-item .mi-icon { width: 18px; text-align: center; flex-shrink: 0; }
.menu-item .mi-label { flex-shrink: 0; }
.menu-item .mi-hint { margin-left: auto; font-size: 11px; color: var(--ui-muted); padding-left: 14px; }
.menu-item.danger { color: var(--ui-danger); }
.menu-item.danger:hover { background: rgba(225, 29, 72, .06); }
.menu-sep { height: 1px; background: var(--ui-border); margin: 5px 8px; }

/* 弹出动画 */
.menu-pop-enter-active { transition: opacity .14s, transform .14s; }
.menu-pop-leave-active { transition: opacity .1s, transform .1s; }
.menu-pop-enter-from, .menu-pop-leave-to { opacity: 0; transform: translateY(-4px); }
</style>
