// 网站统一数据层
// 从后端公开只读接口 (/api/public/...) 拉取真实数据，并适配为前端各模块
// (site / shows / trends / colors / street，以及首页 backstage 面板、文章画廊 reports) 所需结构。
//
// 设计原则：
//  1. 单一数据源：所有 getter 共享一次分页拉取 (loadArticles)，避免重复请求。
//  2. 优雅回落：后端不可达或返回空时，回落到内置示例，保证 SSG 构建与离线预览不报错。
//  3. 颜色模块：后端暂无独立颜色接口，getColors() 先尝试 /api/public/colors，
//     失败则从 runway 文章封面派生占位（接入颜色接口后即可自动生效）。

const API_BASE = ((import.meta as any).env?.PUBLIC_API_BASE ?? "").replace(/\/$/, "")

export type RawArticle = {
  id: number
  title: string
  summary?: string
  description?: string
  cover: string
  brand_name: string
  year: number
  image_count: number
  published_at: number
  source_url?: string
  collection_type?: string
  season?: string
  season_code?: string
  images?: { id: number; image: string; name?: string }[]
}

// ---------- 通用辅助 ----------
export function toAbs(url: string): string {
  if (!url) return ""
  return /^https?:\/\//i.test(url) ? url : API_BASE + url
}

export function seasonLabel(y: number | string): string {
  const n = Number(y)
  return n ? `AW${String(n).slice(2)}` : ""
}

// 系列类型 → 展示名（用于首页/列表的系列标签与筛选）
export const SERIES_LABELS: Record<string, string> = {
  rtw: "成衣 RTW",
  menswear: "男装",
  couture: "高定",
  resort: "度假",
  pre_fall: "早秋",
}
export function seriesLabel(ct?: string): string {
  return (ct && SERIES_LABELS[ct]) || "成衣 RTW"
}

export function fmtDate(t: number | string): string {
  const n = Number(t)
  const d = new Date(n < 1e12 ? n * 1000 : n)
  const p = (x: number) => String(x).padStart(2, "0")
  return `${d.getUTCFullYear()}.${p(d.getUTCMonth() + 1)}.${p(d.getUTCDate())}`
}

// ---------- 内置示例（后端不可达时回落） ----------
const BRANDS = ["MAISON LUMEN", "STUDIO VANTA", "ATELIER NOIR", "KÔ", "CÉLESTE", "RIVE GAUCHE"]
const SAMPLE: RawArticle[] = Array.from({ length: 24 }, (_, i) => ({
  id: i + 1,
  title: `Collection ${String(i + 1).padStart(2, "0")}`,
  brand_name: BRANDS[i % BRANDS.length],
  year: 2023 + (i % 4),
  cover: `https://picsum.photos/seed/s${i + 1}/800/1000`,
  image_count: 3 + (i % 12),
  published_at: Math.floor(Date.UTC(2026, 0, 1) / 1000) - i * 86400,
}))

// ---------- 底层：一次性拉取并缓存 ----------
type Loaded = {
  items: RawArticle[]
  total: number
  brandCount: number
  yearMin: number
  yearMax: number
  latest: RawArticle | null
  sampled: boolean
}
let _loaded: Promise<Loaded> | null = null

function compute(items: RawArticle[], total: number): Loaded {
  const brandCount = new Set(items.map((r) => r.brand_name).filter(Boolean)).size
  const years = items.map((r) => Number(r.year)).filter((y) => y > 0)
  const yearMin = years.length ? Math.min(...years) : 0
  const yearMax = years.length ? Math.max(...years) : 0
  const latest =
    [...items].sort((a, b) => Number(b.published_at) - Number(a.published_at))[0] || null
  return { items, total, brandCount, yearMin, yearMax, latest, sampled: false }
}

function fromSample(): Loaded {
  return { ...compute(SAMPLE, SAMPLE.length), sampled: true }
}

export function loadArticles(): Promise<Loaded> {
  if (_loaded) return _loaded
  _loaded = (async () => {
    if (!API_BASE) return fromSample()
    try {
      const res = await fetch(`${API_BASE}/api/public/articles?page=1&size=60`)
      if (!res.ok) return fromSample()
      const json: any = await res.json()
      const items: RawArticle[] = json?.data ?? []
      if (!items.length) return fromSample()
      return compute(items, Number(json?.total ?? items.length))
    } catch {
      return fromSample()
    }
  })()
  return _loaded
}

export async function fetchArticleById(id: number | string): Promise<RawArticle | null> {
  if (!API_BASE) return null
  try {
    const res = await fetch(`${API_BASE}/api/public/articles/${id}`)
    if (!res.ok) return null
    const json: any = await res.json()
    return json?.data ?? null
  } catch {
    return null
  }
}

// ---------- 模块 getter ----------
// 统一映射：四块面板共用同一真实文章结构，字段含义清晰、不再错配
// （接口仅暴露 runway 文章一类数据，四块面板取真实列表的不同区段，避免重复同一批内容）

export type ArticleCard = {
  id: number
  brand: string
  title: string
  season: string // 季节码，如 AW16
  year: number
  img: string
  count: number
  gallery: string[]
  collection_type?: string // rtw/menswear/couture/resort/pre_fall
  season_code?: string // SS26/FW25/RES26/PF25
}

function mapArticle(r: RawArticle): ArticleCard {
  return {
    id: r.id,
    brand: r.brand_name || "Unknown",
    title: r.title || "",
    season: seasonLabel(r.year),
    year: Number(r.year) || 0,
    img: toAbs(r.cover || ""),
    count: r.image_count || 0,
    gallery: [],
    collection_type: r.collection_type,
    season_code: r.season_code,
  }
}

export async function getShows(limit = 8): Promise<ArticleCard[]> {
  const items = await loadArticlesWithImages(40)
  return items.slice(0, limit)
}

export async function getBackstage(limit = 8): Promise<ArticleCard[]> {
  const items = await loadArticlesWithImages(40)
  return items.slice(8, 8 + limit)
}

export async function getTrends(limit = 9): Promise<ArticleCard[]> {
  const items = await loadArticlesWithImages(40)
  return items.slice(16, 16 + limit)
}

export async function getStreet(limit = 8): Promise<ArticleCard[]> {
  const items = await loadArticlesWithImages(40)
  return items.slice(24, 24 + limit)
}

// 列表带图拉取：一次请求即带回每篇文章前 5 张图（后端 with_images 参数），
// 用于首页卡片缩略图，避免此前逐篇详情请求导致的缓慢。
let _loadedWithImages: Promise<ArticleCard[]> | null = null
export function loadArticlesWithImages(size = 40): Promise<ArticleCard[]> {
  if (_loadedWithImages) return _loadedWithImages
  _loadedWithImages = (async () => {
    if (!API_BASE) return []
    try {
      const res = await fetch(`${API_BASE}/api/public/articles?page=1&size=${size}&with_images=5`)
      if (!res.ok) return []
      const json: any = await res.json()
      const items: RawArticle[] = json?.data ?? []
      return items.map((r: RawArticle) => {
        const base = mapArticle(r)
        base.gallery = (r.images || [])
          .map((im: any) => toAbs(im.image || ""))
          .filter(Boolean)
          .slice(0, 5)
        return base
      })
    } catch {
      return []
    }
  })()
  return _loadedWithImages
}

// attachGallery 在构建期（SSG）为每个展示文章预取其真实多图（前 3 张），
// 供首页卡片直接渲染"图片堆"，无需等到悬停才拉取。后端不可达时 gallery 为空。
async function attachGallery<T extends { id: number; gallery: string[] }>(items: T[]): Promise<T[]> {
  return await Promise.all(
    items.map(async (it) => {
      let gallery: string[] = []
      const art = await fetchArticleById(it.id)
      if (art?.images?.length) {
        gallery = art.images
          .slice(0, 5)
          .map((im: any) => toAbs(im.image || ""))
          .filter(Boolean)
      }
      return { ...it, gallery }
    })
  )
}

export type ColorItem = {
  id: number
  name: string
  brand: string
  season: string
  img: string
}
export async function getColors(limit = 12): Promise<ColorItem[]> {
  // 后端暂无独立颜色接口：优先尝试 /api/public/colors，失败则从 runway 文章封面派生占位。
  if (API_BASE) {
    try {
      const res = await fetch(`${API_BASE}/api/public/colors`)
      if (res.ok) {
        const json: any = await res.json()
        const data: any[] = json?.data ?? []
        if (data.length) {
          return data.slice(0, limit).map((c) => ({
            id: c.id ?? 0,
            name: c.name || c.title || "",
            brand: c.brand_name || "",
            season: seasonLabel(c.year),
            img: toAbs(c.cover || c.image || ""),
          }))
        }
      }
    } catch {
      /* 回落到封面派生 */
    }
  }
  const { items } = await loadArticles()
  return items.slice(0, limit).map((r) => ({
    id: r.id,
    name: r.title,
    brand: r.brand_name,
    season: seasonLabel(r.year),
    img: toAbs(r.cover || ""),
  }))
}

export type SiteInfo = {
  totalReports: number
  brandCount: number
  seasonRange: string
  latest: { title: string; brand: string; date: string; href: string }
}
export async function getSite(): Promise<SiteInfo> {
  const loaded = await loadArticles()
  // 落回到示例时，沿用与首页原本一致的示例展示值
  if (loaded.sampled) {
    return {
      totalReports: 12,
      brandCount: 6,
      seasonRange: "2023–26",
      latest: {
        title: "Paper Light",
        brand: "MAISON LUMEN",
        date: "2026.03.14",
        href: "/article?id=1",
      },
    }
  }
  const { total, brandCount, yearMin, yearMax, latest } = loaded
  const seasonRange =
    yearMin && yearMax ? `${yearMin}–${String(yearMax).slice(2)}` : "2023–26"
  return {
    totalReports: total || 12,
    brandCount: brandCount || 6,
    seasonRange,
    latest: latest
      ? {
          title: latest.title,
          brand: latest.brand_name,
          date: fmtDate(latest.published_at),
          href: `/article?id=${latest.id}`,
        }
      : { title: "Paper Light", brand: "MAISON LUMEN", date: "2026.03.14", href: "/article?id=1" },
  }
}

// ---------- 文章画廊（/articles）所需结构 ----------
export type ReportItem = {
  id: number
  brand: string
  title: string
  year: number
  cover: string
  excerpt: string
  image_count: number
  featured: boolean
  ratio: string
  created_at: number
}
const RATIOS = ["3 / 4", "4 / 5", "1 / 1", "5 / 4"]
export async function getReports(limit = 30): Promise<ReportItem[]> {
  const { items } = await loadArticles()
  return items.slice(0, limit).map((r, i) => ({
    id: r.id,
    brand: r.brand_name || "Unknown",
    title: r.title || "",
    year: Number(r.year) || 0,
    cover: toAbs(r.cover || ""),
    excerpt: (r.summary || r.description || r.title || "").slice(0, 120),
    image_count: r.image_count || 0,
    featured: i % 4 === 0,
    ratio: RATIOS[i % RATIOS.length],
    created_at: Number(r.published_at) || 0,
  }))
}
