<script setup lang="ts">
import {
  PhArrowSquareOut as ArrowSquareOut,
  PhCheckCircle as CheckCircle,
  PhFloppyDisk as FloppyDisk,
  PhImageSquare as ImageSquare,
  PhUploadSimple as UploadSimple,
} from '@phosphor-icons/vue'
import { apiErrorMessage } from '~/composables/useUnsavedChanges'
import type { SiteDocument } from '../../../server/utils/site-schema'

definePageMeta({ layout: false })

const loading = ref(true)
const saving = ref(false)
const publishing = ref(false)
const message = ref('')
const document = ref<SiteDocument>()
const user = ref<{ displayName: string }>()
const uploadBusy = ref<string>()
const { dirty, markClean } = useUnsavedChanges(document)
useHead(() => ({ title: `首页管理｜${document.value?.brand.name || '慧遇书院'}` }))

onMounted(async () => {
  try {
    const [me, site] = await Promise.all([
      $fetch<{ user: { displayName: string } }>('/api/auth/me'),
      $fetch<{ data: SiteDocument }>('/api/admin/site'),
    ])
    user.value = me.user
    document.value = site.data
    await nextTick()
    markClean()
  } catch {
    await navigateTo('/admin/login')
  } finally {
    loading.value = false
  }
})

async function save() {
  if (!document.value) return
  saving.value = true
  message.value = ''
  try {
    await $fetch('/api/admin/site', { method: 'PUT', body: document.value })
    message.value = '草稿已保存'
    markClean()
  } catch (error: any) {
    message.value = apiErrorMessage(error, '保存失败，请检查页面内容')
  } finally {
    saving.value = false
  }
}

async function publish() {
  await save()
  publishing.value = true
  try {
    const result = await $fetch<{ version: number }>('/api/admin/site/publish', { method: 'POST' })
    message.value = `已发布 V${result.version}`
    markClean()
  } catch (error: any) {
    message.value = apiErrorMessage(error, '发布失败，请检查页面内容')
  } finally {
    publishing.value = false
  }
}

async function uploadImage(event: Event, target: 'brand.logo' | 'hero.backgroundImage' | 'teacher.portrait') {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  if (!file || !document.value) return
  uploadBusy.value = target
  message.value = ''
  try {
    const body = new FormData()
    body.append('file', file)
    const result = await $fetch<{ url: string }>('/api/admin/media', { method: 'POST', body })
    if (target === 'brand.logo') document.value.brand.logo = result.url
    if (target === 'hero.backgroundImage') document.value.hero.backgroundImage = result.url
    if (target === 'teacher.portrait') document.value.teacher.portrait = result.url
    message.value = '图片已上传，请保存草稿并发布'
  } catch (error: any) {
    message.value = error?.data?.statusMessage || '图片上传失败'
  } finally {
    uploadBusy.value = undefined
    input.value = ''
  }
}
</script>

<template>
  <main class="admin-shell">
    <AdminSidebar active="home" :logo="document?.brand.logo" :brand-name="document?.brand.name" :english-name="document?.brand.englishName" />
    <section class="admin-main">
      <header class="admin-topbar">
        <div><p>首页管理</p><small>维护官网核心文案并实时预览</small></div>
        <div class="admin-actions">
          <span v-if="dirty" class="dirty-indicator">有未保存修改</span>
          <span v-if="message" class="save-message"><CheckCircle :size="18" />{{ message }}</span>
          <a href="/?preview=draft" target="_blank"><ArrowSquareOut :size="19" />预览草稿</a>
          <button type="button" :disabled="saving" @click="save"><FloppyDisk :size="19" />{{ saving ? '保存中' : '保存草稿' }}</button>
          <button class="publish-button" type="button" :disabled="publishing" @click="publish"><UploadSimple :size="19" />{{ publishing ? '发布中' : '发布更新' }}</button>
        </div>
      </header>

      <div v-if="loading" class="admin-loading">正在加载配置…</div>
      <div v-else-if="document" class="admin-workspace">
        <section class="editor-panel">
          <div class="panel-heading"><div><span>00</span><h1>公司与品牌</h1></div><small>全站统一信息</small></div>
          <div class="form-grid">
            <label>官网展示名称<input v-model="document.brand.name" maxlength="40" placeholder="例如：慧遇书院"></label>
            <label>公司主体全称<input v-model="document.brand.companyName" maxlength="100" placeholder="营业执照登记名称"></label>
            <label>英文名称<input v-model="document.brand.englishName" maxlength="80"></label>
            <label>品牌主张<input v-model="document.brand.slogan" maxlength="40"></label>
            <label>品牌副文案<input v-model="document.brand.subSlogan" maxlength="80"></label>
            <label class="full upload-field">品牌 Logo
              <span class="image-input"><img :src="document.brand.logo" alt="当前品牌 Logo"><input type="file" accept="image/png,image/jpeg,image/webp" @change="uploadImage($event, 'brand.logo')"><b>{{ uploadBusy === 'brand.logo' ? '上传中…' : '选择图片' }}</b></span>
              <MediaPicker v-model="document.brand.logo" />
            </label>
          </div>

          <div class="panel-heading secondary"><div><span>01</span><h2>英雄区</h2></div><small>首屏核心信息</small></div>
          <div class="form-grid">
            <label>第一行标题<input v-model="document.hero.titleLine1" maxlength="20"></label>
            <label>第二行标题<input v-model="document.hero.titleLine2" maxlength="20"></label>
            <label class="full">副标题<input v-model="document.hero.subtitle" maxlength="80"></label>
            <label>按钮文字<input v-model="document.hero.cta" maxlength="20"></label>
            <label>SEO 标题<input v-model="document.seo.title" maxlength="70"></label>
            <label class="full upload-field">首屏背景图
              <span class="image-input"><img :src="document.hero.backgroundImage" alt="当前首屏背景"><input type="file" accept="image/png,image/jpeg,image/webp" @change="uploadImage($event, 'hero.backgroundImage')"><b>{{ uploadBusy === 'hero.backgroundImage' ? '上传中…' : '选择图片' }}</b></span>
              <MediaPicker v-model="document.hero.backgroundImage" />
            </label>
          </div>

          <div id="teacher-form" class="panel-heading secondary"><div><span>02</span><h2>卢慧老师</h2></div><small>首页展示摘要</small></div>
          <div class="form-grid">
            <label>姓名<input v-model="document.teacher.name" maxlength="30"></label>
            <label>身份说明<input v-model="document.teacher.title" maxlength="80"></label>
            <label class="full">简介<textarea v-model="document.teacher.summary" rows="5" maxlength="400" /></label>
            <label class="full upload-field">人物肖像
              <span class="image-input portrait"><img :src="document.teacher.portrait" :alt="document.teacher.name"><input type="file" accept="image/png,image/jpeg,image/webp" @change="uploadImage($event, 'teacher.portrait')"><b>{{ uploadBusy === 'teacher.portrait' ? '上传中…' : '选择图片' }}</b></span>
              <MediaPicker v-model="document.teacher.portrait" />
            </label>
          </div>

          <div class="panel-heading secondary"><div><span>03</span><h2>联系与搜索信息</h2></div><small>页脚和搜索引擎展示</small></div>
          <div class="form-grid">
            <label>联系电话<input v-model="document.contact.phone" maxlength="30"></label>
            <label>联系邮箱<input v-model="document.contact.email" maxlength="100"></label>
            <label class="full">公司地址<input v-model="document.contact.address" maxlength="160"></label>
            <label class="full">SEO 描述<textarea v-model="document.seo.description" rows="3" maxlength="180" /></label>
          </div>

          <div id="media" class="media-placeholder">
            <ImageSquare :size="32" weight="light" />
            <div><strong>本地素材存储</strong><p>一期图片保存在服务器数据卷；Logo、首屏背景与人物肖像已支持上传配置。</p></div>
          </div>
        </section>

        <aside class="preview-panel">
          <div class="preview-label"><span>网站实时预览</span><small>{{ user?.displayName }}</small></div>
          <div class="preview-window" :style="{ backgroundImage: `url(${document.hero.backgroundImage})` }">
            <BrandLogo :src="document.brand.logo" :name="document.brand.name" :english-name="document.brand.englishName" />
            <div><h2>{{ document.hero.titleLine1 }}<br>{{ document.hero.titleLine2 }}</h2><p>{{ document.hero.subtitle }}</p><span>{{ document.hero.cta }} →</span></div>
          </div>
          <div class="preview-teacher">
            <img :src="document.teacher.portrait" :alt="document.teacher.name">
            <div><h3>{{ document.teacher.name }}</h3><p>{{ document.teacher.title }}</p><small>{{ document.teacher.summary }}</small></div>
          </div>
        </aside>
      </div>
    </section>
  </main>
</template>
