<script setup lang="ts">
import { useAuthSession } from '../composables/useAuthSession'
import {
  publicHomeLayoutModeKey,
  type PublicHomeLayoutMode,
} from '../composables/usePublicHomeLayout'
import { unwrapApiBody, type ApiResponse } from '../utils/http/factory'

const route = useRoute()
const { loggedIn, user, clear, initialized, ensureClientMeSynced } = useAuthSession()
const { fetchData } = useClientApi()
const { siteName, allowRegister } = useGlobalConfig()
const logoutLoading = ref(false)

const showPublicLayoutToggle = computed(() => /^\/@[^/]+$/.test(route.path))
const profileSlug = computed(() => {
  const s = route.params.publicSlug
  return typeof s === 'string' && s.length ? s : ''
})

/** 顶栏「控制台」仅在看自己的 /@slug 时显示；浏览他人主页时不显示控制台也不显示登录 */
const showPublicConsoleLink = computed(() => {
  if (!loggedIn.value || !user.value) {
    return false
  }
  const slug = profileSlug.value.trim().toLowerCase()
  if (!slug) {
    return true
  }
  const mine = user.value.publicSlug?.trim().toLowerCase() ?? ''
  return mine !== '' && mine === slug
})

type PublicHomeHeaderPayload = { title: string; iconUrl: string | null }

const { data: publicHomeHeader } = await useAsyncData(
  () => `public-home-header:${profileSlug.value || 'none'}`,
  async () => {
    const slug = profileSlug.value
    if (!slug) {
      return null
    }
    try {
      const res = await $fetch<ApiResponse<PublicHomeHeaderPayload>>(
        `/api/public/profile/${encodeURIComponent(slug)}/home-header`,
      )
      return unwrapApiBody(res)
    }
    catch {
      return null
    }
  },
  { watch: [profileSlug] },
)

const headerBrandTo = computed(() => (profileSlug.value ? `/@${profileSlug.value}` : '/'))
const headerBrandTitle = computed(() => {
  if (!profileSlug.value) {
    return siteName.value
  }
  const t = publicHomeHeader.value?.title
  if (typeof t === 'string' && t.trim().length) {
    return t.trim()
  }
  return siteName.value
})
const headerBrandIconUrl = computed(() => {
  if (!profileSlug.value) {
    return null
  }
  const u = publicHomeHeader.value?.iconUrl
  if (typeof u !== 'string' || !u.trim()) {
    return null
  }
  return u.trim()
})

const showPublicLogin = computed(() => !loggedIn.value && initialized.value)
const showPublicRegister = computed(() =>
  !loggedIn.value && initialized.value && allowRegister.value,
)

async function logout() {
  logoutLoading.value = true
  try {
    await fetchData<{ success: boolean }>('/api/auth/logout', { method: 'POST' })
    clear()
    await navigateTo('/')
  } finally {
    logoutLoading.value = false
  }
}

type LayoutBySlug = Record<string, PublicHomeLayoutMode>

const layoutBySlug = useCookie<LayoutBySlug>('public_home_layout', {
  default: () => ({}),
  maxAge: 60 * 60 * 24 * 400,
  sameSite: 'lax',
})

function cookieModeForSlug(slug: string): PublicHomeLayoutMode {
  const m = layoutBySlug.value[slug]
  return m === 'detailed' || m === 'showcase' ? m : 'showcase'
}

const publicLayoutMode = ref<PublicHomeLayoutMode>('showcase')
provide(publicHomeLayoutModeKey, publicLayoutMode)

function syncModeFromCookie() {
  if (!showPublicLayoutToggle.value || !profileSlug.value) {
    return
  }
  publicLayoutMode.value = cookieModeForSlug(profileSlug.value)
}

syncModeFromCookie()
watch([profileSlug, showPublicLayoutToggle, layoutBySlug], syncModeFromCookie)

watch(publicLayoutMode, (m) => {
  if (!showPublicLayoutToggle.value || !profileSlug.value) {
    return
  }
  layoutBySlug.value = { ...layoutBySlug.value, [profileSlug.value]: m }
})

onMounted(() => {
  ensureClientMeSynced().catch(() => {})
})
</script>

<template>
  <UApp>
    <div class="min-h-screen bg-default text-default">
      <header class="sticky top-0 z-40 border-b border-default/70 bg-default/90 backdrop-blur">
        <UContainer class="flex h-12 items-center justify-between gap-3 sm:gap-4">
          <NuxtLink
            :to="headerBrandTo"
            class="flex min-w-0 items-center gap-2 font-semibold tracking-tight text-highlighted"
          >
            <span class="flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-primary/10 text-primary">
              <img
                v-if="headerBrandIconUrl"
                :src="headerBrandIconUrl"
                alt=""
                class="h-full w-full object-cover"
                loading="lazy"
              >
              <UIcon v-else name="i-lucide-orbit" class="size-4" />
            </span>
            <span class="truncate">{{ headerBrandTitle }}</span>
          </NuxtLink>
          <div class="flex shrink-0 items-center gap-1.5 text-sm sm:gap-2">
            <div
              v-if="showPublicLayoutToggle"
              class="inline-flex rounded-md border border-default/80 bg-elevated/30 p-0.5"
            >
              <UButton
                size="xs"
                :color="publicLayoutMode === 'showcase' ? 'primary' : 'neutral'"
                :variant="publicLayoutMode === 'showcase' ? 'solid' : 'ghost'"
                class="rounded-sm"
                @click="publicLayoutMode = 'showcase'"
              >
                <UIcon name="i-lucide-layout-template" class="size-3.5 sm:mr-1" />
                <span class="hidden sm:inline">展示</span>
              </UButton>
              <UButton
                size="xs"
                :color="publicLayoutMode === 'detailed' ? 'primary' : 'neutral'"
                :variant="publicLayoutMode === 'detailed' ? 'solid' : 'ghost'"
                class="rounded-sm"
                @click="publicLayoutMode = 'detailed'"
              >
                <UIcon name="i-lucide-book-open" class="size-3.5 sm:mr-1" />
                <span class="hidden sm:inline">阅读</span>
              </UButton>
            </div>
            <template v-if="!initialized">
              <USkeleton class="h-5 w-12 rounded" />
            </template>
            <template v-else-if="loggedIn">
              <NuxtLink
                v-if="showPublicConsoleLink"
                to="/me"
                class="inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-xs text-muted transition-colors hover:text-default"
              >
                <UIcon name="i-lucide-layout-dashboard" class="size-3.5" />
                控制台
              </NuxtLink>
              <UButton
                color="neutral"
                variant="ghost"
                size="xs"
                icon="i-lucide-log-out"
                :loading="logoutLoading"
                @click="logout"
              >
                退出
              </UButton>
            </template>
            <template v-else-if="showPublicLogin">
              <NuxtLink to="/login" class="rounded-md px-2 py-1 text-xs text-muted transition-colors hover:text-default">
                登录
              </NuxtLink>
              <NuxtLink
                v-if="showPublicRegister"
                to="/register"
                class="rounded-md border border-default/80 px-2 py-1 text-xs text-muted transition-colors hover:text-default"
              >
                注册
              </NuxtLink>
            </template>
          </div>
        </UContainer>
      </header>
      <main>
        <slot />
      </main>
    </div>
  </UApp>
</template>
