<script setup lang="ts">
const route = useRoute()
const router = useRouter()
const { fetchData, getApiErrorMessage } = useClientApi()

function parsePage(raw: unknown): number {
  const n =
    typeof raw === 'string'
      ? Number.parseInt(raw, 10)
      : typeof raw === 'number'
        ? raw
        : Number.NaN
  if (!Number.isFinite(n) || n < 1) {
    return 1
  }
  return Math.floor(n)
}

const page = ref(parsePage(route.query.page))

watch(
  () => route.query.page,
  () => {
    page.value = parsePage(route.query.page)
  },
)

type DiscoverUser = {
  publicSlug: string
  displayName: string
  avatar: string | null
  location: string | null
}

type Payload = {
  items: DiscoverUser[]
  total: number
  page: number
  pageSize: number
}

const PAGE_SIZE = 10

const data = ref<Payload | null>(null)
const pending = ref(false)
const loadError = ref('')

async function load() {
  pending.value = true
  loadError.value = ''
  try {
    const url = page.value > 1 ? `/api/discover/users?page=${page.value}` : '/api/discover/users'
    data.value = await fetchData<Payload>(url, { notify: false })
  } catch (e: unknown) {
    data.value = null
    loadError.value = getApiErrorMessage(e)
  } finally {
    pending.value = false
  }
}

watch(page, () => {
  void load()
})

function onPageChange(p: number) {
  page.value = p
  const query: Record<string, string | string[] | undefined> = { ...route.query }
  if (p > 1) {
    query.page = String(p)
  }
  else {
    delete query.page
  }
  void router.replace({ query })
}

onMounted(() => {
  void load()
})

usePageTitle(() => (page.value > 1 ? [`第 ${page.value} 页`, '发现'] : ['发现']))
</script>

<template>
  <UContainer class="max-w-6xl py-8">
    <h1 class="mb-6 text-2xl font-semibold text-highlighted">
      发现
    </h1>

    <div v-if="pending && !data" class="text-muted">
      加载中…
    </div>
    <UAlert
      v-else-if="loadError"
      color="error"
      :title="loadError"
      class="mb-6"
    />
    <template v-else-if="data">
      <UEmpty
        v-if="data.total === 0"
        title="暂时还没有用户"
        description="尚无用户开启「出现在发现页」。可在个人资料中打开该选项并设置公开主页 slug。"
      />
      <template v-else>
        <ul class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          <li
            v-for="u in data.items"
            :key="u.publicSlug"
            class="border border-default rounded-xl bg-elevated/20 overflow-hidden transition-shadow hover:shadow-md"
          >
            <NuxtLink
              :to="`/@${encodeURIComponent(u.publicSlug)}`"
              class="flex flex-col gap-3 p-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-default rounded-xl"
            >
              <div class="flex items-center gap-3 min-w-0">
                <UAvatar
                  :src="u.avatar || undefined"
                  :alt="u.displayName"
                  size="md"
                  class="shrink-0 ring-1 ring-default"
                />
                <div class="min-w-0 flex-1">
                  <div class="font-medium text-highlighted truncate">
                    {{ u.displayName }}
                  </div>
                  <div class="text-xs text-muted truncate">
                    @{{ u.publicSlug }}
                  </div>
                </div>
              </div>
              <p v-if="u.location" class="text-sm text-muted line-clamp-2">
                {{ u.location }}
              </p>
            </NuxtLink>
          </li>
        </ul>
        <div v-if="data.total > PAGE_SIZE" class="flex justify-end mt-8">
          <UPagination
            :page="page"
            :total="data.total"
            :items-per-page="PAGE_SIZE"
            size="sm"
            @update:page="onPageChange"
          />
        </div>
      </template>
    </template>
  </UContainer>
</template>
