<template>
  <a-layout class="layout-shell">
    <!-- 左侧固定侧边栏 -->
    <a-layout-sider
      class="sider"
      :width="220"
      :collapsed-width="64"
      breakpoint="lg"
      theme="dark"
      :trigger="null"
      collapsible
      v-model:collapsed="collapsed"
    >
      <!-- Logo 区域 -->
      <div class="sider-logo" @click="navigateTo('/console')">
        <img src="/logo.png" alt="logo" class="logo-img" />
        <transition name="logo-text">
          <span v-if="!collapsed" class="logo-name">控制台</span>
        </transition>
      </div>

      <!-- 菜单 -->
      <a-menu
        mode="inline"
        theme="dark"
        :selected-keys="selectedKeys"
        :open-keys="collapsed ? [] : openKeys"
        :inline-collapsed="collapsed"
        @open-change="onOpenChange"
        @click="onMenuClick"
      >
        <template v-for="entry in menu" :key="isGroup(entry) ? entry.key : entry.to">
          <!-- 分组：有子菜单 -->
          <a-sub-menu v-if="isGroup(entry)" :key="entry.key">
            <template v-if="entry.icon" #icon>
              <component :is="entry.icon" />
            </template>
            <template #title>{{ entry.label }}</template>
            <a-menu-item v-for="item in entry.children" :key="item.to">
              <template v-if="item.icon" #icon>
                <component :is="item.icon" />
              </template>
              {{ item.label }}
            </a-menu-item>
          </a-sub-menu>
          <!-- 单条链接 -->
          <a-menu-item v-else :key="entry.to">
            <template v-if="entry.icon" #icon>
              <component :is="entry.icon" />
            </template>
            {{ entry.label }}
          </a-menu-item>
        </template>
      </a-menu>

      <!-- 折叠按钮 -->
      <div
        class="sider-collapse-trigger"
        role="button"
        tabindex="0"
        :aria-label="collapsed ? '展开菜单' : '收起菜单'"
        @click="toggleCollapsed"
        @keydown.enter.prevent="toggleCollapsed"
        @keydown.space.prevent="toggleCollapsed"
      >
        <RightOutlined v-if="collapsed" style="font-size: 10px" />
        <LeftOutlined v-else style="font-size: 10px" />
      </div>
    </a-layout-sider>

    <!-- 右侧主区域 -->
    <a-layout class="main-layout" :class="{ 'main-layout--collapsed': collapsed }">
      <!-- 顶部 Header -->
      <a-layout-header class="main-header">
        <div class="header-inner">
          <!-- 左侧面包屑或页面标题（可扩展） -->
          <div class="header-left">
            <span class="page-title">{{ currentPageTitle }}</span>
          </div>

          <!-- 右侧用户区 -->
          <div class="header-right">
            <!-- 消息通知铃铛 -->
            <NotificationBell />

            <a-dropdown placement="bottomRight" :trigger="['click']">
              <div class="user-trigger">
                <a-avatar :size="28" :src="user?.avatar || user?.avatarUrl">
                  <template #icon>
                    <UserOutlined />
                  </template>
                </a-avatar>
                <span class="user-name">{{ userDisplayName }}</span>
                <DownOutlined style="font-size: 10px; opacity: 0.6; margin-left: 2px" />
              </div>
              <template #overlay>
                <a-menu @click="onUserMenuClick" class="user-dropdown-menu">
                  <a-menu-item key="account-info">
                    <UserOutlined style="margin-right: 8px" />
                    账户信息
                  </a-menu-item>
                  <a-menu-item key="orders">
                    <ShoppingOutlined style="margin-right: 8px" />
                    我的订单
                  </a-menu-item>
                  <a-menu-item key="account-kyc">
                    <IdcardOutlined style="margin-right: 8px" />
                    实名认证
                  </a-menu-item>
                  <template v-if="isDeveloper">
                    <a-menu-divider />
                    <a-menu-item key="developer">
                      <CodeOutlined style="margin-right: 8px" />
                      开发者中心
                    </a-menu-item>
                  </template>
                  <template v-if="isAdmin">
                    <a-menu-divider />
                    <a-menu-item key="admin">
                      <SettingOutlined style="margin-right: 8px" />
                      平台管理
                    </a-menu-item>
                  </template>
                  <a-menu-divider />
                  <a-menu-item key="logout" class="logout-item">
                    <LogoutOutlined style="margin-right: 8px" />
                    退出登录
                  </a-menu-item>
                </a-menu>
              </template>
            </a-dropdown>
          </div>
        </div>
      </a-layout-header>

      <!-- 内容区 -->
      <a-layout-content class="main-content">
        <a-spin v-if="!ready" size="large" tip="加载中..." class="spin" />
        <template v-else>
          <slot />
        </template>
      </a-layout-content>
    </a-layout>

    <!-- 邀请通知组件 -->
    <ClientOnly>
      <InviteNotification ref="inviteNotificationRef" />
    </ClientOnly>
  </a-layout>
</template>

<script setup lang="ts">
import { message } from 'ant-design-vue'
import {
  CodeOutlined,
  DownOutlined,
  IdcardOutlined,
  LeftOutlined,
  LogoutOutlined,
  RightOutlined,
  SettingOutlined,
  ShoppingOutlined,
  UserOutlined,
} from '@ant-design/icons-vue'
import { consoleNav, type ConsoleNavEntry, type ConsoleNavGroup } from '@/config/console-nav'
import { getUserInfo } from '@/api/layout'
import { getToken, removeToken } from '@/utils/token-util'
import { clearAuthz, setAuthzFromUser } from '@/utils/permission'
import type { User } from '@/api/system/user/model'

const route = useRoute()
const collapsed = ref(false)
const menu = computed(() => consoleNav)
const user = ref<User | null>(null)

const userDisplayName = computed(() => {
  const u = user.value
  return u?.nickname?.trim() || u?.username?.trim() || u?.phone?.trim() || u?.mobile?.trim() || '当前用户'
})

const isAdmin = computed(() => !!(user.value as any)?.isAdmin)
const isDeveloper = computed(() => (user.value as any)?.type === 2)

function isGroup(entry: ConsoleNavEntry): entry is ConsoleNavGroup {
  return 'children' in entry
}

// 当前页面标题
const currentPageTitle = computed(() => {
  const path = route.path
  for (const entry of menu.value) {
    if (isGroup(entry)) {
      const hit = entry.children.find((c) => path === c.to || path.startsWith(c.to + '/'))
      if (hit) return hit.label
    } else {
      if (path === entry.to || path.startsWith(entry.to + '/')) return entry.label
    }
  }
  return '控制台'
})

// 选中 key
const selectedKeys = computed(() => {
  const path = route.path
  for (const entry of menu.value) {
    if (isGroup(entry)) {
      const hit = entry.children.find((c) => path === c.to || path.startsWith(c.to + '/'))
      if (hit) return [hit.to]
    } else {
      if (path === entry.to) return [entry.to]
    }
  }
  return []
})

// 展开 key（自动展开当前路由所在的分组）
const openKeys = ref<string[]>([])

function syncOpenKeys() {
  const path = route.path
  const hit = menu.value.find(
    (entry) => isGroup(entry) && entry.children.some((c) => path === c.to || path.startsWith(c.to + '/'))
  )
  openKeys.value = hit ? [hit.key] : []
}

function onOpenChange(keys: string[]) {
  openKeys.value = Array.isArray(keys) ? keys.slice(-1) : []
}

function onMenuClick(info: { key: string }) {
  navigateTo(String(info.key))
}

function toggleCollapsed() {
  collapsed.value = !collapsed.value
}

function logout() {
  removeToken()
  try {
    localStorage.removeItem('TenantId')
    localStorage.removeItem('UserId')
  } catch { /* ignore */ }
  clearAuthz()
  navigateTo('/')
}

function onUserMenuClick(info: { key: string }) {
  const key = String(info.key)
  if (key === 'home') navigateTo('/')
  if (key === 'account-info') navigateTo('/console/account')
  if (key === 'orders') navigateTo('/console/orders')
  if (key === 'account-members') navigateTo('/console/account/members')
  if (key === 'account-security') navigateTo('/console/account/security')
  if (key === 'account-kyc') navigateTo('/console/account/kyc')
  if (key === 'developer') navigateTo('/developer')
  if (key === 'admin') navigateTo('/admin')
  if (key === 'logout') logout()
}

watch(() => route.path, syncOpenKeys, { immediate: true })

const ready = ref(false)
const inviteNotificationRef = ref()

onMounted(async () => {
  const token = getToken()
  if (!token) {
    clearAuthz()
    message.error('请先登录')
    await navigateTo('/login')
    ready.value = true
    return
  }
  try {
    const me = await getUserInfo()
    user.value = me
    setAuthzFromUser(me)
  } catch {
    user.value = null
    clearAuthz()
  }
  syncOpenKeys()
  ready.value = true
})
</script>

<style scoped>
/* ===== 整体 shell ===== */
.layout-shell {
  min-height: 100vh;
  background: #f5f7fa;
}

/* ===== 左侧边栏 ===== */
.sider {
  position: fixed !important;
  top: 0;
  left: 0;
  height: 100vh;
  z-index: 100;
  overflow: hidden;
  background: #111827 !important;
  box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
  /* 覆盖 Ant Design sider 背景 */
}

:deep(.ant-layout-sider-children) {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

:deep(.ant-menu-dark) {
  background: transparent;
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
}

:deep(.ant-menu-dark .ant-menu-item-selected) {
  background-color: rgba(59, 130, 246, 0.25) !important;
}

:deep(.ant-menu-dark .ant-menu-item:hover),
:deep(.ant-menu-dark .ant-menu-submenu-title:hover) {
  background-color: rgba(255, 255, 255, 0.06) !important;
}

/* Logo 区域 */
.sider-logo {
  height: 56px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 20px;
  cursor: pointer;
  flex-shrink: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  overflow: hidden;
  white-space: nowrap;
}

.sider-logo:hover .logo-img,
.sider-logo:hover .logo-name {
  opacity: 0.8;
}

.logo-img {
  height: 16px;
  width: auto;
  flex-shrink: 0;
  display: block;
}

.logo-name {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.04em;
  background: linear-gradient(135deg, #ffffff 0%, #a5c8ff 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.logo-text-enter-active,
.logo-text-leave-active {
  transition: opacity 0.2s, width 0.2s;
}

.logo-text-enter-from,
.logo-text-leave-to {
  opacity: 0;
  width: 0;
}

/* 折叠按钮 */
.sider-collapse-trigger {
  position: absolute;
  right: -14px;
  top: 50%;
  transform: translateY(-50%);
  width: 14px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #1f2937;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-left: 0;
  border-radius: 0 9999px 9999px 0;
  box-shadow: 2px 0 6px rgba(0, 0, 0, 0.2);
  color: rgba(255, 255, 255, 0.6);
  cursor: pointer;
  z-index: 101;
}

.sider-collapse-trigger:hover {
  color: #fff;
  background: #374151;
}

/* ===== 右侧主区域 ===== */
.main-layout {
  margin-left: 220px;
  transition: margin-left 0.2s ease;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f7fa;
}

/* 当 sider 折叠时，右侧内容区跟着收缩 */
.main-layout--collapsed {
  margin-left: 64px;
}

/* 顶部 Header */
.main-header {
  position: sticky;
  top: 0;
  z-index: 99;
  height: 56px;
  line-height: 56px;
  padding: 0;
  background: #fff !important;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
  flex-shrink: 0;
}

.header-inner {
  height: 100%;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

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

.page-title {
  font-size: 15px;
  font-weight: 600;
  color: #1f2937;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 16px;
}

.user-trigger {
  height: 36px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  border-radius: 9999px;
  cursor: pointer;
  color: #374151;
  transition: background 0.2s;
}

.user-trigger:hover {
  background: rgba(0, 0, 0, 0.04);
}

.user-name {
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
  color: #374151;
}

/* 头像下拉菜单样式 */
.user-dropdown-menu {
  min-width: 180px;
}

.user-dropdown-menu .ant-menu-item,
.user-dropdown-menu .ant-menu-submenu-title {
  padding: 8px 16px;
}

.logout-item {
  color: #ff4d4f;
}

.logout-item:hover {
  background-color: #fff1f0;
}

/* 内容区 */
.main-content {
  flex: 1;
  padding: 20px 24px;
  min-height: calc(100vh - 56px);
}

.spin {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 400px;
}
</style>
