<template>
  <section class="layout">
    <!-- 顶部导航栏：固定在顶部 -->
    <Header :isSmallScreen="screenWidth < COLLAPSE_BREAKPOINT" @toggle-sidebar="handleToggleSidebar" />

    <!-- 主体内容区域 -->
    <section class="main-container" :class="{ 'is-collapsed': sidebarCollapsed }">
      <!-- 左侧侧边菜单：固定在左侧 -->
      <Sidebar :collapsed="sidebarCollapsed" />

      <!-- 右侧内容区：页签 + 主体内容 -->
      <section class="content-container">
        <!-- 页签标签栏 -->
        <Tabs />

        <!-- 主体内容区 -->
        <main class="main-content">
          <transition
            name="fade-transform"
            mode="out-in"
            style="height: 100%; display: flex; flex-direction: column"
          >
            <router-view v-slot="{ Component }">
              <!-- 使用 :key 确保每次路由变化都会创建新的 ErrorBoundary 实例 -->
              <ErrorBoundary :key="route.path + '-' + refreshKey">
                <KeepAlive v-if="route.meta.keepAlive">
                  <component :is="Component" :key="refreshKey" />
                </KeepAlive>
                <component v-else :is="Component" :key="refreshKey" />
              </ErrorBoundary>
            </router-view>
          </transition>
        </main>
      </section>
    </section>
  </section>
</template>

<script setup lang="ts">
defineOptions({
  name: 'Layout',
})
import Header from './Header.vue'
import Sidebar from './Sidebar.vue'
import Tabs from './Tabs.vue'
import ErrorBoundary from '@/components/common/ErrorBoundary.vue'
import { useTabsStore } from '@/stores/modules/tabs'

const route = useRoute()
const tabsStore = useTabsStore()

// 用于组件重新渲染的 key
const refreshKey = computed(() => {
  // 当 refreshKey 包含当前路由时，重新渲染组件
  if (tabsStore.refreshKey.startsWith(route.path)) {
    return tabsStore.refreshKey
  }
  return route.path
})

// 侧边栏收缩状态
const sidebarCollapsed = ref(false)

// 屏幕宽度监听
const screenWidth = ref(window.innerWidth)

// 响应式收起侧边栏的阈值（单位：px）
const COLLAPSE_BREAKPOINT = 992

// 监听屏幕宽度变化
const handleResize = () => {
  screenWidth.value = window.innerWidth
  // 当屏幕宽度小于阈值时自动收起侧边栏
  if (screenWidth.value < COLLAPSE_BREAKPOINT) {
    sidebarCollapsed.value = true
  }else {
    // sidebarCollapsed.value = false
  }
}

onMounted(() => {
  // 初始化时判断屏幕宽度
  handleResize()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
})

// 切换侧边栏
const handleToggleSidebar = (collapsed: boolean) => {
  sidebarCollapsed.value = collapsed
}
</script>

<style scoped lang="scss">
.layout {
  width: 100%;
  height: 100vh;
  overflow: hidden;
  background: var(--el-bg-color-page);

  .main-container {
    display: flex;
    height: calc(100vh - 50px);
    margin-top: 50px;
    transition: margin-left 0.3s ease;

    &.is-collapsed {
      .content-container {
        margin-left: 64px;
      }
    }

    .content-container {
      flex: 1;
      display: flex;
      flex-direction: column;
      overflow: hidden;
      margin-left: 200px;
      transition: margin-left 0.3s ease;

      .main-content {
        flex: 1;
        overflow-y: auto;
        overflow-x: hidden;
        // background: white;
      }
    }
  }
}

// 响应式侧边栏收起
@media screen and (max-width: 992px) {
  .layout {
    .main-container {
      &.is-collapsed {
        .content-container {
          margin-left: 64px;
        }
      }
    }
  }
}

// 页面切换动画
.fade-transform-enter-active,
.fade-transform-leave-active {
  transition: all 0.3s;
}

.fade-transform-enter-from {
  opacity: 0;
  transform: translateX(30px);
}

.fade-transform-leave-to {
  opacity: 0;
  transform: translateX(-30px);
}
</style>
