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

const route = useRoute()
const { loggedIn, pending, refresh } = useAuthSession()
const { siteName } = useGlobalConfig()

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

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 && publicHomeHeader.value?.title) {
    return publicHomeHeader.value.title
  }
  return siteName.value
})
const headerBrandIconUrl = computed(() =>
  profileSlug.value ? publicHomeHeader.value?.iconUrl ?? null : null,
)

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

function syncModeFromStorage() {
  if (!import.meta.client) {
    return
  }
  if (!showPublicLayoutToggle.value || !profileSlug.value) {
    return
  }
  const raw = localStorage.getItem(publicHomeLayoutStorageKey(profileSlug.value))
  publicLayoutMode.value = raw === 'detailed' || raw === 'showcase' ? raw : 'showcase'
}

onMounted(() => {
  refresh().catch(() => {})
  syncModeFromStorage()
})

watch([profileSlug, showPublicLayoutToggle], syncModeFromStorage)

watch(publicLayoutMode, (m) => {
  if (!import.meta.client) {
    return
  }
  if (!showPublicLayoutToggle.value || !profileSlug.value) {
    return
  }
  localStorage.setItem(publicHomeLayoutStorageKey(profileSlug.value), m)
})
</script>

<template>
  <UApp>
    <div class="min-h-screen bg-default text-default">
      <header class="sticky top-0 z-40 border-b border-default/80 bg-default/95 backdrop-blur">
        <UContainer class="flex h-14 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-2 text-sm sm:gap-3">
            <NuxtLink to="/" class="text-muted hover:text-default whitespace-nowrap">
              站点首页
            </NuxtLink>
            <div
              v-if="showPublicLayoutToggle"
              class="inline-flex rounded-lg border border-default bg-elevated/40 p-0.5 shadow-sm"
            >
              <UButton
                size="xs"
                :color="publicLayoutMode === 'showcase' ? 'primary' : 'neutral'"
                :variant="publicLayoutMode === 'showcase' ? 'solid' : 'ghost'"
                class="rounded-md"
                @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-md"
                @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="pending && !loggedIn">
              <USkeleton class="h-5 w-12 rounded" />
            </template>
            <NuxtLink
              v-else-if="loggedIn"
              to="/me"
              class="text-muted hover:text-default whitespace-nowrap"
            >
              控制台
            </NuxtLink>
            <NuxtLink
              v-else
              to="/login"
              class="text-muted hover:text-default whitespace-nowrap"
            >
              登录
            </NuxtLink>
          </div>
        </UContainer>
      </header>
      <main>
        <slot />
      </main>
    </div>
  </UApp>
</template>
