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

definePageMeta({ layout: false })
useHead(() => ({ title: `素材中心｜${site.value?.brand.name || '慧遇书院'}` }))

interface MediaAsset {
  id: number; key: string; originalName: string; mimeType: string; bytes: number; width: number; height: number
  url: string; thumbnailUrl: string; altText: string; source: string; copyright: string
  authorizationStatus: 'pending' | 'authorized' | 'restricted'; status: 'active' | 'trash' | 'deleted'; referenced: boolean
  createdAt: string; deletedAt: string | null
}

const site = ref<SiteDocument>()
const items = ref<MediaAsset[]>([])
const selectedId = ref<number>()
const view = ref<'active' | 'trash'>('active')
const loading = ref(true), busy = ref(false), message = ref('')
const uploadMeta = reactive({ altText: '', source: '', copyright: '', authorizationStatus: 'pending' as MediaAsset['authorizationStatus'] })
const selected = computed(() => items.value.find(item => item.id === selectedId.value))

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

async function loadItems() {
  const result = await $fetch<{ data: MediaAsset[] }>('/api/admin/media', { query: { status: view.value } })
  items.value = result.data
  selectedId.value = items.value[0]?.id
}

async function changeView(next: 'active' | 'trash') { view.value = next; message.value = ''; await loadItems() }

async function upload(event: Event) {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  if (!file) return
  busy.value = true; message.value = ''
  try {
    const body = new FormData(); body.append('file', file)
    Object.entries(uploadMeta).forEach(([key, value]) => body.append(key, value))
    const result = await $fetch<{ media: MediaAsset }>('/api/admin/media', { method: 'POST', body })
    items.value.unshift(result.media); selectedId.value = result.media.id
    uploadMeta.altText = ''; uploadMeta.source = ''; uploadMeta.copyright = ''; uploadMeta.authorizationStatus = 'pending'
    message.value = '素材已上传并生成 WebP 与缩略图'
  } catch (error: any) { message.value = error?.data?.statusMessage || '上传失败' }
  finally { busy.value = false; input.value = '' }
}

async function saveMetadata() {
  if (!selected.value) return
  busy.value = true; message.value = ''
  try {
    await $fetch(`/api/admin/media/${selected.value.id}`, { method: 'PATCH', body: { altText: selected.value.altText, source: selected.value.source, copyright: selected.value.copyright, authorizationStatus: selected.value.authorizationStatus } })
    message.value = '素材信息已保存'
  } catch (error: any) { message.value = error?.data?.statusMessage || '保存失败' }
  finally { busy.value = false }
}

async function trash() {
  if (!selected.value || !window.confirm('确定把该素材移入回收站吗？')) return
  busy.value = true; message.value = ''
  try { await $fetch(`/api/admin/media/${selected.value.id}`, { method: 'DELETE' }); message.value = '素材已移入回收站'; await loadItems() }
  catch (error: any) { message.value = error?.data?.statusMessage || '删除失败' }
  finally { busy.value = false }
}

async function restore() {
  if (!selected.value) return
  busy.value = true
  try { await $fetch(`/api/admin/media/${selected.value.id}/restore`, { method: 'POST' }); message.value = '素材已恢复'; await loadItems() }
  catch (error: any) { message.value = error?.data?.statusMessage || '恢复失败' }
  finally { busy.value = false }
}

const formatBytes = (bytes: number) => bytes < 1024 * 1024 ? `${Math.ceil(bytes / 1024)} KB` : `${(bytes / 1024 / 1024).toFixed(1)} MB`
</script>

<template>
  <main class="admin-shell">
    <AdminSidebar active="media" :logo="site?.brand.logo" :brand-name="site?.brand.name" :english-name="site?.brand.englishName" />
    <section class="admin-main">
      <header class="admin-topbar"><div><p>素材中心</p><small>原图、WebP 衍生图、授权信息与安全回收站</small></div><div class="admin-actions"><span v-if="message" class="save-message"><PhCheckCircle :size="18" />{{ message }}</span><button :class="{ 'publish-button': view === 'active' }" @click="changeView('active')">素材库</button><button :class="{ 'publish-button': view === 'trash' }" @click="changeView('trash')">回收站</button></div></header>
      <div v-if="loading" class="admin-loading">正在加载素材…</div>
      <div v-else class="media-admin-body">
        <section v-if="view === 'active'" class="media-upload-panel editor-panel">
          <div><PhUploadSimple :size="30" /><strong>上传新图片</strong><small>支持 JPG、PNG、WebP；最大 8MB、4000 万像素。Logo 建议使用透明 PNG，宽度 600–1600px</small></div>
          <div class="media-upload-meta"><input v-model="uploadMeta.altText" placeholder="ALT 描述（建议填写）"><input v-model="uploadMeta.source" placeholder="素材来源"><input v-model="uploadMeta.copyright" placeholder="版权/授权说明"><select v-model="uploadMeta.authorizationStatus"><option value="pending">待核验</option><option value="authorized">已授权</option><option value="restricted">限制使用</option></select></div>
          <label class="media-upload-button"><input type="file" accept="image/jpeg,image/png,image/webp" :disabled="busy" @change="upload">{{ busy ? '处理中…' : '选择并上传图片' }}</label>
        </section>
        <div class="media-library-layout">
          <section class="media-grid-panel">
            <div v-if="!items.length" class="empty-editor"><PhImageSquare :size="38" /><p>{{ view === 'active' ? '尚未上传素材' : '回收站为空' }}</p></div>
            <button v-for="item in items" :key="item.id" :class="['media-tile', { active: item.id === selectedId }]" @click="selectedId = item.id"><img :src="item.thumbnailUrl" :alt="item.altText || item.originalName"><span>{{ item.originalName }}</span><small>{{ item.width }}×{{ item.height }} · {{ formatBytes(item.bytes) }}</small><b v-if="item.referenced">使用中</b></button>
          </section>
          <aside v-if="selected" class="media-detail editor-panel">
            <img :src="selected.url" :alt="selected.altText || selected.originalName"><div class="media-detail-meta"><strong>{{ selected.originalName }}</strong><small>{{ selected.mimeType }} · {{ selected.width }}×{{ selected.height }} · {{ formatBytes(selected.bytes) }}</small><a :href="selected.url" target="_blank">打开衍生图</a></div>
            <div v-if="view === 'active'" class="form-grid"><label class="full">ALT 描述<input v-model="selected.altText" maxlength="160"></label><label class="full">素材来源<input v-model="selected.source" maxlength="200"></label><label class="full">版权/授权说明<input v-model="selected.copyright" maxlength="200"></label><label class="full">授权状态<select v-model="selected.authorizationStatus"><option value="pending">待核验</option><option value="authorized">已授权</option><option value="restricted">限制使用</option></select></label></div>
            <div class="media-detail-actions"><template v-if="view === 'active'"><button :disabled="busy" @click="saveMetadata"><PhFloppyDisk :size="17" />保存信息</button><button class="danger-link" :disabled="busy || selected.referenced" @click="trash"><PhTrash :size="17" />{{ selected.referenced ? '页面使用中' : '移入回收站' }}</button></template><button v-else :disabled="busy" @click="restore"><PhArrowCounterClockwise :size="17" />恢复素材</button></div>
          </aside>
        </div>
      </div>
    </section>
  </main>
</template>
