<script>
export default { name: 'EditInfoView' }
</script>
<template>
  <div class="edit-page page-fullscreen">
    <PageHeader title="编辑绘本信息" subtitle="完善信息，作品将进入「未发布」可随时发布" :showBack="true" />

    <div v-if="loading" class="loading-state">
      <loading-outlined class="loading-icon" spin />
      <div class="loading-text">加载中…</div>
    </div>

    <div v-else class="content page-content">
      <!-- 封面预览 -->
      <div class="cover-preview" v-if="coverUrl">
        <img :src="coverUrl" class="cover-img" />
        <div class="cover-title-overlay">{{ store.workDetail?.title || '未命名' }}</div>
      </div>

      <!-- 基本信息 -->
      <div class="card form-card">
        <div class="field-item">
          <div class="field-label">
            <edit-outlined />
            <span>作者署名</span>
            <span class="required-mark">必填</span>
          </div>
          <input v-model="form.author" class="text-input" :class="{ 'input-error': authorError }" placeholder="如：你的名字"
            maxlength="16" @input="authorError = ''" />
          <div class="field-row-meta">
            <span v-if="authorError" class="field-error">{{ authorError }}</span>
            <span v-else class="field-error placeholder-error">&nbsp;</span>
            <span class="char-count">{{ form.author.length }}/16</span>
          </div>
        </div>

        <div class="field-item">
          <div class="field-label">
            <file-text-outlined />
            <span>副标题</span>
            <span class="optional-mark">选填</span>
          </div>
          <input v-model="form.subtitle" class="text-input" placeholder="如：一个关于勇气的故事" maxlength="20" />
          <div class="field-row-meta">
            <span class="char-count">{{ form.subtitle.length }}/20</span>
          </div>
        </div>

        <div class="field-item">
          <div class="field-label">
            <book-outlined />
            <span>绘本简介</span>
            <span class="optional-mark">选填</span>
            <span class="char-count char-count-right">{{ form.intro.length }}/250</span>
          </div>
          <textarea v-model="form.intro" class="textarea-input" placeholder="简单介绍一下这个绘本的故事" maxlength="250" rows="3" />
        </div>
      </div>

      <!-- 标签 -->
      <div class="card form-card">
        <div class="field-label" style="margin-bottom: 12px">
          <tags-outlined />
          <span>绘本标签</span>
        </div>

        <div class="tags-wrap">
          <span v-for="(tag, i) in selectedTags" :key="'s' + i" class="tag selected-tag">
            <span>{{ tag }}</span>
            <close-outlined v-if="selectedTags.length > 1" class="tag-remove" @click="removeTag(i)" />
          </span>
          <!-- 添加标签（达到5个上限时隐藏） -->
          <template v-if="selectedTags.length < 5">
            <span v-if="!addingTag" class="tag add-tag" @click="addingTag = true">
              <plus-outlined />
            </span>
            <span v-else class="tag adding-tag">
              <input ref="tagInput" v-model="newTag" class="tag-input" placeholder="输入标签" maxlength="8"
                @keydown.enter="confirmAddTag" @blur="confirmAddTag" />
            </span>
          </template>
        </div>

        <!-- 推荐标签 -->
        <div v-if="selectedTags.length < 5 && limitedPresets.length > 0" class="preset-tags">
          <span v-for="p in limitedPresets" :key="p" class="tag preset-tag" @click="addPresetTag(p)">
            <plus-outlined />
            <span>{{ p }}</span>
          </span>
        </div>
      </div>
    </div>

    <!-- 底部三按钮 -->
    <div v-if="!loading" class="page-bottom">
      <div class="action-row">
        <button class="action-btn draft-btn" :disabled="processing" @click="handleSave">
          <inbox-outlined />
          <span>保存</span>
        </button>
        <button class="action-btn dubbing-btn" :disabled="processing" @click="handleGoDubbing">
          <audio-outlined />
          <span>去配音</span>
        </button>
        <button class="action-btn publish-btn" :disabled="processing" @click="handlePublish">
          <send-outlined />
          <span>直接发布</span>
        </button>
      </div>
      <div class="action-hint">
        保存后进入「未发布」可随时发布 · 配音是可选步骤 · 发布后进入审核
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onActivated, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import {
  LoadingOutlined,
  EditOutlined,
  FileTextOutlined,
  BookOutlined,
  TagsOutlined,
  PlusOutlined,
  CloseOutlined,
  InboxOutlined,
  AudioOutlined,
  SendOutlined,
} from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import PageHeader from '@/components/aicreate/PageHeader.vue'
import { getWorkDetail, updateWork } from '@/api/aicreate'
import { publicUserWorksApi } from '@/api/public'
import { useAicreateStore } from '@/stores/aicreate'
import { clearExtractDraft } from '@/utils/aicreate/extractDraft'
import { STATUS, getRouteByStatus } from '@/utils/aicreate/status'

const router = useRouter()
const route = useRoute()
const store = useAicreateStore()
const workId = computed(() => route.params.workId || store.workId)

const loading = ref(true)
const processing = ref(false)
const coverUrl = ref('')

const form = ref({ author: '', subtitle: '', intro: '' })
const selectedTags = ref([])
const addingTag = ref(false)
const newTag = ref('')
const tagInput = ref(null)

const PRESET_TAGS = ['冒险', '成长', '友谊', '魔法', '勇敢', '快乐', '温暖', '探索', '梦想', '好奇']
const availablePresets = computed(() =>
  PRESET_TAGS.filter(t => !selectedTags.value.includes(t))
)
const limitedPresets = computed(() => {
  const remaining = 5 - selectedTags.value.length
  if (remaining <= 0) return []
  return availablePresets.value.slice(0, remaining)
})

function removeTag(i) {
  if (selectedTags.value.length <= 1) return
  selectedTags.value.splice(i, 1)
}

function addPresetTag(tag) {
  if (selectedTags.value.length >= 5) return
  if (!selectedTags.value.includes(tag)) selectedTags.value.push(tag)
}

function confirmAddTag() {
  const t = newTag.value.trim()
  if (t && !selectedTags.value.includes(t) && selectedTags.value.length < 5) {
    selectedTags.value.push(t)
  }
  newTag.value = ''
  addingTag.value = false
}

async function loadWork() {
  loading.value = true
  try {
    // 缓存不匹配当前 workId 时重新请求
    if (!store.workDetail || store.workDetail.workId !== workId.value) {
      store.workDetail = null
      const res = await getWorkDetail(workId.value)
      store.workDetail = res
    }
    const w = store.workDetail

    // 已配音（DUBBED）仍可在本页编辑元数据/发布；仅当状态高于当前流程终态时再按 status 跳转
    if (w.status > STATUS.DUBBED) {
      const nextRoute = getRouteByStatus(w.status, w.workId)
      if (nextRoute) { router.replace(nextRoute); return }
    }

    form.value.author = w.author || ''
    form.value.subtitle = w.subtitle || ''
    form.value.intro = w.intro || ''
    selectedTags.value = Array.isArray(w.tags) && w.tags.length ? [...w.tags] : ['冒险']
    coverUrl.value = w.pageList?.[0]?.imageUrl || ''
  } catch (e) {
    // fallback: proceed with empty form
  } finally {
    loading.value = false
  }
}

const authorError = ref('')

function validate() {
  if (!form.value.author.trim()) {
    authorError.value = '请填写作者署名'
    return false
  }
  authorError.value = ''
  return true
}

/**
 * 保存表单数据到后端，返回是否成功
 * 不做跳转，由各 handler 决定下一步去哪
 */
async function saveFormToServer() {
  try {
    const data = { tags: selectedTags.value }
    data.author = form.value.author.trim()
    if (form.value.subtitle.trim()) data.subtitle = form.value.subtitle.trim()
    if (form.value.intro.trim()) data.intro = form.value.intro.trim()

    await updateWork(workId.value, data)

    if (store.workDetail) {
      store.workDetail.author = data.author
      if (data.subtitle) store.workDetail.subtitle = data.subtitle
      if (data.intro) store.workDetail.intro = data.intro
      store.workDetail.tags = [...selectedTags.value]
    }
    return true
  } catch (e) {
    // 容错：保存报错时检查实际状态，可能已经成功但重试导致 CAS 失败
    try {
      const check = await getWorkDetail(workId.value)
      if (check?.status >= 4) return true
    } catch { /* ignore */ }
    message.error(e.message || '保存失败，请重试')
    return false
  }
}

/** 保存（编目完成 → unpublished）→ 保存成功页，可继续配音或进作品库 */
async function handleSave() {
  if (!validate()) return
  processing.value = true
  try {
    if (await saveFormToServer()) {
      store.workDetail = null
      router.push({
        name: 'PublicCreateSaveSuccess',
        params: { workId: String(workId.value || '') },
      })
    }
  } finally {
    processing.value = false
  }
}

/** 去配音 → 跳 DubbingView */
async function handleGoDubbing() {
  if (!validate()) return
  processing.value = true
  try {
    if (await saveFormToServer()) {
      store.workDetail = null
      router.push(`/p/create/dubbing/${workId.value}`)
    }
  } finally {
    processing.value = false
  }
}

/** 按乐读派 remoteWorkId 解析本地作品库主键 id */
async function findUgcIdByRemoteWorkId(remoteId) {
  const rw = String(remoteId || '').trim()
  if (!rw) return null
  let page = 1
  const pageSize = 100
  for (let i = 0; i < 20; i++) {
    const res = await publicUserWorksApi.list({ page, pageSize })
    const list = res?.list || []
    const hit = list.find(w => w.remoteWorkId === rw)
    if (hit) return hit.id
    const total = res?.total ?? 0
    if (page * pageSize >= total) break
    page += 1
  }
  return null
}

/** 发布作品：编目保存 → 提交审核（与作品详情「公开发布」同一接口） */
async function handlePublish() {
  if (!validate()) return
  processing.value = true
  try {
    if (!(await saveFormToServer())) return

    const rw = String(workId.value || '').trim()
    let ugcId = await findUgcIdByRemoteWorkId(rw)
    if (ugcId == null) {
      message.error('作品库尚未同步该绘本，请稍后重试或到作品详情页点击「公开发布」')
      return
    }

    try {
      await publicUserWorksApi.publish(ugcId)
    } catch (e) {
      const msg = e?.message || ''
      if (msg.includes('当前状态不可发布')) {
        await new Promise(r => setTimeout(r, 500))
        await publicUserWorksApi.publish(ugcId)
      } else {
        throw e
      }
    }

    store.workDetail = null
    message.success('提交成功，作品已进入审核，可在作品库「审核中」查看进度')
    router.push({
      name: 'PublicCreateSaveSuccess',
      params: { workId: rw },
      query: { after: 'publish' },
    })
  } catch (e) {
    message.error(e?.message || '提交审核失败，请重试')
  } finally {
    processing.value = false
  }
}

onActivated(() => {
  clearExtractDraft()
  loadWork()
  nextTick(() => { if (tagInput.value) tagInput.value.focus() })
})
</script>

<style lang="scss" scoped>
.edit-page {
  background: var(--ai-bg);
  display: flex;
  flex-direction: column;
}

/* ---------- 加载状态 ---------- */
.loading-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 0;
}

.loading-icon {
  font-size: 44px;
  color: var(--ai-primary);
  margin-bottom: 14px;
}

.loading-text {
  color: var(--ai-text-sub);
  font-size: 14px;
}

/* ---------- 内容区 ---------- */
.content {
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* ---------- 封面预览 ---------- */
.cover-preview {
  position: relative;
  border-radius: var(--ai-radius);
  overflow: hidden;
  height: 130px;
  box-shadow: 0 4px 16px rgba(99, 102, 241, 0.12);
  border: 1px solid rgba(99, 102, 241, 0.06);
}

.cover-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.cover-title-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 16px 18px 12px;
  background: linear-gradient(transparent, rgba(15, 12, 41, 0.75));
  color: #fff;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: 0.5px;
}

/* ---------- 表单卡片 ---------- */
.form-card {
  background: #fff;
  border: 1px solid rgba(99, 102, 241, 0.06);
  border-radius: var(--ai-radius);
  padding: 18px;
  box-shadow: 0 2px 12px rgba(99, 102, 241, 0.05);
}

.field-item {
  margin-bottom: 16px;

  &:last-child {
    margin-bottom: 0;
  }
}

.field-label {
  font-size: 13px;
  color: var(--ai-text);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;

  :deep(.anticon) {
    font-size: 14px;
    color: var(--ai-primary);
  }
}

/* ---------- 必填 / 选填标签 ---------- */
.required-mark {
  color: var(--ai-primary);
  font-size: 11px;
  background: rgba(99, 102, 241, 0.1);
  padding: 2px 8px;
  border-radius: 8px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

.optional-mark {
  color: var(--ai-text-sub);
  font-size: 11px;
  background: rgba(107, 114, 128, 0.08);
  padding: 2px 8px;
  border-radius: 8px;
  font-weight: 600;
  letter-spacing: 0.5px;
}

/* ---------- 输入框 ---------- */
.text-input,
.textarea-input {
  width: 100%;
  border: 1.5px solid rgba(99, 102, 241, 0.12);
  background: rgba(99, 102, 241, 0.04);
  border-radius: 12px;
  padding: 13px 14px;
  font-size: 15px;
  outline: none;
  color: var(--ai-text);
  box-sizing: border-box;
  font-weight: 500;
  transition: all 0.2s;

  &::placeholder {
    color: #b8b6c4;
  }

  &:focus {
    border-color: var(--ai-primary);
    background: #fff;
    box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);
  }
}

.textarea-input {
  resize: none;
  line-height: 1.6;
  font-size: 14px;
}

.input-error {
  border-color: #ef4444 !important;

  &:focus {
    border-color: #ef4444 !important;
    box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.1) !important;
  }
}

/* ---------- 字段下方元信息行 ---------- */
.field-row-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 6px;
  min-height: 16px;
}

.field-error {
  color: #ef4444;
  font-size: 12px;
  font-weight: 500;
}

.placeholder-error {
  visibility: hidden;
}

.char-count {
  font-size: 11px;
  color: var(--ai-text-sub);
  margin-left: auto;
}

.char-count-right {
  margin-left: auto;
}

/* ---------- 标签区 ---------- */
.tags-wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  border-radius: 18px;
  font-size: 13px;
  cursor: pointer;
  transition: all 0.2s;
  font-weight: 600;
}

.selected-tag {
  background: rgba(99, 102, 241, 0.1);
  color: var(--ai-primary);
  border: 1px solid rgba(99, 102, 241, 0.2);
}

.tag-remove {
  font-size: 11px;
  opacity: 0.6;
  margin-left: 2px;
  transition: opacity 0.2s;

  &:hover {
    opacity: 1;
  }
}

.add-tag {
  background: rgba(99, 102, 241, 0.06);
  color: var(--ai-text-sub);
  border: 1px dashed rgba(99, 102, 241, 0.3);
  padding: 6px 14px;

  :deep(.anticon) {
    font-size: 12px;
  }

  &:hover {
    color: var(--ai-primary);
    border-color: var(--ai-primary);
  }
}

.adding-tag {
  background: #fff;
  border: 1.5px solid var(--ai-primary);
  padding: 4px 10px;
}

.tag-input {
  border: none;
  outline: none;
  font-size: 13px;
  width: 70px;
  background: transparent;
  color: var(--ai-text);
  font-weight: 600;
}

.preset-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.preset-tag {
  background: rgba(99, 102, 241, 0.04);
  color: var(--ai-text-sub);
  border: 1px solid rgba(99, 102, 241, 0.1);
  font-size: 12px;
  padding: 4px 10px;
  font-weight: 500;

  :deep(.anticon) {
    font-size: 10px;
  }

  &:hover {
    background: rgba(99, 102, 241, 0.1);
    color: var(--ai-primary);
    border-color: rgba(99, 102, 241, 0.25);
  }
}

/* ---------- 底部三按钮 ---------- */
.action-row {
  display: flex;
  gap: 10px;
}

.action-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 13px 8px;
  border-radius: 22px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.2s;
  white-space: nowrap;
  min-width: 0;

  :deep(.anticon) {
    font-size: 14px;
  }

  &:active {
    transform: scale(0.97);
  }

  &:disabled {
    opacity: 0.4;
    pointer-events: none;
  }
}

/* 保存草稿：最弱，透明 + 紫色淡边 */
.draft-btn {
  background: transparent;
  color: var(--ai-text-sub);
  border: 1.5px solid rgba(99, 102, 241, 0.2);

  &:hover {
    color: var(--ai-primary);
    border-color: var(--ai-primary);
    background: rgba(99, 102, 241, 0.04);
  }
}

/* 去配音：中等，白底紫边 */
.dubbing-btn {
  background: #fff;
  color: var(--ai-primary);
  border: 1.5px solid rgba(99, 102, 241, 0.4);
  box-shadow: 0 2px 10px rgba(99, 102, 241, 0.06);

  &:hover {
    border-color: var(--ai-primary);
    background: rgba(99, 102, 241, 0.04);
    box-shadow: 0 4px 14px rgba(99, 102, 241, 0.12);
  }
}

/* 发布作品：主操作，紫粉渐变 */
.publish-btn {
  background: var(--ai-gradient);
  color: #fff;
  border: none;
  box-shadow: 0 6px 18px rgba(99, 102, 241, 0.32);

  &:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 22px rgba(99, 102, 241, 0.4);
  }
}

.action-hint {
  margin-top: 10px;
  text-align: center;
  font-size: 11px;
  color: var(--ai-text-sub);
  font-weight: 500;
  letter-spacing: 0.3px;
}
</style>
