<script setup lang="ts">
import { ref, onMounted } from 'vue'
import SettingsPanel from './components/SettingsPanel.vue'
import ImageGenerator from './components/ImageGenerator.vue'
import Gallery from './components/Gallery.vue'
import { probeSession, listModels, getSelf, type NewApiUser, type Auth } from './lib/api'
import { loadSettings } from './lib/settings'

const user = ref<NewApiUser | null>(null)
const auth = ref<Auth>({ kind: 'session' })
const baseUrl = ref<string>(loadSettings().baseUrl)
const models = ref<string[]>([])
const error = ref<string>('')
const settingsRef = ref<InstanceType<typeof SettingsPanel> | null>(null)
const galleryRef = ref<InstanceType<typeof Gallery> | null>(null)
const checking = ref<boolean>(true)

async function refreshSession() {
  checking.value = true
  try {
    const u = await probeSession(baseUrl.value)
    user.value = u
    error.value = ''
    if (u) {
      try {
        models.value = await listModels(baseUrl.value, { kind: 'session' })
      } catch (e) {
        error.value = `已登录,但拉取模型失败: ${e}`
      }
    } else {
      models.value = []
    }
  } finally {
    checking.value = false
  }
}

onMounted(refreshSession)
// Re-probe when the tab regains focus (e.g. user came back from /sign-in).
// `visibilitychange` covers mobile / tab-switch too; `focus` covers desktop.
window.addEventListener('focus', refreshSession)
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'visible') refreshSession()
})

async function onSessionChanged(u: NewApiUser | null) {
  user.value = u
  if (u) {
    try {
      models.value = await listModels(baseUrl.value, { kind: 'session' })
    } catch (e) {
      error.value = `已登录,但拉取模型失败: ${e}`
    }
  } else {
    models.value = []
  }
}

function onAuthOverridden(a: Auth) {
  auth.value = a
  if (a.kind === 'sk') {
    // refresh user info using the new auth
    getSelf(baseUrl.value, a)
      .then((u) => {
        user.value = u
      })
      .catch((e) => {
        error.value = `sk-key 无效: ${e}`
      })
  }
}

function onGenerated(img: { prompt: string; model: string; urls: string[] }) {
  galleryRef.value?.add(img)
  // refresh quota after a generation (best-effort)
  if (user.value) {
    probeSession(baseUrl.value)
      .then((u) => {
        if (u) user.value = u
      })
      .catch(() => {
        /* ignore */
      })
  }
}

function onError(msg: string) {
  error.value = msg
}
</script>

<template>
  <div class="min-h-full max-w-5xl mx-auto p-6 space-y-5">
    <header class="flex items-baseline justify-between">
      <div>
        <h1 class="text-2xl font-semibold tracking-tight">newapi-image-gen</h1>
        <p class="text-xs text-zinc-500 mt-0.5">
          走 new-api 的 <code class="text-zinc-400">/v1/images/generations</code>,额度扣 new-api 账户
        </p>
      </div>
      <a
        v-if="user"
        href="/"
        class="text-xs text-zinc-500 hover:text-zinc-300"
      >← 返回 new-api 主页</a>
    </header>

    <p v-if="error" class="rounded-md border border-rose-800 bg-rose-950/40 px-3 py-2 text-sm text-rose-300">
      {{ error }}
    </p>

    <SettingsPanel
      ref="settingsRef"
      :user="user"
      @session-changed="onSessionChanged"
      @auth-overridden="onAuthOverridden"
    />

    <div v-if="checking" class="text-sm text-zinc-500">检查登录态…</div>

    <ImageGenerator
      v-else-if="user"
      :base-url="baseUrl"
      :auth="auth"
      :models="models"
      @generated="onGenerated"
      @error="onError"
    />
    <div v-else class="rounded-xl border border-dashed border-zinc-800 p-6 text-center text-sm text-zinc-500">
      先在上方登录,登录后会自动出现生图面板。
    </div>

    <Gallery ref="galleryRef" :base-url="baseUrl" />

    <footer class="pt-4 pb-2 text-center text-xs text-zinc-600">
      登录走 new-api 自己的 OAuth,会话 cookie 跟 new-api 主站共享;本前端不会碰你的密码或 token。
    </footer>
  </div>
</template>
