<script setup lang="ts">
import { PhCheckCircle, PhFloppyDisk, PhPlus, PhTrash, PhUploadSimple } from '@phosphor-icons/vue'
import { apiErrorMessage } from '~/composables/useUnsavedChanges'
import type { SiteDocument } from '../../../server/utils/site-schema'

definePageMeta({ layout: false })
useHead(() => ({ title: `内容管理｜${document.value?.brand.name || '慧遇书院'}` }))

type ContentTab = 'products' | 'articles' | 'team'
const tab = ref<ContentTab>('products')
const selected = reactive({ products: 0, articles: 0, team: 0 })
const document = ref<SiteDocument>()
const loading = ref(true)
const busy = ref(false)
const message = ref('')
const { dirty, markClean } = useUnsavedChanges(document)

onMounted(async () => {
  try {
    await $fetch('/api/auth/me')
    document.value = (await $fetch<{ data: SiteDocument }>('/api/admin/site')).data
    await nextTick()
    markClean()
  } catch { await navigateTo('/admin/login') }
  finally { loading.value = false }
})

const currentProduct = computed(() => document.value?.products[selected.products])
const currentArticle = computed(() => document.value?.articles[selected.articles])
const currentMember = computed(() => document.value?.team[selected.team])

function makeSlug(prefix: string) { return `${prefix}-${Date.now().toString(36)}` }
function addItem() {
  if (!document.value) return
  if (tab.value === 'products') {
    document.value.products.push({ slug: makeSlug('product'), title: '新产品', subtitle: '', type: 'course', summary: '', content: '', image: '/images/hero-bg-v3.webp', href: '', status: 'draft' })
    selected.products = document.value.products.length - 1
  } else if (tab.value === 'articles') {
    document.value.articles.push({ slug: makeSlug('article'), type: 'news', title: '新内容', summary: '', content: '', cover: '/images/hero-bg-v3.webp', publishedAt: new Date().toISOString().slice(0, 10), status: 'draft', statementNo: '', sourceName: '', sourceUrl: '' })
    selected.articles = document.value.articles.length - 1
  } else {
    document.value.team.push({ slug: makeSlug('member'), name: '新成员', role: '', summary: '', avatar: '/images/lu-hui-portrait.jpg', specialties: [], status: 'draft' })
    selected.team = document.value.team.length - 1
  }
}

function removeItem() {
  if (!document.value || !window.confirm('确定删除当前内容吗？保存后生效。')) return
  document.value[tab.value].splice(selected[tab.value], 1 as never)
  selected[tab.value] = Math.max(0, selected[tab.value] - 1)
}

async function save(publish = false) {
  if (!document.value) return
  busy.value = true
  message.value = ''
  try {
    await $fetch('/api/admin/site', { method: 'PUT', body: document.value })
    if (publish) {
      const result = await $fetch<{ version: number }>('/api/admin/site/publish', { method: 'POST' })
      message.value = `已发布 V${result.version}`
    } else message.value = '草稿已保存'
    markClean()
  } catch (error: any) { message.value = apiErrorMessage(error, '保存失败，请检查必填项和英文标识') }
  finally { busy.value = false }
}

const previewHref = computed(() => {
  if (tab.value === 'products' && currentProduct.value) return `/products/${currentProduct.value.slug}?preview=draft`
  if (tab.value === 'articles' && currentArticle.value) return `${currentArticle.value.type === 'statement' ? '/statements' : '/news'}/${currentArticle.value.slug}?preview=draft`
  return '/team?preview=draft'
})

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

<template>
  <main class="admin-shell">
    <AdminSidebar active="content" :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"><PhCheckCircle :size="18" />{{ message }}</span>
          <a :href="previewHref" target="_blank">预览草稿</a>
          <button :disabled="busy" @click="save(false)"><PhFloppyDisk :size="18" />保存草稿</button>
          <button class="publish-button" :disabled="busy" @click="save(true)"><PhUploadSimple :size="18" />发布更新</button>
        </div>
      </header>
      <div v-if="loading" class="admin-loading">正在加载内容…</div>
      <div v-else-if="document" class="content-admin-body">
        <div class="content-tabs">
          <button v-for="item in ([['products','课程与产品'],['articles','动态与声明'],['team','陪伴团队']] as const)" :key="item[0]" :class="{ active: tab === item[0] }" @click="tab = item[0]">{{ item[1] }}</button>
        </div>
        <div class="content-layout">
          <aside class="content-list">
            <button class="add-content" @click="addItem"><PhPlus :size="18" />新建内容</button>
            <template v-if="tab === 'products'">
              <button v-for="(item, index) in document.products" :key="item.slug" :class="{ active: selected.products === index }" @click="selected.products = index"><strong>{{ item.title }}</strong><small>{{ item.status }} · {{ item.slug }}</small></button>
            </template>
            <template v-if="tab === 'articles'">
              <button v-for="(item, index) in document.articles" :key="item.slug" :class="{ active: selected.articles === index }" @click="selected.articles = index"><strong>{{ item.title }}</strong><small>{{ item.type }} · {{ item.status }}</small></button>
            </template>
            <template v-if="tab === 'team'">
              <button v-for="(item, index) in document.team" :key="item.slug" :class="{ active: selected.team === index }" @click="selected.team = index"><strong>{{ item.name }}</strong><small>{{ item.role || '未填写角色' }} · {{ item.status }}</small></button>
            </template>
          </aside>

          <section class="content-editor">
            <div class="panel-heading"><div><span>编辑</span><h1>{{ tab === 'products' ? '课程与产品' : tab === 'articles' ? '动态与声明' : '陪伴团队' }}</h1></div><button class="danger-link" :disabled="!(document[tab]?.length)" @click="removeItem"><PhTrash :size="17" />删除</button></div>
            <div v-if="tab === 'products' && currentProduct" class="form-grid">
              <label>标题<input v-model="currentProduct.title" maxlength="60"></label><label>英文标识<input v-model="currentProduct.slug" placeholder="family-course"></label>
              <label>类型<select v-model="currentProduct.type"><option value="course">课程</option><option value="service">服务</option><option value="tool">工具</option></select></label><label>状态<select v-model="currentProduct.status"><option value="draft">草稿</option><option value="published">已发布</option><option value="offline">已下线</option></select></label>
              <label class="full">副标题<input v-model="currentProduct.subtitle"></label><label class="full">摘要<textarea v-model="currentProduct.summary" rows="3" /></label><label class="full">正文<textarea v-model="currentProduct.content" rows="12" /></label>
              <label class="full">封面地址<input v-model="currentProduct.image"><span class="compact-upload"><input type="file" accept="image/png,image/jpeg,image/webp" @change="uploadImage($event, url => currentProduct!.image = url)">上传本地图片</span><MediaPicker v-model="currentProduct.image" /></label>
            </div>
            <div v-else-if="tab === 'articles' && currentArticle" class="form-grid">
              <label>标题<input v-model="currentArticle.title"></label><label>英文标识<input v-model="currentArticle.slug"></label>
              <label>类型<select v-model="currentArticle.type"><option value="news">品牌动态</option><option value="statement">官方声明</option><option value="media">媒体报道</option></select></label><label>状态<select v-model="currentArticle.status"><option value="draft">草稿</option><option value="published">已发布</option><option value="offline">已下线</option></select></label>
              <label>发布日期<input v-model="currentArticle.publishedAt" type="date"></label><label>声明编号<input v-model="currentArticle.statementNo"></label>
              <label class="full">摘要<textarea v-model="currentArticle.summary" rows="3" /></label><label class="full">正文<textarea v-model="currentArticle.content" rows="14" /></label>
              <label>来源名称<input v-model="currentArticle.sourceName"></label><label>来源链接<input v-model="currentArticle.sourceUrl"></label>
              <label class="full">封面地址<input v-model="currentArticle.cover"><span class="compact-upload"><input type="file" accept="image/png,image/jpeg,image/webp" @change="uploadImage($event, url => currentArticle!.cover = url)">上传本地图片</span><MediaPicker v-model="currentArticle.cover" /></label>
            </div>
            <div v-else-if="tab === 'team' && currentMember" class="form-grid">
              <label>姓名<input v-model="currentMember.name"></label><label>英文标识<input v-model="currentMember.slug"></label>
              <label>角色<input v-model="currentMember.role"></label><label>状态<select v-model="currentMember.status"><option value="draft">草稿</option><option value="published">已发布</option><option value="offline">已下线</option></select></label>
              <label class="full">简介<textarea v-model="currentMember.summary" rows="5" /></label><label class="full">专长（用中文逗号分隔）<input :value="currentMember.specialties.join('，')" @input="currentMember.specialties = ($event.target as HTMLInputElement).value.split(/[，,]/).map(v => v.trim()).filter(Boolean).slice(0, 8)"></label>
              <label class="full">头像地址<input v-model="currentMember.avatar"><span class="compact-upload"><input type="file" accept="image/png,image/jpeg,image/webp" @change="uploadImage($event, url => currentMember!.avatar = url)">上传本地图片</span><MediaPicker v-model="currentMember.avatar" /></label>
            </div>
            <div v-else class="empty-editor">当前分类暂无内容，点击“新建内容”开始编辑。</div>
          </section>
        </div>
      </div>
    </section>
  </main>
</template>
