<template>
  <div class="admin-layout">
    <header class="top-nav">
      <div class="nav-logo" @click="goHome" title="返回首页">
        <img v-if="logImg" :src="logImg" class="logo-img" alt="" />
        <div v-else class="logo-icon">
          <i class="el-icon-s-platform" />
        </div>
        <span class="logo-text">{{ title }}</span>
        <div class="logo-home-badge" @click.stop="goHome">
          <i class="el-icon-s-home" />
        </div>
      </div>
      <div class="nav-divider" />

      <nav class="nav-menu">
        <div
          v-for="(menu, index) in visibleTopMenus"
          :key="menu.path + index"
          class="nav-item"
          :class="{ active: activeTopIndex === index }"
          @click="switchTopMenu(index)"
        >
          <svg-icon v-if="menu.meta && menu.meta.icon" :icon-class="menu.meta.icon" />
          <span>{{ menu.meta.title }}</span>
        </div>
        <el-dropdown v-if="overflowTopMenus.length" trigger="click" @command="onMoreMenuCommand">
          <div class="nav-item nav-item-more" :class="{ active: activeTopIndex >= visibleTopMenus.length }">
            <span>更多菜单</span>
            <i class="el-icon-arrow-down el-icon--right" />
          </div>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item
              v-for="(menu, idx) in overflowTopMenus"
              :key="menu.path + idx"
              :command="visibleTopMenus.length + idx"
            >
              <svg-icon v-if="menu.meta && menu.meta.icon" :icon-class="menu.meta.icon" />
              {{ menu.meta.title }}
            </el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </nav>

      <div class="user-area">
        <template v-if="device !== 'mobile'">
          <search class="header-tool" />
          <screenfull class="header-tool" />
          <el-tooltip content="布局大小" effect="dark" placement="bottom">
            <size-select class="header-tool" />
          </el-tooltip>
        </template>
        <div class="user-info">
          <div class="user-avatar">{{ userInitial }}</div>
          <span class="user-role">管理员</span>
        </div>
        <el-dropdown trigger="click" @command="handleCommand">
          <div class="nav-user">
            <span class="nav-username">{{ name }}</span>
            <i class="el-icon-arrow-down dropdown-arrow" />
          </div>
          <el-dropdown-menu slot="dropdown">
            <router-link to="/user/profile">
              <el-dropdown-item command="profile">
                <i class="el-icon-user" /> 个人中心
              </el-dropdown-item>
            </router-link>
            <el-dropdown-item command="logout" divided>
              <i class="el-icon-switch-button" /> 退出登录
            </el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </div>
    </header>

    <div class="main-container">
      <aside class="sidebar" :class="{ 'sidebar-dashboard': isDashboard }">
        <div v-if="isDashboard" class="dashboard-shortcuts">
          <div class="shortcuts-title">
            <i class="el-icon-s-grid" />
            <span>快捷入口</span>
          </div>
          <div
            v-for="(menu, index) in topMenus"
            :key="menu.path + index"
            class="shortcut-item"
            @click="switchTopMenu(index)"
          >
            <svg-icon v-if="menu.meta && menu.meta.icon" :icon-class="menu.meta.icon" />
            <span>{{ menu.meta.title }}</span>
          </div>
        </div>
        <saas-sidebar v-else class="saas-sidebar-panel" />
      </aside>

      <main class="content-area">
        <tags-view v-if="needTagsView" />
        <app-main />
      </main>
    </div>
  </div>
</template>

<script>
import { mapGetters, mapState } from 'vuex'
import { constantRoutes } from '@/router'
import SaasSidebar from './components/Sidebar/index.vue'
import TagsView from './components/TagsView/index.vue'
import AppMain from './components/AppMain'
import Search from '@/components/HeaderSearch'
import Screenfull from '@/components/Screenfull'
import SizeSelect from '@/components/SizeSelect'

export default {
  name: 'AdminLayout',
  components: {
    SaasSidebar,
    TagsView,
    AppMain,
    Search,
    Screenfull,
    SizeSelect
  },
  data() {
    return {
      activeTopIndex: 0,
      visibleNumber: 12
    }
  },
  computed: {
    ...mapGetters(['name', 'device', 'sidebarRouters']),
    ...mapState({
      needTagsView: state => state.settings.tagsView,
      topbarRouters: state => state.permission.topbarRouters
    }),
    title() {
      return process.env.VUE_APP_TITLE_INDEX || '云联融智SAAS'
    },
    logImg() {
      try {
        return require(process.env.VUE_APP_LOG_URL)
      } catch (e) {
        return ''
      }
    },
    userInitial() {
      const name = this.name || '管'
      return name.charAt(0).toUpperCase()
    },
    topMenus() {
      const list = []
      this.topbarRouters.forEach(menu => {
        if (menu.hidden !== true) {
          if (menu.path === '/') {
            list.push(menu.children[0])
          } else {
            list.push(menu)
          }
        }
      })
      return list
    },
    visibleTopMenus() {
      return this.topMenus.slice(0, this.visibleNumber)
    },
    overflowTopMenus() {
      return this.topMenus.slice(this.visibleNumber)
    },
    isDashboard() {
      const p = this.$route.path
      return p === '/index' || p === '/' || p === ''
    }
  },
  watch: {
    '$route.path'() {
      this.syncActiveTopFromRoute()
    },
    topMenus: {
      handler() {
        this.syncActiveTopFromRoute()
      },
      immediate: true
    }
  },
  beforeMount() {
    window.addEventListener('resize', this.setVisibleNumber)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.setVisibleNumber)
  },
  mounted() {
    this.setVisibleNumber()
    this.syncActiveTopFromRoute()
  },
  methods: {
    setVisibleNumber() {
      const width = document.body.getBoundingClientRect().width / 3
      this.visibleNumber = Math.max(4, parseInt(width / 85))
    },
    goHome() {
      if (this.$route.path !== '/index') {
        this.$router.push('/index').catch(() => {})
      }
    },
    switchTopMenu(index) {
      this.activeTopIndex = index
      const menu = this.topMenus[index]
      if (!menu) return
      const key = this.resolveTopMenuKey(menu)
      if (this.ishttp(key)) {
        window.open(key, '_blank')
        return
      }
      if (key.indexOf('/redirect') !== -1) {
        this.$router.push({ path: key.replace('/redirect', '') }).catch(() => {})
        return
      }
      const routes = this.activeRoutes(key)
      const firstPath = this.getFirstRoutePath(routes)
      if (firstPath && this.$route.path !== firstPath) {
        this.$router.push(firstPath).catch(() => {})
      }
    },
    onMoreMenuCommand(index) {
      this.switchTopMenu(index)
    },
    normPath(p) {
      if (!p) return ''
      const s = String(p)
      if (this.ishttp(s)) return s
      return s.startsWith('/') ? s : '/' + s
    },
    resolveTopMenuKey(menu) {
      if (!menu) return ''
      for (const router of this.topbarRouters) {
        if (router.hidden) continue
        if (this.normPath(router.path) === this.normPath(menu.path) && router.path !== '/') {
          return router.path
        }
        if (!router.children || !router.children.length) continue
        const matched = router.children.some(child => {
          if (child.hidden) return false
          return child === menu || this.normPath(child.path) === this.normPath(menu.path)
        })
        if (matched) {
          return router.path
        }
      }
      return menu.path
    },
    activeRoutes(key) {
      const routes = []
      const normalizedKey = this.normPath(key)
      const topRouter = this.topbarRouters.find(r => !r.hidden && this.normPath(r.path) === normalizedKey)
      if (topRouter && topRouter.children && topRouter.children.length) {
        topRouter.children.forEach(child => {
          if (!child.hidden) {
            routes.push(this.prefixSidebarRouteTree(child, normalizedKey))
          }
        })
      } else {
        const childrenMenus = this.buildChildrenMenus()
        childrenMenus.forEach(item => {
          if (this.normPath(item.parentPath) === normalizedKey) {
            routes.push(item)
          }
        })
      }
      if (routes.length > 0) {
        this.$store.commit('SET_SIDEBAR_ROUTERS', routes)
      }
      return routes
    },
    /** 为侧栏嵌套菜单补全相对 path，避免子菜单链接跳到 /operLog 等错误路径 */
    prefixSidebarRouteTree(route, parentPath) {
      const cloned = { ...route }
      const seg = (cloned.path || '').replace(/^\//, '')
      if (seg && !this.ishttp(cloned.path) && !cloned.path.startsWith('/')) {
        cloned.path = this.normPath(parentPath) + '/' + seg
      } else if (cloned.path && !cloned.path.startsWith('/') && !this.ishttp(cloned.path)) {
        cloned.path = '/' + cloned.path
      }
      if (cloned.children && cloned.children.length) {
        cloned.children = cloned.children.map(child =>
          this.prefixSidebarRouteTree(child, cloned.path)
        )
      }
      return cloned
    },
    getFirstRoutePath(routes) {
      if (!routes || !routes.length) return null
      for (let i = 0; i < routes.length; i++) {
        const route = routes[i]
        if (route.hidden) continue
        if (route.children && route.children.length) {
          const childPath = this.getFirstRoutePath(route.children)
          if (childPath) return childPath
        }
        if (!route.path || this.ishttp(route.path)) continue
        if (route.path.indexOf('/redirect') !== -1) {
          return route.path.replace('/redirect', '')
        }
        if (route.path.startsWith('/')) {
          return route.path
        }
      }
      return null
    },
    buildChildrenMenus() {
      const childrenMenus = []
      this.topbarRouters.forEach(router => {
        if (!router.children) return
        for (const item in router.children) {
          const child = router.children[item]
          if (child.parentPath === undefined) {
            if (router.path === '/') {
              const seg = (child.path || '').replace(/^\//, '')
              if (seg.indexOf('redirect/') !== 0) {
                child.path = '/redirect/' + seg
              }
            } else if (!this.ishttp(child.path)) {
              const seg = (child.path || '').replace(/^\//, '')
              if (!child.path || !child.path.startsWith('/')) {
                child.path = this.normPath(router.path) + '/' + seg
              }
            }
            child.parentPath = router.path
          }
          childrenMenus.push(child)
        }
      })
      return constantRoutes.concat(childrenMenus)
    },
    syncActiveTopFromRoute() {
      if (!this.topMenus.length) return
      const path = this.$route.path
      let topKey = ''
      if (path.lastIndexOf('/') > 0) {
        const tmp = path.substring(1)
        topKey = '/' + tmp.substring(0, tmp.indexOf('/'))
      } else if (path === '/index' || path === '/') {
        topKey = '/'
      }
      let found = -1
      this.topMenus.forEach((menu, index) => {
        const key = this.resolveTopMenuKey(menu)
        if (topKey && this.normPath(key) === this.normPath(topKey)) {
          found = index
        }
      })
      if (found >= 0) {
        this.activeTopIndex = found
        this.activeRoutes(this.resolveTopMenuKey(this.topMenus[found]))
      }
    },
    ishttp(url) {
      return url && (url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1)
    },
    handleCommand(cmd) {
      if (cmd === 'logout') {
        this.$confirm('确定注销并退出系统吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$store.dispatch('LogOut').then(() => {
            location.href = '/index'
          })
        }).catch(() => {})
      }
    }
  }
}
</script>

<style scoped>
.admin-layout {
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  margin: 0 !important;
  padding: 0 !important;
  position: relative;
}

.top-nav {
  height: 50px;
  background: #fff;
  display: flex;
  align-items: center;
  padding: 0 20px 0 0;
  flex-shrink: 0;
  z-index: 100;
  border-bottom: 1px solid #e8e8e8;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

.nav-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  margin-right: 8px;
  flex-shrink: 0;
  padding: 0 16px;
}

.logo-img {
  width: 32px;
  height: 32px;
  object-fit: contain;
  flex-shrink: 0;
}

.logo-icon {
  width: 32px;
  height: 32px;
  background: linear-gradient(135deg, #409eff, #1890ff);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 17px;
  flex-shrink: 0;
}

.logo-text {
  font-size: 17px;
  font-weight: 600;
  color: #303133;
  white-space: nowrap;
}

.logo-home-badge {
  width: 20px;
  height: 20px;
  border-radius: 4px;
  background: rgba(64, 158, 255, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-left: 4px;
  flex-shrink: 0;
}

.logo-home-badge i {
  font-size: 13px;
  color: #409eff;
}

.nav-divider {
  width: 1px;
  height: 24px;
  background: #e8e8e8;
  margin-right: 8px;
  flex-shrink: 0;
}

.nav-menu {
  display: flex;
  align-items: center;
  flex: 1;
  overflow: hidden;
  min-width: 0;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 18px;
  height: 50px;
  cursor: pointer;
  color: #606266;
  font-size: 14px;
  white-space: nowrap;
  flex-shrink: 0;
  border-bottom: 2px solid transparent;
  box-sizing: border-box;
}

.nav-item:hover {
  color: #409eff;
}

.nav-item.active {
  color: #409eff;
  border-bottom-color: #409eff;
  font-weight: 500;
}

.nav-item .svg-icon {
  font-size: 16px;
}

.user-area {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  flex-shrink: 0;
  padding-left: 12px;
}

.header-tool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 6px;
  font-size: 18px;
  color: #5a5e66;
  cursor: pointer;
}

.header-tool:hover {
  color: #409eff;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 8px;
}

.user-avatar {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: linear-gradient(135deg, #409eff, #1890ff);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
}

.user-role {
  font-size: 13px;
  color: #909399;
}

.nav-user {
  display: flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 6px;
}

.nav-user:hover {
  background: rgba(64, 158, 255, 0.08);
}

.nav-username {
  font-size: 14px;
  color: #303133;
}

.dropdown-arrow {
  color: #909399;
  font-size: 12px;
}

.main-container {
  flex: 1;
  display: flex;
  overflow: hidden;
  margin: 0 !important;
  padding: 0 !important;
}

.sidebar {
  width: 200px;
  flex-shrink: 0;
  background: #fafbff;
  border-right: 1px solid #e8e8e8;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.sidebar-dashboard {
  background: #fafbff;
}

.saas-sidebar-panel {
  flex: 1;
  min-height: 0;
  width: 100% !important;
  border-right: none !important;
  background: transparent !important;
}

.dashboard-shortcuts {
  padding: 16px 12px;
}

.shortcuts-title {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 600;
  color: #999;
  padding: 0 4px 10px;
  border-bottom: 1px solid #f0f0f0;
  margin-bottom: 8px;
}

.shortcut-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 8px;
  cursor: pointer;
  color: #555;
  font-size: 14px;
  margin-bottom: 2px;
}

.shortcut-item:hover {
  background: #ede9fe;
  color: #4f46e5;
}

.shortcut-item .svg-icon {
  color: #8b5cf6;
}

.content-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: #f5f6fa;
  min-width: 0;
}

.content-area >>> .tags-view-container {
  flex-shrink: 0;
}

.content-area >>> .app-main {
  flex: 1;
  overflow: auto;
  min-height: 0;
  width: 100%;
  box-sizing: border-box;
  /* 仅留一层外边距，避免与 .app-container 叠加缩窄内容区 */
  padding: 12px 16px 16px;
  background: #f5f6fa;
}

/* 功能页白卡片铺满内容区，去掉全局 margin 造成的左右大留白 */
.content-area >>> .app-main .app-container {
  margin: 0;
  width: 100%;
  min-height: calc(100vh - 50px - 34px - 28px);
  box-sizing: border-box;
}
</style>

<style scoped>
/* 侧栏菜单样式 — 与 adminUI AdminLayout 一致 */
.sidebar >>> .sidebar-wrapper {
  width: 100%;
  height: 100%;
  background: transparent;
  border: none;
}

.sidebar >>> .sidebar-header {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 600;
  color: #999;
  letter-spacing: 0.5px;
  padding: 16px 16px 10px;
  border-bottom: 1px solid #f0f0f0;
  background: #fafbff;
}

.sidebar >>> .sidebar-menu {
  border: none;
  padding: 8px 12px;
  background-color: #fafbff !important;
}

.sidebar >>> .el-menu-item {
  height: 50px !important;
  line-height: 50px !important;
  font-size: 14px !important;
  padding-left: 24px !important;
  color: #555 !important;
  border-radius: 8px;
  margin-bottom: 2px;
}

.sidebar >>> .el-submenu__title {
  height: 50px !important;
  line-height: 50px !important;
  font-size: 14px !important;
  font-weight: 500;
  color: #555 !important;
  border-radius: 8px;
  margin-bottom: 2px;
}

.sidebar >>> .el-menu-item .svg-icon,
.sidebar >>> .el-submenu__title .svg-icon {
  margin-right: 8px;
  color: #8b5cf6 !important;
}

.sidebar >>> .el-submenu .el-menu-item {
  padding-left: 44px !important;
  height: 46px !important;
  line-height: 46px !important;
  font-size: 13px !important;
  min-width: auto !important;
}

.sidebar >>> .el-menu-item.is-active {
  background-color: #ede9fe !important;
  color: #4f46e5 !important;
  font-weight: 600;
  border-left: 3px solid #4f46e5 !important;
  padding-left: 21px !important;
}

.sidebar >>> .el-menu-item:hover,
.sidebar >>> .el-submenu__title:hover {
  background-color: #ede9fe !important;
  color: #4f46e5 !important;
}

.sidebar >>> .el-submenu .el-menu-item:hover {
  background-color: #ede9fe !important;
  color: #4f46e5 !important;
}
</style>
