<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { api, generatedUrl } from '../api'
import { site } from '../site'
import { isAuthed, openLogin } from '../auth'
import Icon from '../components/Icon.vue'

const router = useRouter()

// Navigate to a signed-in page, or pop the login modal (remembering the
// destination) when the visitor isn't logged in yet.
function go(path, query) {
  const target = query ? { path, query } : { path }
  if (isAuthed()) { router.push(target); return }
  openLogin(typeof target === 'string' ? target : router.resolve(target).fullPath)
}

const stats = ref({ generated_count: 0, recent: [] })
const managed = ref([])     // managed model records (provider, type, ...)
const showcase = ref({ hero: [], bento: [] })
// heroDeck holds the top-3 hero cards in a RANDOMIZED order, so a different card
// fronts the deck on each page load. It's reshuffled only when the hero set first
// loads or its members change — not on every 30s poll, so the deck stays put.
const heroDeck = ref([])
function shuffleArr(arr) {
  const a = [...arr]
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1))
    ;[a[i], a[j]] = [a[j], a[i]]
  }
  return a
}
let timer = null

async function refresh() {
  try {
    // No /logs here — that endpoint now requires a login and only returns the
    // caller's own entries. The avg-latency KPI comes from /stats (aggregate,
    // prompt-free) so the public home page exposes nothing per-user.
    const [s, m, sc] = await Promise.all([
      api('/stats'),
      api('/managed-models'),
      api('/showcase'),
    ])
    stats.value = s.data || { generated_count: 0, recent: [] }
    managed.value = (m.data?.data || []).filter((x) => x.enabled !== false)
    showcase.value = sc.data?.data || { hero: [], bento: [] }
    // Randomize which hero card fronts the deck: shuffle the top-3 once when the
    // set first loads / changes; keep the order stable across refreshes so the
    // deck doesn't reshuffle every 30s while the visitor is looking at it.
    const top3 = (showcase.value.hero || []).slice(0, 3)
    const sameSet = heroDeck.value.length === top3.length
      && top3.every((c) => heroDeck.value.some((d) => d.id === c.id))
    if (!sameSet) heroDeck.value = shuffleArr(top3)
  } catch {}
}
onMounted(() => { refresh(); timer = setInterval(refresh, 30000) })
onUnmounted(() => clearInterval(timer))

// ---- KPI strip — three signals derived from real data ----
const modelCount = computed(() => managed.value.length)

// Show the 24h average (matches the admin overview); fall back to the all-time
// average on a quiet day so the KPI isn't blank.
const avgElapsed = computed(() => stats.value?.avg_elapsed_ms_24h ?? stats.value?.avg_elapsed_ms ?? null)
const avgLabel = computed(() => {
  if (avgElapsed.value == null) return '—'
  if (avgElapsed.value < 1000) return avgElapsed.value + 'ms'
  return (avgElapsed.value / 1000).toFixed(1) + 's'
})

// ---- “已接入” provider strip, derived from managed models ----
const PROVIDER_TINT = {
  adobe:   'from-rose-400 to-orange-400',
  chatgpt: 'from-violet-500 to-fuchsia-500',
  google:  'from-sky-400 to-indigo-500',
  default: 'from-emerald-400 to-teal-500',
}
const providerGroups = computed(() => {
  const map = new Map()
  for (const m of managed.value) {
    const key = (m.provider || 'unknown').toLowerCase()
    const g = map.get(key) || { name: m.provider || 'unknown', image: 0, video: 0 }
    if (m.type === 'video') g.video++
    else g.image++
    map.set(key, g)
  }
  return [...map.entries()].map(([key, g]) => ({
    ...g,
    grad: PROVIDER_TINT[key] || PROVIDER_TINT.default,
  })).sort((a, b) => (b.image + b.video) - (a.image + a.video))
})

// Admin-curated "我们的作品" entries from /admin/api/showcase (kind=work),
// already sorted by weight on the server.
const works = computed(() => showcase.value.work || [])

// Hero deck = a random ordering of the top-3 hero entries (see refresh).
const bento = computed(() => showcase.value.bento || [])

// Resolve an image reference: external URLs pass through, relative paths
// (like "user/abc.png") are served from /generated by the backend.
function imgSrc(image) {
  if (!image) return ''
  return /^https?:\/\//i.test(image) ? image : generatedUrl(image)
}
// Background style for a showcase card. Prefers a real image (the new shape);
// falls back to the legacy CSS gradient so seed entries still render.
function cardBg(card) {
  if (card.image) {
    return {
      backgroundImage: `url("${imgSrc(card.image)}")`,
      backgroundSize: 'cover',
      backgroundPosition: 'center',
    }
  }
  return { background: card.gradient }
}

function useExample(ex) {
  go('/user', { prompt: ex.prompt })
}
</script>

<template>
  <div class="space-y-28">
    <!-- ============ HERO ============ -->
    <section class="relative pt-8 md:pt-16 grid lg:grid-cols-[1.15fr_1fr] gap-10 lg:gap-16 items-center min-h-[640px]">
      <!-- LEFT: copy -->
      <div>
        <h1 class="font-bold tracking-tight leading-[0.9] text-[clamp(2.5rem,6.5vw,6.5rem)] text-[color:var(--fg)]">
          <span class="block text-[color:var(--fg-3)] font-light italic">Imagine</span>
          <span class="block">it,
            <span class="bg-gradient-to-r from-fuchsia-300 via-violet-300 to-sky-300 bg-clip-text text-transparent italic">type</span>
            it,
          </span>
          <span class="block">own it.</span>
        </h1>

        <p class="mt-8 text-base md:text-lg text-[color:var(--fg-2)] max-w-md leading-relaxed">
          {{ site.subtitle || '把脑海里的画面写成一句话,GPT、Gemini、Firefly、Flux 等顶级模型替你变成图像与视频。' }}
        </p>

        <div class="mt-10 flex items-center gap-4">
          <button @click="go('/user')"
                  class="group inline-flex items-center gap-3 rounded-full bg-[var(--btn-solid-bg)] text-[color:var(--btn-solid-fg)] hover:bg-[var(--btn-solid-bg-h)] pl-6 pr-3 py-3 text-sm font-semibold transition-all">
            开始画图
            <span class="w-8 h-8 rounded-full bg-[var(--btn-solid-fg)] text-[color:var(--btn-solid-bg)] grid place-items-center group-hover:translate-x-1 transition-transform">
              →
            </span>
          </button>
          <a href="#bento" class="text-sm text-[color:var(--fg-3)] hover:text-[color:var(--fg)] transition-colors">浏览灵感 ↓</a>
        </div>

        <!-- counter strip — three real signals: models we support, total
             outputs ever generated, average wall-clock to produce one. -->
        <div class="mt-14 grid grid-cols-3 gap-px rounded-2xl overflow-hidden ring-1 ring-[color:var(--hairline)] max-w-xl" style="background: var(--hairline)">
          <div class="bg-[var(--surface)] px-5 py-4">
            <div class="text-2xl md:text-3xl font-bold tabular-nums text-[color:var(--fg)]">{{ modelCount }}</div>
            <div class="text-[10px] text-[color:var(--fg-3)] mt-1 uppercase tracking-[0.2em]">已接入模型</div>
          </div>
          <div class="bg-[var(--surface)] px-5 py-4">
            <div class="text-2xl md:text-3xl font-bold tabular-nums text-[color:var(--fg)]">{{ stats.generated_count || 0 }}</div>
            <div class="text-[10px] text-[color:var(--fg-3)] mt-1 uppercase tracking-[0.2em]">已生成作品</div>
          </div>
          <div class="bg-[var(--surface)] px-5 py-4">
            <div class="text-2xl md:text-3xl font-bold tabular-nums text-[color:var(--fg)]">{{ avgLabel }}</div>
            <div class="text-[10px] text-[color:var(--fg-3)] mt-1 uppercase tracking-[0.2em]">平均出片</div>
          </div>
        </div>
      </div>

      <!-- RIGHT: stacked card deck — driven by /admin/api/showcase (kind=hero),
           top 3 by weight. Position classes are picked by index so existing CSS
           transforms in <style> still apply. -->
      <div class="relative h-[480px] lg:h-[560px] hero-deck">
        <template v-for="(card, i) in heroDeck" :key="card.id">
          <!-- back -->
          <div v-if="i === 2"
               class="deck-card deck-card-3 absolute inset-y-8 right-12 lg:right-20 w-[68%] rounded-3xl overflow-hidden ring-1 ring-white/10 shadow-2xl"
               :style="cardBg(card)">
            <div class="absolute inset-0 mix-blend-overlay opacity-25"
                 style="background-image:url('data:image/svg+xml;utf8,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22120%22 height=%22120%22><filter id=%22n%22><feTurbulence baseFrequency=%220.85%22 numOctaves=%222%22 seed=%222%22/></filter><rect width=%22100%25%22 height=%22100%25%22 filter=%22url(%23n)%22 opacity=%220.5%22/></svg>')"></div>
            <div class="absolute inset-x-0 bottom-0 p-5 bg-gradient-to-t from-black/85 via-black/30 to-transparent">
              <div class="text-[10px] uppercase tracking-[0.3em] text-white/55">{{ card.subtitle }}</div>
              <div class="text-lg font-semibold text-white mt-1">{{ card.title }}</div>
            </div>
          </div>

          <!-- middle -->
          <div v-if="i === 1"
               class="deck-card deck-card-2 absolute inset-y-4 right-4 lg:right-8 w-[72%] rounded-3xl overflow-hidden ring-1 ring-white/10 shadow-2xl"
               :style="cardBg(card)">
            <div class="absolute inset-0 mix-blend-overlay opacity-25"
                 style="background-image:url('data:image/svg+xml;utf8,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22120%22 height=%22120%22><filter id=%22n%22><feTurbulence baseFrequency=%220.85%22 numOctaves=%222%22 seed=%223%22/></filter><rect width=%22100%25%22 height=%22100%25%22 filter=%22url(%23n)%22 opacity=%220.5%22/></svg>')"></div>
            <div class="absolute inset-x-0 bottom-0 p-5 bg-gradient-to-t from-black/85 via-black/30 to-transparent">
              <div class="text-[10px] uppercase tracking-[0.3em] text-white/55">{{ card.subtitle }}</div>
              <div class="text-lg font-semibold text-white mt-1">{{ card.title }}</div>
            </div>
          </div>

          <!-- front -->
          <div v-if="i === 0"
               class="deck-card deck-card-1 absolute inset-y-0 right-0 w-[78%] rounded-3xl overflow-hidden ring-1 ring-white/15 shadow-[0_30px_80px_-20px_rgba(168,85,247,0.45)]"
               :style="cardBg(card)">
            <div class="absolute inset-0 mix-blend-overlay opacity-30"
                 style="background-image:url('data:image/svg+xml;utf8,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22120%22 height=%22120%22><filter id=%22n%22><feTurbulence baseFrequency=%220.85%22 numOctaves=%222%22 seed=%221%22/></filter><rect width=%22100%25%22 height=%22100%25%22 filter=%22url(%23n)%22 opacity=%220.5%22/></svg>')"></div>
            <div class="absolute top-0 inset-x-0 flex items-center justify-between px-5 py-4">
              <div class="flex items-center gap-1.5">
                <span class="w-2.5 h-2.5 rounded-full bg-white/20"></span>
                <span class="w-2.5 h-2.5 rounded-full bg-white/20"></span>
                <span class="w-2.5 h-2.5 rounded-full bg-white/20"></span>
              </div>
              <div class="text-[10px] uppercase tracking-[0.25em] text-white/60 font-mono">live</div>
            </div>
            <div class="absolute inset-x-0 bottom-0 p-6 bg-gradient-to-t from-black/90 via-black/40 to-transparent">
              <div class="text-[10px] uppercase tracking-[0.3em] text-white/65">{{ card.subtitle }}</div>
              <div class="text-2xl font-bold text-white mt-2">{{ card.title }}</div>
              <p class="text-xs text-white/70 mt-2 line-clamp-2 leading-relaxed">{{ card.prompt }}</p>
            </div>
          </div>
        </template>
      </div>
    </section>

    <!-- ============ WORKS STRIP ============ -->
    <section v-if="works.length" class="-mx-8 md:-mx-14">
      <div class="px-8 md:px-14 mb-6">
        <h2 class="text-3xl md:text-4xl font-bold tracking-tight text-[color:var(--fg)]">我们的作品</h2>
      </div>
      <div class="marquee-wrap">
        <div class="marquee-track">
          <div v-for="(w, i) in [...works, ...works]" :key="w.id + '-' + i"
               class="shrink-0 w-56 h-56 rounded-2xl overflow-hidden ring-1 ring-white/[0.08] hover:ring-white/30 hover:scale-[1.02] transition-all cursor-pointer relative"
               @click="go('/logs')">
            <img :src="imgSrc(w.image)" loading="lazy"
                 class="w-full h-full object-cover" />
            <div v-if="w.title" class="absolute inset-x-0 bottom-0 p-3 bg-gradient-to-t from-black/85 via-black/30 to-transparent">
              <div class="text-xs font-medium text-white line-clamp-1">{{ w.title }}</div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- ============ BENTO EXAMPLES ============ -->
    <section id="bento">
      <div class="flex items-end justify-between flex-wrap gap-3 mb-8">
        <div>
          <div class="text-[10px] uppercase tracking-[0.3em] text-violet-300/70 font-medium">灵感</div>
          <h2 class="mt-2 text-3xl md:text-4xl font-bold tracking-tight text-[color:var(--fg)]">从一个起点开始</h2>
          <p class="text-[color:var(--fg-3)] mt-2 max-w-md">点任意一张,自动进入画图工作台并预填提示词。</p>
        </div>
      </div>

      <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 grid-flow-row-dense gap-4 auto-rows-[200px]">
        <button v-for="ex in bento" :key="ex.id" @click="useExample(ex)"
                class="group relative text-left overflow-hidden rounded-3xl ring-1 ring-white/[0.06] hover:ring-white/20 transition-all"
                :class="ex.span"
                :style="cardBg(ex)">
          <!-- grain -->
          <div class="absolute inset-0 mix-blend-overlay opacity-30"
               style="background-image: url('data:image/svg+xml;utf8,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22120%22 height=%22120%22><filter id=%22n%22><feTurbulence baseFrequency=%220.85%22 numOctaves=%222%22 seed=%221%22/></filter><rect width=%22100%25%22 height=%22100%25%22 filter=%22url(%23n)%22 opacity=%220.5%22/></svg>')"></div>
          <!-- veil -->
          <div class="absolute inset-0 bg-gradient-to-t from-black/85 via-black/30 to-transparent"></div>

          <div class="absolute top-5 right-5 w-9 h-9 rounded-xl bg-white/15 backdrop-blur ring-1 ring-white/20 grid place-items-center opacity-0 group-hover:opacity-100 group-hover:scale-100 scale-95 transition-all">
            <Icon name="open" class="w-3.5 h-3.5" />
          </div>

          <div class="absolute inset-x-0 bottom-0 p-5 md:p-6">
            <div class="text-[10px] uppercase tracking-[0.3em] text-white/55">{{ ex.subtitle }}</div>
            <div class="text-xl md:text-2xl font-bold mt-2 text-white">{{ ex.title }}</div>
            <div class="text-xs text-white/65 mt-2 line-clamp-2 leading-relaxed">{{ ex.prompt }}</div>
          </div>
        </button>
      </div>
    </section>

    <!-- ============ MODELS GRID ============ -->
    <section>
      <div class="flex items-end justify-between flex-wrap gap-3 mb-8">
        <div>
          <div class="text-[10px] uppercase tracking-[0.3em] text-sky-300/70 font-medium">模型</div>
          <h2 class="mt-2 text-3xl md:text-4xl font-bold tracking-tight text-[color:var(--fg)]">已接入</h2>
          <p class="text-[color:var(--fg-3)] mt-2 max-w-md">由管理员在后台注册;以下为已对接的上游 family。</p>
        </div>
      </div>

      <div class="grid sm:grid-cols-2 md:grid-cols-3 gap-3">
        <div v-for="p in providerGroups" :key="p.name"
             class="group relative overflow-hidden rounded-2xl bg-[var(--surface)] ring-1 ring-[color:var(--hairline)] p-5 hover:ring-[color:var(--fg-faint)] transition-all">
          <div class="absolute -right-8 -top-8 w-32 h-32 rounded-full bg-gradient-to-br opacity-30 blur-xl group-hover:opacity-50 transition-opacity"
               :class="p.grad"></div>
          <div class="relative flex items-center justify-between">
            <div>
              <div class="text-base font-semibold capitalize text-[color:var(--fg)]">{{ p.name }}</div>
              <div class="text-[10px] uppercase tracking-[0.25em] text-[color:var(--fg-3)] mt-1 flex gap-2">
                <span v-if="p.image">{{ p.image }} 图像</span>
                <span v-if="p.video">{{ p.video }} 视频</span>
              </div>
            </div>
            <span class="w-2.5 h-2.5 rounded-full bg-gradient-to-br" :class="p.grad"></span>
          </div>
        </div>
        <div v-if="!providerGroups.length" class="text-sm text-[color:var(--fg-3)] col-span-full text-center py-10">
          管理员尚未接入任何模型
        </div>
      </div>
    </section>

    <!-- ============ FOOTER CTA ============ -->
    <section class="cta-band relative overflow-hidden rounded-[2rem] ring-1 ring-[color:var(--hairline)] p-12 md:p-20">
      <div class="relative max-w-2xl">
        <h3 class="text-4xl md:text-6xl font-bold tracking-tight leading-[1.05] text-[color:var(--fg)]">
          停下来思考,<br />
          <span class="italic font-light text-[color:var(--fg-3)]">不如</span> 直接开始。
        </h3>
        <p class="text-base md:text-lg text-[color:var(--fg-2)] mt-6 max-w-lg leading-relaxed">
          登录即可开始。打开画图工作台,写一句话,看 AI 替你完成。
        </p>
        <button @click="go('/user')"
                class="mt-10 group inline-flex items-center gap-3 rounded-full bg-[var(--btn-solid-bg)] text-[color:var(--btn-solid-fg)] hover:bg-[var(--btn-solid-bg-h)] pl-6 pr-3 py-3 text-sm font-semibold transition-all">
          开始画图
          <span class="w-8 h-8 rounded-full bg-[var(--btn-solid-fg)] text-[color:var(--btn-solid-bg)] grid place-items-center group-hover:translate-x-1 transition-transform">
            →
          </span>
        </button>
      </div>
    </section>

    <!-- thin footer line -->
    <footer class="pt-12 border-t border-[color:var(--hairline)] flex flex-wrap items-center justify-between gap-4 text-xs text-[color:var(--fg-3)]">
      <div class="flex items-center gap-3">
        <span class="font-mono">{{ site.title }}</span>
        <span>·</span>
        <span>AI 生图与生视频平台</span>
      </div>
    </footer>
  </div>
</template>

<style scoped>
.line-clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ----- Hero stacked card deck ----- */
.hero-deck { perspective: 1200px; }
.deck-card { transform-origin: center bottom; will-change: transform, opacity; }
/* staggered fade-in-up on load, then a livelier continuous float with a gentle
   rotation wobble. The :hover rules below still take over to fan the deck out. */
.deck-card-1 { animation: deckIn1 0.8s cubic-bezier(0.2,0.7,0.2,1) backwards, deckFloat1 7s ease-in-out 0.8s infinite; }
.deck-card-2 { animation: deckIn2 0.8s cubic-bezier(0.2,0.7,0.2,1) 0.12s backwards, deckFloat2 9s ease-in-out 0.92s infinite; }
.deck-card-3 { animation: deckIn3 0.8s cubic-bezier(0.2,0.7,0.2,1) 0.24s backwards, deckFloat3 11s ease-in-out 1.04s infinite; opacity: 0.85; }
@keyframes deckFloat1 {
  0%,100% { transform: rotate(2deg) translateY(0); }
  35%     { transform: rotate(0.5deg) translateY(-16px); }
  70%     { transform: rotate(3deg) translateY(-7px); }
}
@keyframes deckFloat2 {
  0%,100% { transform: rotate(-3deg) translateY(0); }
  50%     { transform: rotate(-1.5deg) translateY(-13px); }
}
@keyframes deckFloat3 {
  0%,100% { transform: rotate(5deg) translateY(0); }
  50%     { transform: rotate(3.5deg) translateY(-10px); }
}
@keyframes deckIn1 {
  from { opacity: 0; transform: rotate(2deg) translateY(48px) scale(0.92); }
  to   { opacity: 1; transform: rotate(2deg) translateY(0) scale(1); }
}
@keyframes deckIn2 {
  from { opacity: 0; transform: rotate(-3deg) translateY(48px) scale(0.92); }
  to   { opacity: 1; transform: rotate(-3deg) translateY(0) scale(1); }
}
@keyframes deckIn3 {
  from { opacity: 0; transform: rotate(5deg) translateY(48px) scale(0.92); }
  to   { opacity: 0.85; transform: rotate(5deg) translateY(0) scale(1); }
}
.hero-deck:hover .deck-card-1 { transform: rotate(0deg) translateY(-12px); transition: transform 0.4s ease; animation: none; }
.hero-deck:hover .deck-card-2 { transform: rotate(-6deg) translate(-30px, 10px); transition: transform 0.4s ease; animation: none; }
.hero-deck:hover .deck-card-3 { transform: rotate(8deg) translate(-50px, 20px); transition: transform 0.4s ease; animation: none; opacity: 0.7; }

.marquee-wrap {
  position: relative;
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent 0%, #000 6%, #000 94%, transparent 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 6%, #000 94%, transparent 100%);
}
.marquee-track {
  display: flex;
  gap: 1rem;
  width: max-content;
  padding: 0 2rem;
  animation: marquee 55s linear infinite;
}
.marquee-wrap:hover .marquee-track { animation-play-state: paused; }
@keyframes marquee {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}
</style>
