<template>
  <a-layout class="app-layout">
    <!-- ── Header ─────────────────────────────────────────── -->
    <a-layout-header class="app-header">
      <div class="header-left">
        <div class="logo" @click="$router.push('/')">
          <FileSearchOutlined class="logo-icon" />
          <span v-show="!siderCollapsed">政务文档智能检索</span>
        </div>
      </div>
      <div class="header-center"></div>
      <div class="header-right">
        <a-popover trigger="click" placement="bottomRight" overlay-class-name="user-popover">
          <div class="user-info">
            <a-avatar size="small" style="background-color: #1677ff;">
              <template #icon><UserOutlined /></template>
            </a-avatar>
            <div class="user-detail">
              <span class="user-name">{{ userStore.userName || userStore.userId || '未登录' }}</span>
              <span v-if="userStore.deptName || userStore.officeName" class="user-dept">
                {{ [userStore.deptName, userStore.officeName].filter(Boolean).join(' - ') }}
              </span>
            </div>
          </div>
          <template #content>
            <div class="user-popover-content">
              <div class="user-popover-header">
                <a-avatar :size="40" style="background-color: #1677ff;">
                  <template #icon><UserOutlined style="font-size: 20px" /></template>
                </a-avatar>
                <div class="user-popover-name">
                  <span class="name">{{ userStore.userName || userStore.userId || '未登录' }}</span>
                  <span class="id">{{ userStore.userId }}</span>
                </div>
              </div>
              <a-divider style="margin: 12px 0" />
              <div class="user-popover-fields">
                <div v-if="userStore.deptName" class="field-row">
                  <span class="field-label">部门</span>
                  <span class="field-value">{{ userStore.deptName }}</span>
                </div>
                <div v-if="userStore.officeName" class="field-row">
                  <span class="field-label">科室</span>
                  <span class="field-value">{{ userStore.officeName }}</span>
                </div>
                <div v-if="userStore.areaName" class="field-row">
                  <span class="field-label">地区</span>
                  <span class="field-value">{{ userStore.areaName }}</span>
                </div>
              </div>
              <a-divider style="margin: 12px 0" />
              <a-button block danger @click="handleLogout" v-if="userStore.userId">
                <template #icon><LogoutOutlined /></template>
                退出登录
              </a-button>
            </div>
          </template>
        </a-popover>
      </div>
    </a-layout-header>

    <!-- ── Body: Sider + Content ──────────────────────────── -->
    <a-layout class="app-body">
      <a-layout-sider
        class="app-sider"
        :width="220"
        :collapsed-width="64"
        collapsible
        v-model:collapsed="siderCollapsed"
        theme="light"
      >
        <a-menu
          class="sider-menu"
          mode="inline"
          v-model:open-keys="openKeys"
          :selected-keys="selectedMenuKeys"
          @click="handleMenuClick"
        >
          <!-- 文档服务 -->
          <a-sub-menu key="doc-service">
            <template #icon><AppstoreOutlined /></template>
            <template #title>文档服务</template>
            <a-menu-item key="/search">
              <template #icon><SearchOutlined /></template>
              <span>文档检索</span>
            </a-menu-item>
            <a-menu-item key="/research">
              <template #icon><ExperimentOutlined /></template>
              <span>研究分析</span>
            </a-menu-item>
            <a-menu-item key="/qa">
              <template #icon><MessageOutlined /></template>
              <span>智能问答</span>
            </a-menu-item>
            <a-menu-item key="/notebook">
              <template #icon><BookOutlined /></template>
              <span>专题写稿</span>
            </a-menu-item>
            <a-menu-item key="/matters">
              <template #icon><TagsOutlined /></template>
              <span>事项查询</span>
            </a-menu-item>
            <a-menu-item key="/guides">
              <template #icon><ReadOutlined /></template>
              <span>办事指南</span>
            </a-menu-item>
            <a-menu-item key="/graph">
              <template #icon><DeploymentUnitOutlined /></template>
              <span>知识图谱</span>
            </a-menu-item>
          </a-sub-menu>

          <!-- 系统管理 -->
          <a-sub-menu key="sys-admin">
            <template #icon><SettingOutlined /></template>
            <template #title>系统管理</template>
            <a-menu-item key="/admin">
              <template #icon><DashboardOutlined /></template>
              <span>管理后台</span>
            </a-menu-item>
            <a-menu-item key="/admin/graph">
              <template #icon><ApartmentOutlined /></template>
              <span>图谱管理</span>
            </a-menu-item>
            <a-menu-item key="/admin/ingest-traces">
              <template #icon><NodeIndexOutlined /></template>
              <span>入库追踪</span>
            </a-menu-item>
            <a-menu-item key="/admin/convert-logs">
              <template #icon><SwapOutlined /></template>
              <span>转换记录</span>
            </a-menu-item>
            <!-- 仅在开发模式下显示 Mock 菜单 -->
            <!-- Only show Mock menu in development mode -->
            <a-menu-item v-if="isDev" key="/mock">
              <template #icon><BugOutlined /></template>
              <span>Mock 测试台</span>
            </a-menu-item>
          </a-sub-menu>
        </a-menu>
      </a-layout-sider>

      <a-layout class="app-content-layout">
        <!-- Tab bar -->
        <div class="app-tabs">
          <a-tabs
            :active-key="tabsStore.activeKey"
            type="editable-card"
            hide-add
            size="small"
            @change="onTabSelect"
            @edit="onTabEdit"
          >
            <a-tab-pane
              v-for="tab in tabsStore.tabs"
              :key="tab.key"
              :tab="tab.title"
              :closable="tab.closable"
            />
          </a-tabs>
        </div>

        <!-- Page content -->
        <a-layout-content class="app-content">
          <router-view />
        </a-layout-content>
      </a-layout>
    </a-layout>

    <!-- Global basket drawer (triggered by basketStore.openDrawer) -->
    <ResearchBasketDrawer />
  </a-layout>
</template>

/**
 * 应用根组件
 * 实现整体布局：顶部导航栏、左侧可折叠菜单、多标签页内容区。
 * 负责菜单点击与路由的双向同步，以及标签页的增删管理。
 */
<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import {
  AppstoreOutlined,
  SearchOutlined,
  ExperimentOutlined,
  MessageOutlined,
  DeploymentUnitOutlined,
  SettingOutlined,
  DashboardOutlined,
  ApartmentOutlined,
  FileSearchOutlined,
  UserOutlined,
  LogoutOutlined,
  BugOutlined,
  SwapOutlined,
  TagsOutlined,
  NodeIndexOutlined,
  ReadOutlined,
  BookOutlined,
} from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { useUserStore } from '@/stores/user'
import { useTabsStore } from '@/stores/tabs'
import ResearchBasketDrawer from '@/components/ResearchBasketDrawer.vue'

const router = useRouter()
const route = useRoute()
const userStore = useUserStore()
const tabsStore = useTabsStore()

function handleLogout() {
  userStore.logout()
  message.success('已退出登录')
  router.push('/mock')
}

const siderCollapsed = ref(false)
// 仅在开发模式下显示 Mock 菜单
// Only show Mock menu in development mode
const isDev = import.meta.env.DEV || window.location.href.includes('192.168') || window.location.href.includes('localhost') || window.location.href.includes('mock=dev')
const openKeys = ref<string[]>(['doc-service'])

// Guard flag: when true, ignore @change from a-tabs
let navigating = false

// ── Menu → route mapping ──────────────────────────────────────

// 菜单路径与标签页标题的映射，用于新建标签页时取得中文标题
const menuTitleMap: Record<string, string> = {
  '/search':              '文档检索',
  '/research':            '研究分析',
  '/qa':                  '智能问答',
  '/notebook':            '专题写稿',
  '/matters':             '事项查询',
  '/guides':              '办事指南',
  '/graph':               '知识图谱',
  '/admin':               '管理后台',
  '/admin/graph':         '图谱管理',
  '/admin/ingest-traces': '入库追踪',
  '/admin/convert-logs':  '转换记录',
  '/mock':                'Mock 测试台',
}

// 菜单路径与其所属父级子菜单 key 的映射，用于自动展开侧边栏子菜单
const menuParentMap: Record<string, string> = {
  '/search':              'doc-service',
  '/research':            'doc-service',
  '/qa':                  'doc-service',
  '/notebook':            'doc-service',
  '/matters':             'doc-service',
  '/guides':              'doc-service',
  '/graph':               'doc-service',
  '/admin':               'sys-admin',
  '/admin/graph':         'sys-admin',
  '/admin/ingest-traces': 'sys-admin',
  '/admin/convert-logs':  'sys-admin',
  '/mock':                'sys-admin',
}

// ── Computed menu state ───────────────────────────────────────

// 根据当前路由路径推算菜单高亮项；对文档详情页等子路径回退到父级菜单
const selectedMenuKeys = computed(() => {
  const p = route.path
  if (p.startsWith('/doc/')) return ['/search']
  if (p.startsWith('/matters/')) return ['/matters']
  if (p.startsWith('/guides/')) return ['/guides']
  if (p.startsWith('/qa')) return ['/qa']
  if (p.startsWith('/notebook')) return ['/notebook']
  if (menuTitleMap[p]) return [p]
  if (p.startsWith('/admin')) return ['/admin']
  return ['/search']
})

// ── Navigation helper ─────────────────────────────────────────

// 导航辅助：设置 navigating 标志位避免 a-tabs 的 @change 回调触发循环跳转
function navigateTo(path: string) {
  navigating = true
  router.push(path).catch(() => {}).finally(() => {
    nextTick(() => { navigating = false })
  })
}

// ── Menu click → add tab + navigate ───────────────────────────

function handleMenuClick({ key }: { key: string }) {
  const title = menuTitleMap[key]
  if (title) {
    tabsStore.addTab({ key, title, path: key })
    navigateTo(key)
  }
}

// ── Tab click → navigate ──────────────────────────────────────

function onTabSelect(key: string) {
  if (navigating) return
  const tab = tabsStore.tabs.find(t => t.key === key)
  if (tab) {
    tabsStore.activeKey = key
    navigateTo(tab.path)
  }
}

function onTabEdit(targetKey: string | MouseEvent, action: string) {
  if (action === 'remove' && typeof targetKey === 'string') {
    const newKey = tabsStore.removeTab(targetKey)
    if (newKey) {
      const tab = tabsStore.tabs.find(t => t.key === newKey)
      if (tab) navigateTo(tab.path)
    }
  }
}

// ── Sync route changes → tab bar ──────────────────────────────

// 路由切换后自动在标签页栏同步新增/激活对应标签，并展开所属子菜单
router.afterEach((to) => {
  const p = to.path
  if (p === '/') return

  let title = (to.meta?.title as string) || '未命名'
  if (p.startsWith('/guides/by-doc/') && to.params.docId) {
    title = `指南文档 ${(to.params.docId as string).slice(0, 8)}`
  } else if (p.startsWith('/guides/') && to.params.profileId) {
    title = `指南 ${(to.params.profileId as string).slice(0, 8)}`
  }

  tabsStore.addTab({ key: p, title, path: to.fullPath })

  // Auto-expand parent sub-menu
  const parent = menuParentMap[p]
  if (parent && !openKeys.value.includes(parent)) {
    openKeys.value = [...openKeys.value, parent]
  }
})

// Initialize tab for current route on mount
;(() => {
  const p = route.path
  if (p !== '/' && route.matched.length) {
    const title = (route.meta?.title as string) || '未命名'
    tabsStore.addTab({ key: p, title, path: route.fullPath })
  }
})()

</script>

<!--
  全局样式：需要被子组件使用的工具类保留在非 scoped 块中
  Global styles: utility classes used by child components remain unscoped
-->
<style lang="less">
// 全局工具类，供各页面组件复用
// Global utility class, reused by page components
.page-container {
  padding: 24px;
  max-width: 1400px;
  margin: 0 auto;
}

// 用户信息悬浮窗（渲染在 body 下，必须用全局样式）
.user-popover {
  .ant-popover-inner {
    padding: 0;
  }
}

.user-popover-content {
  width: 240px;
  padding: 16px;
}

.user-popover-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

.user-popover-name {
  display: flex;
  flex-direction: column;
  line-height: 1.4;
  min-width: 0;

  .name {
    font-size: 15px;
    font-weight: 600;
    color: rgba(0, 0, 0, 0.88);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .id {
    font-size: 12px;
    color: rgba(0, 0, 0, 0.45);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.user-popover-fields {
  .field-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 0;
    font-size: 13px;
  }

  .field-label {
    color: rgba(0, 0, 0, 0.45);
    flex-shrink: 0;
  }

  .field-value {
    color: rgba(0, 0, 0, 0.88);
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-left: 12px;
  }
}
</style>

<!--
  组件局部样式：仅作用于 App.vue 自身的布局元素
  Component-scoped styles: only affect App.vue layout elements
-->
<style scoped lang="less">
.app-layout {
  min-height: 100vh;
}

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 24px;
  height: 56px;
  line-height: 56px;
  background: #001529;
  color: #fff;
  z-index: 100;

  .header-left {
    display: flex;
    align-items: center;
    flex-shrink: 0;
  }

  .logo {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    font-size: 16px;
    font-weight: 600;
    color: #fff;
    white-space: nowrap;
  }

  .logo-icon {
    font-size: 22px;
    color: #1890ff;
  }

  .header-center {
    flex: 1;
  }

  .header-right {
    display: flex;
    align-items: center;
    gap: 20px;
    flex-shrink: 0;
  }

  .user-info {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
    transition: background-color 0.2s;

    &:hover {
      background: rgba(255, 255, 255, 0.1);
    }
  }

  .user-detail {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
  }

  .user-name {
    color: rgba(255, 255, 255, 0.85);
    font-size: 14px;
  }

  .user-dept {
    color: rgba(255, 255, 255, 0.5);
    font-size: 11px;
  }
}

.app-body {
  flex: 1;
  min-height: 0;
}

.app-sider {
  border-right: 1px solid #f0f0f0;
  background: #fff !important;

  :deep(.sider-menu) {
    border-right: none;
  }
}

.app-content-layout {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: #f5f5f5;
}

.app-tabs {
  padding: 8px 16px 0;
  background: #fff;
  border-bottom: 1px solid #f0f0f0;

  :deep(.ant-tabs) {
    margin-bottom: -1px;
  }

  :deep(.ant-tabs-nav) {
    margin-bottom: 0;
  }
}

.app-content {
  flex: 1;
  overflow: auto;
  background: #f5f5f5;
}
</style>
