<script setup lang="ts">
/**
 * 作品列表：单列大图卡片，展示简介摘要、技术栈与外链入口。
 */
import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import AppNavbar from '@/components/layout/AppNavbar.vue'
import AppPageShell from '@/components/layout/AppPageShell.vue'
import ContentPageHeader from '../../components/ContentPageHeader.vue'
import { getWorks, type Work } from '@/api'
import { resolveMediaUrl } from '@/utils/request'
import { flattenTechStack, openExternalUrl, parseWorkLinks, stripHtml } from '@/utils/content'

const loading = ref(false)
const list = ref<Work[]>([])

async function load() {
  loading.value = true
  try {
    list.value = await getWorks() || []
  }
  catch (e: unknown) {
    uni.showToast({ title: e instanceof Error ? e.message : '加载失败', icon: 'none' })
  }
  finally {
    loading.value = false
  }
}

onShow(load)

const open = (id: string) => uni.navigateTo({ url: `/subPackages/content/pages/works/detail?id=${id}` })

const workDesc = (w: Work) => stripHtml(String(w.desc || w.description || ''))
const workTech = (w: Work) => flattenTechStack(w.techStack).slice(0, 6)
const workLinks = (w: Work) => parseWorkLinks(w.links)
const meta = (w: Work) => [w.year, w.category].filter(Boolean).join(' · ')

/** 阻止冒泡打开外链，避免同时进入详情 */
const stopOpen = (url?: string) => {
  openExternalUrl(url)
}
</script>

<template>
  <AppPageShell>
    <AppNavbar title="作品" show-back />
    <view class="page-pad">
      <ContentPageHeader
        eyebrow="Works"
        title="精选作品"
        desc="这里展示了参与设计和开发的核心项目。"
      />

      <view
        v-for="item in list"
        :key="item.id"
        class="art-card art-card-press work-card animate-reveal"
        @click="open(item.id)"
      >
        <view class="thumb-wrap">
          <image
            v-if="item.heroImg"
            class="thumb"
            :src="resolveMediaUrl(String(item.heroImg))"
            mode="aspectFill"
          />
          <view v-else class="thumb thumb--empty" />
          <view class="thumb-wash" />
        </view>
        <view class="body">
          <text v-if="meta(item)" class="font-mono-label text-art-accent">{{ meta(item) }}</text>
          <text class="title">{{ item.title }}</text>
          <text v-if="workDesc(item)" class="desc text-art-muted">{{ workDesc(item) }}</text>
          <view v-if="workTech(item).length" class="pills">
            <text v-for="(t, i) in workTech(item)" :key="i" class="pill">{{ t }}</text>
          </view>
          <view v-if="workLinks(item).live || workLinks(item).demo || workLinks(item).github" class="links">
            <view
              v-if="workLinks(item).live"
              class="link-chip"
              @click.stop="stopOpen(workLinks(item).live)"
            >
              线上
            </view>
            <view
              v-if="workLinks(item).demo"
              class="link-chip"
              @click.stop="stopOpen(workLinks(item).demo)"
            >
              演示
            </view>
            <view
              v-if="workLinks(item).github"
              class="link-chip"
              @click.stop="stopOpen(workLinks(item).github)"
            >
              源码
            </view>
          </view>
          <text class="cta text-art-accent">查看项目详情 →</text>
        </view>
      </view>

      <wd-loading v-if="loading" />
      <wd-empty v-if="!loading && !list.length" description="暂无作品" />
    </view>
  </AppPageShell>
</template>

<style scoped lang="scss">
.page-pad { padding: 24rpx 32rpx 80rpx; }
.work-card {
  margin-bottom: 40rpx;
  overflow: hidden;
}
.thumb-wrap { position: relative; }
.thumb { width: 100%; height: 360rpx; display: block; }
.thumb--empty { height: 360rpx; background: rgba(212, 179, 131, 0.12); }
.thumb-wash {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 40%, rgba(0, 0, 0, 0.35) 100%);
  pointer-events: none;
}
.body {
  padding: 28rpx 28rpx 32rpx;
  display: flex;
  flex-direction: column;
  gap: 14rpx;
}
.title {
  font-size: 40rpx;
  color: rgb(var(--art-text));
  font-family: 'Playfair Display', serif;
  font-style: italic;
  line-height: 1.3;
}
.desc {
  font-size: 26rpx;
  line-height: 1.65;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pills { display: flex; flex-wrap: wrap; gap: 12rpx; }
.pill {
  padding: 8rpx 16rpx;
  border: 1px solid var(--art-card-border);
  border-radius: 999rpx;
  font-size: 22rpx;
  color: rgb(var(--art-muted));
}
.links { display: flex; flex-wrap: wrap; gap: 12rpx; }
.link-chip {
  padding: 10rpx 20rpx;
  border: 1px solid var(--art-card-border);
  border-radius: 999rpx;
  font-size: 22rpx;
  color: rgb(var(--art-text));
}
.cta { font-size: 24rpx; margin-top: 4rpx; }
</style>
