<template>
  <div class="relative flex flex-col min-h-screen">
    <!-- Random background -->
    <div class="app-randbg" aria-hidden="true">
      <img
        v-if="randBgUrl"
        class="app-randbg-img"
        :src="randBgUrl"
        alt=""
        decoding="async"
        fetchpriority="low"
      />
    </div>

    <!-- PWA Splash Screen -->
    <SplashScreen :visible="showSplash" />

    <!-- 移动端：菜单遮罩 -->
    <div
      v-show="mobileNavOpen"
      class="fixed inset-0 z-[98] bg-apptext/20 backdrop-blur-[2px] md:hidden motion-safe:transition-opacity"
      aria-hidden="true"
      @click="closeMobileNav"
    />

    <!-- Top navigation -->
    <div class="sticky top-0 z-[100] relative">
      <header
        class="flex items-center justify-between gap-3 min-h-[56px] px-[5vw] py-3 glass-strong border-b border-white/35 shadow-[0_4px_24px_rgba(33,33,40,0.08)] md:min-h-0 md:py-4 md:gap-5 max-md:px-3 max-md:py-2.5"
      >
        <!-- Brand -->
        <div
          class="flex gap-4 items-center cursor-pointer select-none min-w-0 flex-1 md:flex-initial md:gap-4 max-md:gap-2"
          @click="onLogoClick"
        >
          <div class="w-[46px] h-[46px] rounded-[10px] overflow-hidden border border-white/60 glass-strong shadow-[0_12px_24px_rgba(33,33,40,0.18)] flex items-center justify-center shrink-0 max-md:w-9 max-md:h-9">
            <img src="/logo.png" alt="萌芽小店" draggable="false" class="w-full h-full object-contain" />
          </div>
          <div class="min-w-0">
            <h1 class="text-[28px] tracking-wide truncate max-md:text-[15px] max-md:font-semibold">萌芽小店</h1>
          </div>
        </div>

        <!-- Desktop actions -->
        <div class="hidden md:flex gap-3 items-center shrink-0">
          <button type="button" class="ghost" @click="goHome">商店</button>
          <template v-if="loggedIn">
            <button type="button" class="ghost relative inline-flex items-center gap-1" @click="goWishlist">
              <span>☆</span>
              收藏夹
              <span
                v-if="wishlistCount > 0"
                class="inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-gradient-to-br from-accent to-accent2 text-white text-[11px] font-bold leading-none"
              >{{ wishlistCount }}</span>
            </button>
            <button type="button" class="ghost" @click="goMyOrders">我的订单</button>
            <div
              class="flex items-center gap-2 px-3 py-1.5 rounded-full bg-white/60 border border-white/35 cursor-pointer hover:bg-white/85 transition-colors"
              @click="goProfile"
            >
              <img
                v-if="authState.avatarUrl"
                class="w-7 h-7 rounded-full object-cover border border-white/35"
                :src="authState.avatarUrl"
                :alt="authState.username"
              />
              <div
                v-else
                class="w-7 h-7 rounded-full flex items-center justify-center bg-gradient-to-br from-accent to-accent2 text-white text-[15px] font-semibold border border-white/35"
              >
                {{ (authState.username || authState.account || '?').charAt(0) }}
              </div>
              <span class="text-[17px] font-bold text-apptext max-w-[100px] overflow-hidden text-ellipsis whitespace-nowrap">
                {{ authState.username || authState.account }}
              </span>
            </div>
            <button type="button" class="ghost" @click="logout">退出</button>
          </template>
          <a
            v-else
            class="inline-flex items-center px-[18px] py-[10px] rounded-lg bg-gradient-to-br from-accent to-accent2 text-white no-underline text-[17px] shadow-[0_10px_30px_rgba(145,168,208,0.35)] transition-transform hover:-translate-y-px"
            :href="loginUrl"
          >萌芽账号登录</a>
        </div>

        <!-- Mobile menu toggle -->
        <button
          type="button"
          class="md:hidden flex-shrink-0 flex items-center justify-center w-10 h-10 rounded-xl border border-white/50 bg-white/60 text-apptext shadow-sm tap-target"
          :aria-expanded="mobileNavOpen"
          :aria-label="mobileNavOpen ? '关闭菜单' : '打开菜单'"
          @click="mobileNavOpen = !mobileNavOpen"
        >
          <svg v-if="!mobileNavOpen" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
            <path d="M4 6h16M4 12h16M4 18h16"/>
          </svg>
          <svg v-else width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
            <path d="M18 6L6 18M6 6l12 12"/>
          </svg>
        </button>
      </header>

      <!-- Mobile dropdown -->
      <Transition
        enter-active-class="transition ease-out duration-200"
        enter-from-class="opacity-0 -translate-y-2"
        enter-to-class="opacity-100 translate-y-0"
        leave-active-class="transition ease-in duration-150"
        leave-from-class="opacity-100 translate-y-0"
        leave-to-class="opacity-0 -translate-y-2"
      >
        <nav
          v-if="mobileNavOpen"
          class="md:hidden absolute left-0 right-0 top-full z-[101] border-t border-white/35 glass-strong shadow-[0_16px_40px_rgba(33,33,40,0.14)] max-h-[min(75vh,560px)] overflow-y-auto overscroll-contain px-3 py-3 pb-[max(16px,env(safe-area-inset-bottom))]"
          @click.stop
        >
          <div class="flex flex-col gap-2">
            <button type="button" class="app-mobile-nav-btn" @click="navGoHome">商店</button>
            <template v-if="loggedIn">
              <button type="button" class="app-mobile-nav-btn flex items-center justify-between gap-3" @click="navGoWishlist">
                <span class="inline-flex items-center gap-1.5">
                  <span class="text-accent">☆</span>
                  收藏夹
                </span>
                <span
                  v-if="wishlistCount > 0"
                  class="inline-flex items-center justify-center min-w-[22px] h-[22px] px-1.5 rounded-full bg-gradient-to-br from-accent to-accent2 text-white text-[12px] font-bold"
                >{{ wishlistCount }}</span>
              </button>
              <button type="button" class="app-mobile-nav-btn" @click="navGoMyOrders">我的订单</button>
              <button type="button" class="app-mobile-nav-btn flex items-center gap-3 text-left min-w-0" @click="navGoProfile">
                <img
                  v-if="authState.avatarUrl"
                  class="w-9 h-9 rounded-full object-cover border border-white/35 shrink-0"
                  :src="authState.avatarUrl"
                  alt=""
                />
                <div
                  v-else
                  class="w-9 h-9 rounded-full flex items-center justify-center bg-gradient-to-br from-accent to-accent2 text-white text-sm font-semibold shrink-0"
                >
                  {{ (authState.username || authState.account || '?').charAt(0) }}
                </div>
                <span class="font-bold truncate min-w-0">{{ authState.username || authState.account }}</span>
                <span class="text-muted text-[13px] shrink-0 ml-auto">个人主页</span>
              </button>
              <button type="button" class="app-mobile-nav-btn !text-[#b84d5c] !border-[rgba(184,77,92,0.25)]" @click="navLogout">
                退出登录
              </button>
            </template>
            <a
              v-else
              class="app-mobile-nav-btn app-mobile-nav-btn-primary text-center no-underline"
              :href="loginUrl"
              @click="closeMobileNav"
            >萌芽账号登录</a>
          </div>
        </nav>
      </Transition>
    </div>

    <!-- Admin modal -->
    <Teleport to="body">
      <Transition name="modal">
        <div
          v-if="showAdminModal"
          class="admin-modal fixed inset-0 z-[1000] flex items-center justify-center bg-apptext/35 backdrop-blur-lg"
          @click.self="showAdminModal = false"
        >
          <div class="admin-modal relative w-[360px] max-w-[90vw] px-8 pt-9 pb-7 glass-strong rounded-xl shadow-[0_24px_60px_rgba(33,33,40,0.22)] text-center">
            <button
              class="absolute top-3 right-4 bg-transparent border-none text-[22px] text-muted hover:text-apptext cursor-pointer px-2 py-1 rounded leading-none transition-colors"
              @click="showAdminModal = false"
            >&times;</button>
            <div class="inline-flex items-center justify-center w-14 h-14 rounded-[10px] bg-gradient-to-br from-accent to-accent2 text-white mb-4">
              <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
            </div>
            <h3 class="text-[22px] mb-1.5">管理员验证</h3>
            <p class="text-[15px] text-muted mb-5">请输入管理员令牌以访问后台</p>
            <form @submit.prevent="submitAdminToken">
              <input
                ref="tokenInputRef"
                v-model="tokenInput"
                type="password"
                class="w-full px-4 py-3 rounded-lg border border-white/35 bg-white/65 text-center tracking-widest text-[18px] outline-none transition focus:border-accent focus:shadow-[0_0_0_3px_rgba(180,154,203,0.18)]"
                style="font-family: var(--font-serif);"
                placeholder="输入 Token…"
                autocomplete="off"
              />
              <p v-if="tokenError" class="text-[15px] text-[#d4566a] mt-2">{{ tokenError }}</p>
              <button type="submit" class="primary w-full mt-4 py-3 text-[17px]" :disabled="!tokenInput.trim()">
                进入后台
              </button>
            </form>
          </div>
        </div>
      </Transition>
    </Teleport>

    <!-- Page body -->
    <div class="flex-1 flex flex-col px-[5vw] py-7 max-md:px-[2vw] max-md:py-3">
      <main class="flex-1 py-7 min-h-0">
        <router-view />
      </main>

      <!-- Footer -->
      <footer class="mt-3 px-[26px] py-6 glass rounded-[var(--radius-default)] shadow-[0_-4px_30px_rgba(33,33,40,0.06)] max-md:px-3.5 max-md:py-5">
        <div class="flex flex-col items-center gap-3.5">
          <!-- Brand -->
          <div class="flex items-center gap-2.5">
            <img src="/logo.png" alt="萌芽小店" class="w-7 h-7 rounded-[5px] object-contain border border-white/50 shadow-[0_4px_12px_rgba(33,33,40,0.1)]" />
            <span class="text-[19px] font-semibold text-apptext tracking-[0.5px]" style="font-family: var(--font-serif);">萌芽小店</span>
          </div>

          <!-- Divider -->
          <div class="w-10 h-0.5 rounded-full bg-gradient-to-r from-accent to-accent2 opacity-50"></div>

          <!-- Links / stats -->
          <div class="flex items-center gap-6 flex-wrap justify-center max-md:flex-row max-md:flex-wrap max-md:gap-2.5 max-md:justify-center">
            <a
              class="inline-flex items-center gap-1.5 text-[#3d5a88] no-underline text-[15px] font-semibold px-3 py-1.5 rounded bg-[rgba(145,168,208,0.12)] hover:bg-[rgba(145,168,208,0.22)] transition-colors"
              href="mailto:mail@smyhub.com"
            >
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>
              mail@smyhub.com
            </a>
            <span v-if="statsLoaded" class="inline-flex items-center gap-1.5 text-[15px] font-semibold text-[#6b4d85] px-3 py-1.5 rounded bg-[rgba(180,154,203,0.12)]">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20V10"/><path d="M18 20V4"/><path d="M6 20v-4"/></svg>
              累计下单 {{ stats.totalOrders }} 次
            </span>
            <span v-if="statsLoaded" class="inline-flex items-center gap-1.5 text-[15px] font-semibold text-[#3d5a88] px-3 py-1.5 rounded bg-[rgba(145,168,208,0.12)]">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg>
              累计访问 {{ stats.totalVisits }} 次
            </span>
          </div>

          <p class="text-[14px] text-[#45424a]/95 tracking-[0.3px]">© 2025 – 2026 萌芽小店 · All rights reserved</p>
        </div>
      </footer>
    </div>

    <!-- Floating chat widget -->
    <ChatWidget
      v-if="loggedIn && authState.token"
      :user-token="authState.token"
      :user-name="authState.username || authState.account"
      :user-avatar="authState.avatarUrl"
    />

    <!-- PWA update toast -->
    <Transition name="pwa-toast">
      <div
        v-if="needRefresh"
        class="fixed bottom-20 left-1/2 -translate-x-1/2 z-[9999] flex items-center gap-3 px-[18px] py-2.5 rounded-3xl bg-[#1a1a1a] text-white text-[13px] shadow-[0_4px_24px_rgba(0,0,0,0.25)] whitespace-nowrap"
      >
        <span>发现新版本</span>
        <button
          class="bg-[#4ade80] text-[#111] border-none rounded-xl px-3.5 py-1 text-xs font-semibold cursor-pointer"
          @click="updateServiceWorker(true)"
        >立即更新</button>
      </div>
    </Transition>
  </div>
</template>

<script setup>
import { computed, nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { verifyAdminToken, fetchStats, recordSiteVisit } from './modules/shared/api'
import { authState, isLoggedIn, clearAuth, getLoginUrl } from './modules/shared/auth'
import { wishlistCount, loadWishlist } from './modules/shared/useWishlist'
import ChatWidget from './modules/chat/ChatWidget.vue'
import SplashScreen from './modules/shared/SplashScreen.vue'
import { useRegisterSW } from 'virtual:pwa-register/vue'

const RAND_BG_JSON_URL = 'https://randbg.api.smyhub.com/api/random?format=json'

const { needRefresh, updateServiceWorker } = useRegisterSW({
  onRegisteredSW(swUrl, r) {
    if (r) setInterval(() => r.update(), 1000 * 60 * 60)
  }
})

const showSplash = ref(true)
const randBgUrl = ref('')

const router = useRouter()
const stats = reactive({ totalOrders: 0, totalVisits: 0 })
const statsLoaded = ref(false)

const loggedIn = computed(() => isLoggedIn())
const loginUrl = computed(() => getLoginUrl())

const showAdminModal = ref(false)
const tokenInput = ref('')
const tokenError = ref('')
const tokenInputRef = ref(null)

let logoClickCount = 0
let logoClickTimer = null
const CLICK_THRESHOLD = 5
const CLICK_WINDOW_MS = 2000

const onLogoClick = () => {
  logoClickCount++
  clearTimeout(logoClickTimer)
  if (logoClickCount >= CLICK_THRESHOLD) {
    logoClickCount = 0
    tokenInput.value = ''
    tokenError.value = ''
    showAdminModal.value = true
    nextTick(() => tokenInputRef.value?.focus())
    return
  }
  logoClickTimer = setTimeout(() => { logoClickCount = 0 }, CLICK_WINDOW_MS)
}

const submitAdminToken = async () => {
  const input = tokenInput.value.trim()
  if (!input) return
  tokenError.value = ''
  try {
    const valid = await verifyAdminToken(input)
    if (valid) {
      showAdminModal.value = false
      router.push(`/admin?token=${encodeURIComponent(input)}`)
    } else {
      tokenError.value = '令牌错误，请重试'
    }
  } catch {
    tokenError.value = '验证失败，无法连接服务器'
  }
}

const goHome = () => { router.push('/') }
const goMyOrders = () => { router.push('/my/orders') }
const goWishlist = () => { router.push('/wishlist') }

const goProfile = () => {
  if (authState.account) {
    window.open(`https://auth.shumengya.top/user/${authState.account}`, '_blank')
  }
}

const logout = () => { clearAuth() }

const mobileNavOpen = ref(false)
const closeMobileNav = () => {
  mobileNavOpen.value = false
}
const navGoHome = () => {
  closeMobileNav()
  goHome()
}
const navGoWishlist = () => {
  closeMobileNav()
  goWishlist()
}
const navGoMyOrders = () => {
  closeMobileNav()
  goMyOrders()
}
const navGoProfile = () => {
  closeMobileNav()
  goProfile()
}
const navLogout = () => {
  closeMobileNav()
  logout()
}

watch(() => router.currentRoute.value.fullPath, () => {
  closeMobileNav()
})

watch(mobileNavOpen, (open) => {
  if (typeof document === 'undefined') return
  document.body.style.overflow = open ? 'hidden' : ''
})

const onNavEscape = (e) => {
  if (e.key === 'Escape') closeMobileNav()
}

const SPLASH_MIN_MS = 1400

onMounted(async () => {
  const splashStart = Date.now()

  fetch(RAND_BG_JSON_URL)
    .then((r) => r.json())
    .then((data) => {
      if (data && typeof data.url === 'string') randBgUrl.value = data.url
    })
    .catch(() => {})

  await loadWishlist()
  try {
    recordSiteVisit().then((result) => {
      if (result.totalVisits) stats.totalVisits = result.totalVisits
    }).catch(() => {})
    const data = await fetchStats()
    stats.totalOrders = data.totalOrders || 0
    stats.totalVisits = data.totalVisits || 0
    statsLoaded.value = true
  } catch (e) {
    statsLoaded.value = false
  }

  const elapsed = Date.now() - splashStart
  const remaining = SPLASH_MIN_MS - elapsed
  setTimeout(() => { showSplash.value = false }, remaining > 0 ? remaining : 0)

  window.addEventListener('keydown', onNavEscape)
})

onUnmounted(() => {
  window.removeEventListener('keydown', onNavEscape)
  if (typeof document !== 'undefined') document.body.style.overflow = ''
})

watch(() => authState.token, async (newToken) => {
  if (newToken) {
    await loadWishlist()
  }
})
</script>

<style scoped>
.app-mobile-nav-btn {
  width: 100%;
  box-sizing: border-box;
  text-align: left;
  padding: 0.875rem 1rem;
  border-radius: 0.75rem;
  border: 1px solid var(--line-color);
  background: rgba(255, 255, 255, 0.58);
  color: var(--color-apptext);
  font-size: 16px;
  font-weight: 700;
  font-family: var(--font-serif);
  cursor: pointer;
  transition: background 0.15s ease, transform 0.12s ease;
}
.app-mobile-nav-btn:hover {
  background: rgba(255, 255, 255, 0.78);
}
.app-mobile-nav-btn:active {
  transform: scale(0.99);
}
.app-mobile-nav-btn-primary {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent2));
  color: #fff !important;
  border-color: transparent;
  box-shadow: 0 8px 24px rgba(145, 168, 208, 0.35);
}
.tap-target {
  min-width: 44px;
  min-height: 44px;
}
</style>
