<template>
  <div v-if="isPreview" style="background:#e65100;color:white;text-align:center;padding:6px 16px;font-size:13px;font-weight:600;letter-spacing:0.5px;position:sticky;top:0;z-index:100">
    ⚠️ 预览环境 · PR #{{ prId }} · 数据为生产副本，修改不影响正式环境 · {{ buildInfo }}
  </div>
  <div class="app-header">
    <div class="header-inner">
      <div class="header-left">
        <div class="header-icon">🌿</div>
        <div class="header-title">
          <h1>doTERRA 配方计算器</h1>
          <p>查询配方 · 计算成本 · 自制配方 · 导出卡片 · 精油知识</p>
          <p v-if="auth.isAdmin" class="version-info">v2.0.0 · 2026-04-10</p>
        </div>
      </div>
      <div class="header-right" @click="toggleUserMenu">
        <template v-if="auth.isLoggedIn">
          <span v-if="auth.isBusiness" class="biz-badge" title="商业认证用户">🏢</span>
          <span class="user-name">{{ auth.user.display_name || auth.user.username }} ▾</span>
          <span v-if="unreadNotifCount > 0" class="notif-badge">{{ unreadNotifCount }}</span>
        </template>
        <template v-else>
          <span class="login-btn">登录</span>
        </template>
      </div>
    </div>
  </div>

  <!-- User Menu Popup -->
  <UserMenu v-if="showUserMenu" @close="showUserMenu = false; loadUnreadCount()" />

  <!-- Nav tabs -->
  <div class="nav-tabs" ref="navTabsRef" :style="isPreview ? { top: '36px' } : {}">
    <div v-for="tab in visibleTabs" :key="tab.key"
      class="nav-tab"
      :class="{ active: ui.currentSection === tab.key }"
      @click="handleTabClick(tab)"
    >{{ tab.icon }} {{ tab.label }}</div>
  </div>

  <!-- Main content -->
  <div class="main" @touchstart="onSwipeStart" @touchend="onSwipeEnd">
    <router-view />
  </div>

  <!-- Login Modal -->
  <LoginModal v-if="ui.showLoginModal" @close="ui.closeLogin()" />

  <!-- Custom Dialog -->
  <CustomDialog />

  <!-- Toast messages -->
  <div v-for="toast in ui.toasts" :key="toast.id" class="toast">{{ toast.msg }}</div>
</template>

<script setup>
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useAuthStore } from './stores/auth'
import { useOilsStore } from './stores/oils'
import { useRecipesStore } from './stores/recipes'
import { useUiStore } from './stores/ui'
import LoginModal from './components/LoginModal.vue'
import CustomDialog from './components/CustomDialog.vue'
import UserMenu from './components/UserMenu.vue'
import { api } from './composables/useApi'

const auth = useAuthStore()
const oils = useOilsStore()
const recipeStore = useRecipesStore()
const ui = useUiStore()
const router = useRouter()
const route = useRoute()
const showUserMenu = ref(false)
const navTabsRef = ref(null)

// Tab 定义，顺序固定
// require: 点击时需要的条件，不满足则提示
// hide: 完全隐藏（只有满足条件才显示）
const allTabs = [
  { key: 'search',    icon: '🔍', label: '配方查询' },
  { key: 'manage',    icon: '📋', label: '管理配方',  require: 'login' },
  { key: 'inventory', icon: '📦', label: '个人库存',  require: 'login' },
  { key: 'oils',      icon: '💧', label: '精油价目' },
  { key: 'projects',  icon: '💼', label: '商业核算',  require: 'login' },
]

// 所有人都能看到大部分 tab，bug 和用户管理只有 admin 可见
const visibleTabs = computed(() => allTabs.filter(t => {
  if (!t.hide) return true
  if (t.hide === 'admin') return auth.isAdmin
  return true
}))
const unreadNotifCount = ref(0)

async function loadUnreadCount() {
  if (!auth.isLoggedIn) return
  try {
    const res = await api('/api/notifications')
    if (res.ok) {
      const data = await res.json()
      unreadNotifCount.value = data.filter(n => !n.is_read).length
    }
  } catch {}
}

// Sync ui.currentSection from route on load and navigation
const routeToSection = { '/': 'search', '/manage': 'manage', '/inventory': 'inventory', '/oils': 'oils', '/projects': 'projects', '/mydiary': 'mydiary', '/audit': 'audit', '/bugs': 'bugs', '/users': 'users' }
watch(() => route.path, (path) => {
  const section = routeToSection[path] || 'search'
  ui.showSection(section)
  nextTick(() => scrollActiveTabToCenter())
}, { immediate: true })

// Preview environment detection: pr-{id}.oil.oci.euphon.net
const hostname = window.location.hostname
const prMatch = hostname.match(/^pr-(\d+)\./)
const isPreview = !!prMatch
const prId = prMatch ? prMatch[1] : ''
const buildInfo = __BUILD_TIME__ || ''

function handleTabClick(tab) {
  if (tab.require === 'login' && !auth.isLoggedIn) {
    ui.openLogin(() => goSection(tab.key))
    return
  }
  if (tab.require === 'business' && !auth.isBusiness) {
    if (!auth.isLoggedIn) {
      ui.openLogin(() => goSection(tab.key))
    } else {
      ui.showToast('需要商业认证才能使用此功能')
    }
    return
  }
  goSection(tab.key)
}

function goSection(name) {
  ui.showSection(name)
  router.push('/' + (name === 'search' ? '' : name))
  nextTick(() => scrollActiveTabToCenter())
}

function scrollActiveTabToCenter() {
  if (!navTabsRef.value) return
  const active = navTabsRef.value.querySelector('.nav-tab.active')
  if (!active) return
  const container = navTabsRef.value
  const scrollLeft = active.offsetLeft - container.clientWidth / 2 + active.clientWidth / 2
  container.scrollTo({ left: scrollLeft, behavior: 'smooth' })
}

function requireLogin(name) {
  if (!auth.isLoggedIn) {
    ui.openLogin()
    return
  }
  goSection(name)
}

function toggleUserMenu() {
  if (!auth.isLoggedIn) {
    ui.openLogin()
    return
  }
  showUserMenu.value = !showUserMenu.value
}

// ── 左右滑动切换 tab ──
// 滑动顺序 = visibleTabs 的顺序（根据用户角色动态决定）
// 轮播区域（data-no-tab-swipe）内的滑动不触发 tab 切换
const swipeStartX = ref(0)
const swipeStartY = ref(0)

function onSwipeStart(e) {
  swipeStartX.value = e.touches[0].clientX
  swipeStartY.value = e.touches[0].clientY
}

function onSwipeEnd(e) {
  const dx = e.changedTouches[0].clientX - swipeStartX.value
  const dy = e.changedTouches[0].clientY - swipeStartY.value
  // 必须是水平滑动 > 50px，且水平距离大于垂直距离
  if (Math.abs(dx) < 50 || Math.abs(dy) > Math.abs(dx)) return
  // 轮播区域内不触发 tab 切换
  if (e.target.closest && e.target.closest('[data-no-tab-swipe]')) return

  const tabs = visibleTabs.value.map(t => t.key)
  const currentIdx = tabs.indexOf(ui.currentSection)
  if (currentIdx < 0) return

  let nextIdx = -1
  if (dx < 0 && currentIdx < tabs.length - 1) nextIdx = currentIdx + 1
  else if (dx > 0 && currentIdx > 0) nextIdx = currentIdx - 1
  if (nextIdx >= 0) {
    const tab = visibleTabs.value[nextIdx]
    handleTabClick(tab)
  }
}

onMounted(async () => {
  await auth.initToken()
  await Promise.all([
    oils.loadOils(),
    recipeStore.loadRecipes(),
    recipeStore.loadTags(),
  ])
  if (auth.isLoggedIn) {
    await recipeStore.loadFavorites()
    await loadUnreadCount()
  }

  // Periodic refresh
  setInterval(async () => {
    if (document.visibilityState !== 'visible') return
    try {
      await auth.loadMe()
      await loadUnreadCount()
    } catch {}
  }, 15000)
})
</script>

<style scoped>
.header-inner {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  position: relative;
  z-index: 1;
}
.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
}
.header-icon { font-size: 36px; flex-shrink: 0; }
.header-title { color: white; min-width: 0; }
.header-title h1 {
  font-family: 'Noto Serif SC', serif;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.header-title p {
  font-size: 12px;
  opacity: 0.8;
  margin-top: 3px;
  letter-spacing: 0.5px;
  white-space: nowrap;
}
.version-info {
  font-size: 10px !important;
  opacity: 0.5 !important;
  margin-top: 1px !important;
}
.header-right {
  flex-shrink: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
}
.user-name {
  color: white;
  font-size: 13px;
  font-weight: 500;
  opacity: 0.95;
  white-space: nowrap;
}
.notif-badge {
  background: #e53935;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  min-width: 18px;
  height: 18px;
  line-height: 18px;
  text-align: center;
  border-radius: 9px;
  padding: 0 5px;
  margin-left: 4px;
}
.login-btn {
  color: white;
  background: rgba(255,255,255,0.2);
  padding: 5px 14px;
  border-radius: 12px;
  font-size: 13px;
}
.biz-badge { font-size: 14px; }
@media (max-width: 480px) {
  .header-icon { font-size: 28px; }
  .header-title h1 { font-size: 18px; }
  .header-title p { font-size: 10px; }
}
</style>
