<script setup lang="ts">
type PublicPostListItem = {
  title?: string | null
  excerpt?: string | null
  slug?: string | null
  publishedAt?: Date | string | null
  tags?: string[]
}

type PublicTimelineItem = {
  id?: number
  title?: string | null
  occurredOn?: Date | string | null
  bodyMarkdown?: string | null
}

type PublicRssListItem = {
  title?: string | null
  canonicalUrl?: string | null
  canonical_url?: string | null
}

type NormalizedModule<T> = {
  items: T[]
  total: number
}

type SocialLink = {
  label: string
  icon?: string
  safeHref: string
}

const props = defineProps<{
  slug: string
  displayName: string
  publicSlug: string | null
  avatar: string | null
  bioPreviewText: string
  hasBioPreview: boolean
  socialLinks: SocialLink[]
  postsModule: NormalizedModule<PublicPostListItem>
  timelineModule: NormalizedModule<PublicTimelineItem>
  readingModule: NormalizedModule<PublicRssListItem>
}>()

function postTitle(it: PublicPostListItem): string {
  const t = it.title
  return typeof t === 'string' && t.trim().length ? t : '未命名文章'
}

function postExcerpt(it: PublicPostListItem): string {
  return typeof it.excerpt === 'string' ? it.excerpt : ''
}

function postSlug(it: PublicPostListItem): string {
  return typeof it.slug === 'string' ? it.slug : ''
}

function timelineTitle(it: PublicTimelineItem): string {
  const t = it.title
  return typeof t === 'string' && t.trim().length ? t : '未命名动态'
}

function timelineBody(it: PublicTimelineItem): string {
  return typeof it.bodyMarkdown === 'string' ? it.bodyMarkdown : ''
}

function timelineKey(it: PublicTimelineItem, index: number): string | number {
  return it.id ?? index
}

function rssHref(it: PublicRssListItem): string | undefined {
  return it.canonicalUrl ?? it.canonical_url ?? undefined
}

function rssTitle(it: PublicRssListItem): string {
  const t = it.title
  return typeof t === 'string' && t.trim().length ? t : '未命名'
}

function rssHostname(href: string | undefined): string {
  if (!href) {
    return ''
  }
  try {
    return new URL(href).hostname
  }
  catch {
    return href
  }
}

const hasModuleContent = computed(() =>
  props.postsModule.total > 0 || props.timelineModule.total > 0 || props.readingModule.total > 0,
)
</script>

<template>
  <div class="mx-auto flex w-full max-w-xl flex-col gap-10 sm:gap-12">
    <section
      class="w-full rounded-2xl border border-default/80 bg-elevated/25 px-6 py-8 text-center shadow-sm ring-1 ring-black/5 dark:ring-white/10 sm:px-10 sm:py-9"
      aria-label="个人资料"
    >
      <div class="flex flex-col items-center gap-4">
        <div v-if="avatar" class="flex justify-center">
          <img
            :src="avatar"
            alt=""
            class="h-24 w-24 rounded-full border-2 border-default object-cover shadow-md ring-4 ring-primary/10"
          >
        </div>
        <div class="space-y-1">
          <h1 class="text-balance text-2xl font-semibold tracking-tight text-highlighted sm:text-3xl">
            {{ displayName }}
          </h1>
          <p
            v-if="publicSlug"
            class="text-sm font-medium tabular-nums text-muted"
          >
            @{{ publicSlug }}
          </p>
        </div>
        <ul
          v-if="socialLinks.length"
          class="flex flex-wrap items-center justify-center gap-2.5"
          aria-label="社交链接"
        >
          <li v-for="(l, i) in socialLinks" :key="i">
            <a
              :href="l.safeHref"
              target="_blank"
              rel="noopener noreferrer"
              :title="l.label"
              :aria-label="`${l.label}（新窗口打开）`"
              class="flex size-10 items-center justify-center rounded-full border border-default/80 bg-default/40 text-primary transition-colors hover:border-primary/35 hover:bg-elevated focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
            >
              <UIcon
                :name="socialLinkIconName({ ...l, url: l.safeHref })"
                class="size-5 shrink-0 opacity-90"
              />
            </a>
          </li>
        </ul>
      </div>
    </section>

    <section
      v-if="hasBioPreview"
      class="w-full"
    >
      <NuxtLink
        :to="`/@${slug}/about`"
        class="block rounded-2xl border border-default/70 bg-elevated/20 p-5 transition-colors hover:border-primary/25 hover:bg-elevated/35 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary sm:p-6"
      >
        <p class="text-sm leading-relaxed text-toned sm:text-base">
          {{ bioPreviewText }}
        </p>
        <p class="mt-3 text-xs font-medium text-primary">
          查看完整介绍
        </p>
      </NuxtLink>
    </section>

    <template v-if="hasModuleContent">
      <PublicHubModuleCard
        title="文章"
        :total="postsModule.total"
        description="最近发布的文章摘要，进入后可查看完整内容。"
        :to="`/@${slug}/posts`"
      >
        <template #preview>
          <NuxtLink
            v-for="(p, i) in postsModule.items.slice(0, 2)"
            :key="`${postSlug(p)}-${i}`"
            :to="`/@${slug}/posts/${encodeURIComponent(postSlug(p))}`"
            class="block rounded-lg border border-default/80 bg-default/30 px-3 py-2 transition-colors hover:bg-elevated/40"
          >
            <div class="text-sm font-medium text-highlighted">
              {{ postTitle(p) }}
            </div>
            <time
              v-if="p.publishedAt"
              class="mt-1 block text-xs tabular-nums text-muted"
              :datetime="occurredOnToIsoAttr(p.publishedAt)"
            >{{ formatPublishedDateOnly(p.publishedAt) }}</time>
            <PostTagsPostTagBadges v-if="p.tags?.length" :tags="p.tags" :max="3" class="mt-1.5" />
            <p v-if="postExcerpt(p)" class="mt-1 line-clamp-2 text-xs text-muted">
              {{ postExcerpt(p) }}
            </p>
          </NuxtLink>
        </template>
      </PublicHubModuleCard>

      <PublicHubModuleCard
        title="时光机"
        :total="timelineModule.total"
        description="近期动态与节点，仅展示入口预览。"
        :to="`/@${slug}/timeline`"
      >
        <template #preview>
          <div
            v-for="(e, i) in timelineModule.items.slice(0, 2)"
            :key="timelineKey(e, i)"
            class="rounded-lg border border-default/80 bg-default/30 px-3 py-2"
          >
            <div class="text-sm font-medium text-highlighted">
              {{ timelineTitle(e) }}
            </div>
            <time
              v-if="e.occurredOn"
              class="mt-1 block text-xs tabular-nums text-muted"
              :datetime="occurredOnToIsoAttr(e.occurredOn)"
            >{{ formatOccurredOnDisplay(e.occurredOn) }}</time>
            <p v-if="timelineBody(e)" class="mt-1 line-clamp-2 text-xs text-muted">
              {{ timelineBody(e) }}
            </p>
          </div>
        </template>
      </PublicHubModuleCard>

      <PublicHubModuleCard
        title="阅读"
        :total="readingModule.total"
        description="最近收藏/阅读条目，进入阅读页获取完整列表。"
        :to="`/@${slug}/reading`"
      >
        <template #preview>
          <template v-for="(item, i) in readingModule.items.slice(0, 2)" :key="i">
            <a
              v-if="rssHref(item)"
              :href="rssHref(item)"
              target="_blank"
              rel="noopener noreferrer"
              class="block rounded-lg border border-default/80 bg-default/30 px-3 py-2 transition-colors hover:bg-elevated/40"
            >
              <div class="text-sm font-medium text-highlighted">
                {{ rssTitle(item) }}
              </div>
              <div class="mt-1 text-xs text-muted">
                {{ rssHostname(rssHref(item)) }}
              </div>
            </a>
            <div
              v-else
              class="rounded-lg border border-default/80 bg-default/30 px-3 py-2"
            >
              <div class="text-sm font-medium text-highlighted">
                {{ rssTitle(item) }}
              </div>
            </div>
          </template>
        </template>
      </PublicHubModuleCard>
    </template>
    <UEmpty
      v-else
      title="这里还没有公开内容"
      description="站主尚未发布任何公开文章或动态。"
    />
  </div>
</template>
