<template>
  <div class="admin-shell">
    <!-- ===== 侧边栏：树形菜单 ===== -->
    <aside class="sidebar" :class="{ open: mobileSidebarOpen }">
      <!-- Logo -->
      <div class="sidebar-logo" @click="router.push('/admin/dashboard')">
        <svg class="logo-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
        </svg>
        <span class="logo-text">Mokee</span>
      </div>

      <!-- 菜单树 -->
      <nav class="sidebar-nav">
        <!-- 首页 -->
        <div
          class="menu-item single"
          :class="{ active: activeMenu === '/admin/dashboard' }"
          @click="openPage('/admin/dashboard', '首页')"
        >
          <el-icon :size="18"><HomeFilled /></el-icon>
          <span>首页</span>
        </div>

        <!-- 系统管理 -->
        <div class="menu-group" :class="{ open: menuOpen.system }">
          <div class="menu-item parent" :class="{ active: activeGroup === 'system' }" @click="menuOpen.system = !menuOpen.system">
            <el-icon :size="18"><Monitor /></el-icon>
            <span>系统管理</span>
            <el-icon :size="14" class="arrow" :class="{ rotated: menuOpen.system }"><ArrowRight /></el-icon>
          </div>
          <div class="sub-items" v-show="menuOpen.system">
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/system' }" @click="openPage('/admin/system', '系统列表')">
              <span>系统列表</span>
            </div>
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/api' }" @click="openPage('/admin/api', '接口管理')">
              <span>接口管理</span>
            </div>
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/dict' }" @click="openPage('/admin/dict', '数据字典')">
              <span>数据字典</span>
            </div>
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/file' }" @click="openPage('/admin/file', '文件管理')">
              <span>文件管理</span>
            </div>
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/email' }" @click="openPage('/admin/email', '邮件管理')">
              <span>邮件管理</span>
            </div>
          </div>
        </div>

        <!-- 用户权限 -->
        <div class="menu-group" :class="{ open: menuOpen.user }">
          <div class="menu-item parent" :class="{ active: activeGroup === 'user' }" @click="menuOpen.user = !menuOpen.user">
            <el-icon :size="18"><UserFilled /></el-icon>
            <span>用户权限</span>
            <el-icon :size="14" class="arrow" :class="{ rotated: menuOpen.user }"><ArrowRight /></el-icon>
          </div>
          <div class="sub-items" v-show="menuOpen.user">
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/user' }" @click="openPage('/admin/user', '用户管理')">
              <span>用户管理</span>
            </div>
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/role' }" @click="openPage('/admin/role', '角色管理')">
              <span>角色管理</span>
            </div>
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/menu' }" @click="openPage('/admin/menu', '菜单管理')">
              <span>菜单管理</span>
            </div>
          </div>
        </div>

        <!-- 日志审计 -->
        <div class="menu-group" :class="{ open: menuOpen.log }">
          <div class="menu-item parent" :class="{ active: activeGroup === 'log' }" @click="menuOpen.log = !menuOpen.log">
            <el-icon :size="18"><Document /></el-icon>
            <span>日志审计</span>
            <el-icon :size="14" class="arrow" :class="{ rotated: menuOpen.log }"><ArrowRight /></el-icon>
          </div>
          <div class="sub-items" v-show="menuOpen.log">
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/log/login' }" @click="openPage('/admin/log/login', '登录日志')">
              <span>登录日志</span>
            </div>
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/log/operation' }" @click="openPage('/admin/log/operation', '操作日志')">
              <span>操作日志</span>
            </div>
            <div class="menu-item child" :class="{ active: activeMenu === '/admin/log/token' }" @click="openPage('/admin/log/token', 'Token日志')">
              <span>Token日志</span>
            </div>
          </div>
        </div>
      </nav>

      <!-- 底部 -->
      <div class="sidebar-footer">
        <div class="menu-item single" @click="router.push('/select')">
          <el-icon :size="18"><Switch /></el-icon>
          <span>切换系统</span>
        </div>
      </div>
    </aside>

    <!-- 移动端遮罩 -->
    <div :class="['sidebar-overlay', { show: mobileSidebarOpen }]" @click="mobileSidebarOpen = false" />

    <!-- ===== 右侧主体 ===== -->
    <div class="main-area">
      <!-- 顶栏 -->
      <header class="topbar">
        <div class="topbar-left">
          <span class="hamburger" @click="mobileSidebarOpen = !mobileSidebarOpen">
            <el-icon :size="20"><component :is="mobileSidebarOpen ? Fold : Expand" /></el-icon>
          </span>
          <el-breadcrumb separator="/" class="breadcrumb-desk">
            <el-breadcrumb-item :to="{ path: '/admin/dashboard' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item v-if="breadcrumbParent">{{ breadcrumbParent }}</el-breadcrumb-item>
            <el-breadcrumb-item v-if="breadcrumbCurrent">{{ breadcrumbCurrent }}</el-breadcrumb-item>
          </el-breadcrumb>
        </div>
        <div class="topbar-right">
          <el-dropdown trigger="hover" placement="bottom-end">
            <div class="user-chip">
              <el-avatar :size="28" :src="authStore.userInfo?.avatar">
                {{ authStore.userInfo?.realName?.charAt(0) || 'U' }}
              </el-avatar>
              <span class="user-name">{{ authStore.userInfo?.realName || authStore.userInfo?.username || '用户' }}</span>
              <el-icon :size="12" class="user-chevron"><ArrowDown /></el-icon>
            </div>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item @click="router.push('/admin/personal')">
                  <el-icon><User /></el-icon>个人中心
                </el-dropdown-item>
                <el-dropdown-item @click="router.push('/select')">
                  <el-icon><Switch /></el-icon>切换系统
                </el-dropdown-item>
                <el-dropdown-item divided @click="handleLogout">
                  <el-icon><SwitchButton /></el-icon>退出登录
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </header>

      <!-- 标签栏 -->
      <div class="tab-bar" v-if="tabsStore.tabs.length > 0">
        <div class="tab-list" ref="tabListRef">
          <div
            v-for="tab in tabsStore.tabs"
            :key="tab.path"
            :class="['tab-chip', { active: tabsStore.activeTab === tab.path }]"
            @click="switchTab(tab)"
            @contextmenu.prevent="showMenu($event, tab)"
          >
            <span class="tab-title">{{ tab.title }}</span>
            <el-icon
              v-if="tabsStore.tabs.length > 1"
              class="tab-close"
              :size="12"
              @click.stop="closeTab(tab.path)"
            ><Close /></el-icon>
          </div>
        </div>
        <el-dropdown trigger="click" @command="handleTabCmd" class="tab-more">
          <span class="tab-more-btn">
            <el-icon :size="14"><ArrowDown /></el-icon>
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="closeCurrent">
                <el-icon><Close /></el-icon>关闭当前
              </el-dropdown-item>
              <el-dropdown-item command="closeOthers">
                <el-icon><Remove /></el-icon>关闭其他
              </el-dropdown-item>
              <el-dropdown-item command="closeAll">
                <el-icon><CircleClose /></el-icon>关闭全部
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>

      <!-- 右键菜单 -->
      <Teleport to="body">
        <div
          v-if="ctxMenu.visible"
          class="ctx-overlay"
          @click="ctxMenu.visible = false"
        >
          <div
            class="ctx-menu"
            :style="{ left: ctxMenu.x + 'px', top: ctxMenu.y + 'px' }"
            @click.stop
          >
            <div class="ctx-item" @click="closeTab(ctxMenu.tab?.path); ctxMenu.visible = false">
              <el-icon :size="14"><Close /></el-icon>关闭
            </div>
            <div class="ctx-item" @click="closeOthers(ctxMenu.tab?.path); ctxMenu.visible = false">
              <el-icon :size="14"><Remove /></el-icon>关闭其他
            </div>
            <div class="ctx-item" @click="closeAll(); ctxMenu.visible = false">
              <el-icon :size="14"><CircleClose /></el-icon>关闭全部
            </div>
          </div>
        </div>
      </Teleport>

      <!-- 内容区 -->
      <main class="content">
        <router-view :key="tabsStore.activeTab" />
      </main>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, watch, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {
  HomeFilled, Monitor, UserFilled, Document,
  ArrowRight, Switch, ArrowDown, SwitchButton,
  User, Close, Remove, CircleClose, Expand, Fold,
} from '@element-plus/icons-vue'
import { useAuthStore } from '@/stores/auth'
import { useTabsStore } from '@/stores/tabs'

const route = useRoute()
const router = useRouter()
const authStore = useAuthStore()
const tabsStore = useTabsStore()
const tabListRef = ref<HTMLElement>()
const mobileSidebarOpen = ref(false)

// 菜单展开状态
const menuOpen = reactive({ system: true, user: true, log: true })

// 当前高亮
const activeMenu = computed(() => {
  const p = route.path
  const known = ['/admin/dashboard', '/admin/system', '/admin/api', '/admin/dict', '/admin/file', '/admin/email',
    '/admin/user', '/admin/role', '/admin/menu', '/admin/log/login', '/admin/log/operation', '/admin/log/token']
  return known.find(k => p.startsWith(k)) || p
})

const activeGroup = computed(() => {
  const p = route.path
  if (p.startsWith('/admin/system') || p.startsWith('/admin/api') || p.startsWith('/admin/dict') || p.startsWith('/admin/file') || p.startsWith('/admin/email')) return 'system'
  if (p.startsWith('/admin/user') || p.startsWith('/admin/role') || p.startsWith('/admin/menu')) return 'user'
  if (p.startsWith('/admin/log')) return 'log'
  return ''
})

// 面包屑
const breadcrumbMap: Record<string, { parent?: string; current: string }> = {
  '/admin/dashboard': { current: '首页' },
  '/admin/system': { parent: '系统管理', current: '系统列表' },
  '/admin/api': { parent: '系统管理', current: '接口管理' },
  '/admin/dict': { parent: '系统管理', current: '数据字典' },
  '/admin/file': { parent: '系统管理', current: '文件管理' },
  '/admin/email': { parent: '系统管理', current: '邮件管理' },
  '/admin/user': { parent: '用户权限', current: '用户管理' },
  '/admin/role': { parent: '用户权限', current: '角色管理' },
  '/admin/menu': { parent: '用户权限', current: '菜单管理' },
  '/admin/log/login': { parent: '日志审计', current: '登录日志' },
  '/admin/log/operation': { parent: '日志审计', current: '操作日志' },
  '/admin/log/token': { parent: '日志审计', current: 'Token日志' },
  '/admin/user/form': { parent: '用户权限', current: '用户表单' },
  '/admin/role/form': { parent: '用户权限', current: '角色表单' },
  '/admin/menu/form': { parent: '用户权限', current: '菜单表单' },
  '/admin/system/form': { parent: '系统管理', current: '系统表单' },
  '/admin/api/form': { parent: '系统管理', current: '接口表单' },
  '/admin/dict/form': { parent: '系统管理', current: '字典表单' },
  '/admin/personal': { current: '个人中心' },
}

const breadcrumbParent = computed(() => {
  const key = Object.keys(breadcrumbMap).find(k => route.path.startsWith(k))
  return key ? breadcrumbMap[key].parent : undefined
})
const breadcrumbCurrent = computed(() => {
  const key = Object.keys(breadcrumbMap).find(k => route.path.startsWith(k))
  return key ? breadcrumbMap[key].current : undefined
})

// ===== 标签页 =====
function openPage(path: string, title: string) {
  tabsStore.addTab({ path, meta: { title }, query: {} } as any)
  router.push(path)
  mobileSidebarOpen.value = false
}

function switchTab(tab: any) {
  router.push(tab.path)
}

function closeTab(path: string) {
  tabsStore.removeTab(path)
  if (tabsStore.activeTab) {
    router.push(tabsStore.activeTab)
  } else {
    router.push('/admin/dashboard')
    tabsStore.addTab({ path: '/admin/dashboard', meta: { title: '首页' }, query: {} } as any)
  }
}

function closeOthers(path?: string) {
  if (path) tabsStore.closeOthers(path)
}

function closeAll() {
  tabsStore.closeAll()
  router.push('/admin/dashboard')
  tabsStore.addTab({ path: '/admin/dashboard', meta: { title: '首页' }, query: {} } as any)
}

function handleTabCmd(cmd: string) {
  const cur = tabsStore.activeTab
  if (cmd === 'closeCurrent' && cur) closeTab(cur)
  else if (cmd === 'closeOthers' && cur) closeOthers(cur)
  else if (cmd === 'closeAll') closeAll()
}

// 右键菜单
const ctxMenu = reactive({ visible: false, x: 0, y: 0, tab: null as any })
function showMenu(e: MouseEvent, tab: any) {
  ctxMenu.visible = true
  ctxMenu.x = e.clientX
  ctxMenu.y = e.clientY
  ctxMenu.tab = tab
}

// 路由变化自动加标签
watch(() => route.path, (p) => {
  if (p.startsWith('/admin') && p !== '/admin') {
    tabsStore.addTab(route)
  }
})

onMounted(async () => {
  // 跨域名跳转后 Pinia 状态丢失，重新从服务端加载用户信息
  await authStore.fetchUserInfo()
  if (route.path !== '/admin' && route.path !== '/admin/dashboard') {
    tabsStore.addTab(route)
  }
  // 首页默认标签
  if (!tabsStore.tabs.find((t: any) => t.path === '/admin/dashboard')) {
    tabsStore.addTab({ path: '/admin/dashboard', meta: { title: '首页' }, query: {} } as any)
  }
  if (route.path === '/admin') {
    router.push('/admin/dashboard')
  }
})

async function handleLogout() {
  try { await authStore.logout() } catch {}
  tabsStore.closeAll()
  // 直接完整跳转登录页，避免 router.push 触发组件 API 请求
  window.location.href = import.meta.env.VITE_LOGIN_URL || '/login'
}
</script>

<style scoped>
/* ===== 整体布局 ===== */
.admin-shell { display:flex; height:100vh; overflow:hidden; background:var(--bg-page); }

/* ===== 侧边栏 ===== */
.sidebar {
  width: 240px; flex-shrink:0;
  background: var(--bg-surface);
  border-right: 1px solid var(--border-color);
  display:flex; flex-direction:column; overflow:hidden; z-index:50;
}

.sidebar-logo {
  display:flex; align-items:center; gap:10px;
  height: 58px; padding:0 20px;
  border-bottom: 1px solid var(--border-light);
  cursor:pointer; flex-shrink:0;
}
.logo-svg { width:22px; height:22px; color:var(--color-primary); flex-shrink:0; }
.logo-text { font-size:18px; font-weight:700; color:var(--text-primary); letter-spacing:-0.3px; }

.sidebar-nav { flex:1; overflow-y:auto; padding:16px 12px; }
.sidebar-footer { padding:8px 12px 16px; border-top:1px solid var(--border-light); flex-shrink:0; }

/* ===== 菜单项 ===== */
.menu-item {
  display:flex; align-items:center; gap:10px;
  height:42px; padding:0 14px;
  border-radius: var(--radius-md);
  cursor:pointer; font-size:14px; font-weight:500;
  color: var(--text-secondary);
  transition: all var(--transition-fast);
  white-space:nowrap;
}
.menu-item:hover { background:var(--bg-hover); color:var(--text-primary); }
.menu-item.active { background:var(--color-primary-bg); color:var(--color-primary); font-weight:600; }

.menu-item.single { margin-bottom:4px; }

.menu-item.parent {
  font-weight:600; font-size:14px; color:var(--text-primary);
  margin-top:2px;
}

.menu-item.child {
  padding-left:48px; height:38px;
  font-size:14px; font-weight:400;
  color: var(--text-muted);
  margin:1px 0;
}
.menu-item.child:hover { color:var(--text-primary); }
.menu-item.child.active { color:var(--color-primary); font-weight:500; }

/* 展开箭头 */
.arrow { margin-left:auto; transition:transform var(--transition-fast); color:var(--text-muted); flex-shrink:0; }
.arrow.rotated { transform:rotate(90deg); }

.sub-items { overflow:hidden; padding-bottom:4px; }

/* ===== 分隔线（菜单组之间） ===== */
.menu-group { padding:4px 0; }
.menu-group + .menu-group { border-top:1px solid var(--border-light); }

/* ===== 主体区域 ===== */
.main-area { flex:1; display:flex; flex-direction:column; overflow:hidden; min-width:0; }

/* ===== 顶栏 ===== */
.topbar {
  display:flex; align-items:center; justify-content:space-between;
  height:58px; background:var(--bg-surface);
  border-bottom:1px solid var(--border-color);
  padding:0 24px; flex-shrink:0;
}
.topbar-left { display:flex; align-items:center; }
.topbar-right { display:flex; align-items:center; }

.user-chip {
  display:flex; align-items:center; gap:8px;
  padding:5px 12px 5px 5px; border-radius:24px;
  cursor:pointer; transition:all var(--transition-fast);
  border:1px solid transparent;
}
.user-chip:hover { background:var(--bg-hover); border-color:var(--border-color); }
.user-name {
  font-size:14px; font-weight:500; color:var(--text-secondary);
  max-width:100px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.user-chevron { color:var(--text-muted); flex-shrink:0; }

/* ===== 标签栏 ===== */
.tab-bar {
  display:flex; align-items:center;
  height:42px; background:var(--bg-surface);
  border-bottom:1px solid var(--border-color);
  padding:0 12px; flex-shrink:0; gap:4px;
}
.tab-list { display:flex; flex:1; overflow-x:auto; overflow-y:hidden; height:100%; align-items:center; gap:2px; }
.tab-list::-webkit-scrollbar { height:2px; }

.tab-chip {
  display:flex; align-items:center; gap:6px;
  height:34px; padding:0 12px;
  border-radius:var(--radius-sm);
  cursor:pointer; font-size:13px;
  color:var(--text-muted);
  transition:all var(--transition-fast);
  white-space:nowrap; flex-shrink:0;
}
.tab-chip:hover { background:var(--bg-hover); color:var(--text-secondary); }
.tab-chip.active { background:var(--color-primary-bg); color:var(--color-primary); font-weight:500; }
.tab-title { max-width:120px; overflow:hidden; text-overflow:ellipsis; }

.tab-close { border-radius:3px; padding:1px; opacity:0; transition:all var(--transition-fast); }
.tab-chip:hover .tab-close { opacity:1; }
.tab-close:hover { background:var(--border-color); color:var(--text-primary); }

.tab-more { flex-shrink:0; }
.tab-more-btn {
  display:flex; align-items:center; justify-content:center;
  width:30px; height:30px; border-radius:var(--radius-sm);
  cursor:pointer; color:var(--text-muted);
  transition:all var(--transition-fast);
}
.tab-more-btn:hover { background:var(--bg-hover); color:var(--text-secondary); }

/* ===== 右键菜单 ===== */
.ctx-overlay { position:fixed; inset:0; z-index:9998; }
.ctx-menu {
  position:fixed; z-index:9999;
  background:var(--bg-surface); border:1px solid var(--border-color);
  border-radius:var(--radius-md); box-shadow:var(--shadow-lg);
  min-width:150px; padding:4px;
}
.ctx-item {
  display:flex; align-items:center; gap:8px;
  padding:9px 14px; font-size:14px; cursor:pointer;
  color:var(--text-secondary); border-radius:var(--radius-sm);
  transition:all var(--transition-fast);
}
.ctx-item:hover { background:var(--bg-hover); color:var(--text-primary); }

/* ===== 内容区 ===== */
.content { flex:1; overflow-y:auto; padding:24px; }

/* ===== 汉堡按钮 ===== */
.hamburger {
  display: none; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--radius-md);
  cursor: pointer; color: var(--text-secondary);
  margin-right: 8px; flex-shrink: 0;
}
.hamburger:hover { background: var(--bg-hover); color: var(--color-primary); }

/* ===== 侧边栏遮罩 ===== */
.sidebar-overlay {
  display: none;
  position: fixed; inset: 0; z-index: 99;
  background: rgba(0,0,0,0.4);
}

/* ===== 移动端适配 ===== */
@media (max-width: 768px) {
  .hamburger { display: flex; }
  .breadcrumb-desk { display: none; }

  /* 侧边栏滑出 */
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 100;
    width: 260px !important;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    box-shadow: none;
  }
  .sidebar.open {
    transform: translateX(0);
  }

  .sidebar-overlay.show { display: block; }

  /* 主体全宽 */
  .main-area { width: 100%; }

  /* 顶栏 */
  .topbar { padding: 0 12px; height: 50px; }
  .user-chip { padding: 4px 8px 4px 4px; }
  .user-name { display: none; }

  /* 标签栏 */
  .tab-bar { height: 36px; padding: 0 6px; }
  .tab-chip { height: 28px; padding: 0 8px; font-size: 12px; }
  .tab-title { max-width: 80px; }

  /* 内容区 */
  .content { padding: 12px; }
}
</style>
