<template>
  <div class="layout-cloud" :class="{ 'is-nav-open': sidebarOpen }">
    <div class="nav-backdrop" aria-hidden="true" @click="sidebarOpen = false" />

    <aside class="sidebar" role="navigation" :aria-hidden="desktopNav ? undefined : !sidebarOpen">
      <div class="sidebar-brand">
        <button type="button" class="sidebar-close" aria-label="关闭菜单" @click="sidebarOpen = false">
          ×
        </button>
        <div class="brand-title">抖音 Cookie 提取</div>
        <div class="brand-sub">扫码登录 · JSON 导出</div>
      </div>

      <nav class="sidebar-nav">
        <router-link
          v-for="item in navItems"
          :key="item.name"
          :to="{ name: item.name }"
          class="nav-item"
          exact-active-class="nav-item-active"
          @click="onNavClick"
        >
          {{ item.label }}
        </router-link>
      </nav>

      <div class="sidebar-footer">
        <button type="button" class="btn btn-soft full-width" @click="refreshAll">刷新状态</button>
      </div>
    </aside>

    <div class="main-wrap">
      <header class="mobile-topbar">
        <button
          type="button"
          class="nav-toggle"
          aria-label="打开菜单"
          :aria-expanded="sidebarOpen"
          @click="sidebarOpen = true"
        >
          <span class="nav-toggle-bar"></span>
          <span class="nav-toggle-bar"></span>
          <span class="nav-toggle-bar"></span>
        </button>
        <span class="mobile-title">Cookie 提取</span>
      </header>
      <main class="main-inner">
        <router-view v-slot="{ Component }">
          <transition name="fade" mode="out-in">
            <component :is="Component" />
          </transition>
        </router-view>
      </main>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()
const sidebarOpen = ref(false)
const desktopNav = ref(true)

const navItems = [
  { name: 'home', label: '扫码提取' },
  { name: 'debug', label: 'SSO 调试' },
]

let mq
function syncMq() {
  desktopNav.value = typeof window !== 'undefined' && window.matchMedia('(min-width: 900px)').matches
  if (desktopNav.value) sidebarOpen.value = false
}

function refreshAll() {
  window.dispatchEvent(new CustomEvent('douyin-refresh-all'))
}

function onNavClick() {
  if (!desktopNav.value) sidebarOpen.value = false
}

function onKeydown(e) {
  if (e.key === 'Escape' && sidebarOpen.value) sidebarOpen.value = false
}

watch(
  () => route.fullPath,
  () => {
    if (!desktopNav.value) sidebarOpen.value = false
  },
)

watch(sidebarOpen, (open) => {
  if (typeof document === 'undefined') return
  document.body.style.overflow = open && !desktopNav.value ? 'hidden' : ''
})

onMounted(() => {
  syncMq()
  mq = window.matchMedia('(min-width: 900px)')
  mq.addEventListener('change', syncMq)
  window.addEventListener('keydown', onKeydown)
})
onUnmounted(() => {
  if (mq) mq.removeEventListener('change', syncMq)
  window.removeEventListener('keydown', onKeydown)
  document.body.style.overflow = ''
})
</script>

<style scoped>
.layout-cloud {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
  height: 100vh;
  height: 100dvh;
  max-height: 100vh;
  max-height: 100dvh;
  overflow: hidden;
}

.nav-backdrop {
  display: none;
}

.sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  align-self: stretch;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border-light);
  display: flex;
  flex-direction: column;
  box-shadow: 1px 0 0 rgba(0, 0, 0, 0.04);
  min-height: 0;
}

.sidebar-brand {
  position: relative;
  flex-shrink: 0;
  padding: 1rem 0.75rem 0.85rem;
  border-bottom: 1px solid var(--border-light);
}

.sidebar-close {
  display: none;
  position: absolute;
  top: 0.75rem;
  right: 0.65rem;
  width: var(--tap-min, 44px);
  height: var(--tap-min, 44px);
  margin: 0;
  padding: 0;
  border: none;
  background: #f5f7fa;
  border-radius: var(--radius-sm);
  font-size: 1.5rem;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
}

.brand-title {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text-strong);
  letter-spacing: -0.02em;
  padding-right: 2.5rem;
}

.brand-sub {
  font-size: 0.75rem;
  color: var(--muted);
  margin-top: 0.25rem;
}

.sidebar-nav {
  flex: 1;
  min-height: 0;
  padding: 0.55rem 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  overflow-y: auto;
}

.nav-item {
  display: flex;
  align-items: center;
  min-height: var(--tap-min, 44px);
  padding: 0.45rem 0.6rem;
  border-radius: var(--radius-sm);
  color: var(--text-strong);
  font-size: 0.875rem;
  border: 1px solid #e8e8e8;
  background: #ffffff;
  text-decoration: none;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.nav-item:hover {
  background: #f7f8fa;
  border-color: #dcdfe6;
}

.nav-item-active {
  background: #eef5fe !important;
  color: #3b82f6 !important;
  font-weight: 600;
  border-color: #bfdbfe !important;
}

.sidebar-footer {
  flex-shrink: 0;
  padding: 0.55rem 0.5rem;
  border-top: 1px solid var(--border-light);
  padding-bottom: max(0.55rem, env(safe-area-inset-bottom));
}

.full-width {
  width: 100%;
}

.sidebar-footer .btn-soft {
  background: #f5f5f5;
  border-color: #e8e8e8;
  color: #303133;
}

.mobile-topbar {
  display: none;
}

.main-wrap {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.main-inner {
  flex: 1;
  width: 100%;
  min-width: 0;
  min-height: 0;
  box-sizing: border-box;
  padding-top: var(--main-pad-y);
  padding-bottom: max(var(--main-pad-y), env(safe-area-inset-bottom));
  padding-left: var(--main-pad-start);
  padding-right: var(--main-pad-end);
  overflow: auto;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.12s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

@media (max-width: 899px) {
  .sidebar-close {
    display: block;
  }

  .nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 250;
    background: rgba(0, 0, 0, 0.45);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.2s ease, visibility 0.2s;
  }

  .layout-cloud.is-nav-open .nav-backdrop {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  }

  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: min(260px, 86vw);
    z-index: 300;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
  }

  .layout-cloud.is-nav-open .sidebar {
    transform: translateX(0);
    box-shadow: 4px 0 24px rgba(0, 0, 0, 0.12);
  }

  .mobile-topbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-shrink: 0;
    padding: 0.5rem var(--main-pad-end, var(--main-pad-x));
    padding-top: max(0.5rem, env(safe-area-inset-top));
    background: var(--surface);
    border-bottom: 1px solid var(--border-light);
    position: sticky;
    top: 0;
    z-index: 100;
  }

  .nav-toggle {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: var(--tap-min, 44px);
    height: var(--tap-min, 44px);
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    cursor: pointer;
  }

  .nav-toggle-bar {
    display: block;
    height: 2px;
    background: var(--text-strong);
    border-radius: 1px;
  }

  .mobile-title {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text-strong);
  }
}
</style>
