<template>
  <div class="work-mgmt-page">
    <a-card class="title-card">
      <template #title>作品管理</template>
    </a-card>

    <!-- 统计卡片（可点击筛选） -->
    <div class="stats-row">
      <div
        v-for="item in statsItems"
        :key="item.key"
        :class="['stat-card', { active: activeStatKey === item.key }]"
        @click="handleStatClick(item.key)"
      >
        <div class="stat-icon" :style="{ background: item.bgColor }">
          <component :is="item.icon" :style="{ color: item.color }" />
        </div>
        <div class="stat-info">
          <span class="stat-count">{{ item.value }}</span>
          <span class="stat-label">{{ item.label }}</span>
        </div>
      </div>
    </div>

    <!-- 筛选 -->
    <div class="filter-bar">
      <a-form layout="inline" :model="filterFormModel" @finish="handleSearch">
        <a-form-item label="作品/作者">
          <a-input
            v-model:value="keyword"
            placeholder="作品名称或作者"
            allow-clear
            style="width: 180px"
            @press-enter="handleSearch"
          />
        </a-form-item>
        <a-form-item label="状态">
          <a-select v-model:value="filterStatus" style="width: 120px" @change="handleSearch">
            <a-select-option value="">全部</a-select-option>
            <a-select-option value="published">正常</a-select-option>
            <a-select-option value="taken_down">已下架</a-select-option>
            <a-select-option value="recommended">推荐中</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="排序">
          <a-select v-model:value="sortBy" style="width: 120px" @change="handleSearch">
            <a-select-option value="latest">最新发布</a-select-option>
            <a-select-option value="hot">最多点赞</a-select-option>
            <a-select-option value="views">最多浏览</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button type="primary" @click="handleSearch"><template #icon><SearchOutlined /></template>搜索</a-button>
            <a-button @click="handleReset"><template #icon><ReloadOutlined /></template>重置</a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </div>

    <!-- 表格 -->
    <a-table :columns="columns" :data-source="dataSource" :loading="loading" :pagination="pagination" row-key="id" @change="handleTableChange" class="data-table">
      <template #bodyCell="{ column, record, index }">
        <template v-if="column.key === 'index'">{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</template>
        <template v-else-if="column.key === 'cover'">
          <img v-if="record.coverUrl" :src="record.coverUrl" class="cover-thumb" />
          <div v-else class="cover-empty">无</div>
        </template>
        <template v-else-if="column.key === 'titleDesc'">
          <div class="title-cell">
            <span class="work-title">{{ record.title }}</span>
            <span v-if="record.description" class="work-desc">{{ record.description }}</span>
          </div>
        </template>
        <template v-else-if="column.key === 'author'">{{ record.creator?.nickname || '-' }}</template>
        <template v-else-if="column.key === 'status'">
          <a-tag :color="record.status === 'published' ? 'green' : 'red'">
            {{ record.status === 'published' ? '正常' : '已下架' }}
          </a-tag>
          <a-tag v-if="record.isRecommended" color="blue">推荐</a-tag>
        </template>
        <template v-else-if="column.key === 'publishTime'">{{ formatDate(record.publishTime) }}</template>
        <template v-else-if="column.key === 'action'">
          <a-space>
            <a-button type="link" size="small" @click="showDetail(record.id)">查看</a-button>
            <a-button type="link" size="small" @click="handleRecommend(record)">
              {{ record.isRecommended ? '取消推荐' : '推荐' }}
            </a-button>
            <a-button v-if="record.status === 'published'" type="link" danger size="small" @click="openTakedown(record)">下架</a-button>
            <a-button v-else type="link" size="small" style="color: #10b981" @click="handleRestore(record)">恢复上架</a-button>
          </a-space>
        </template>
      </template>
    </a-table>

    <!-- 下架弹窗（填写原因） -->
    <a-modal v-model:open="takedownVisible" title="下架作品" @ok="handleTakedown" :confirm-loading="takedownLoading">
      <p style="margin-bottom: 12px; color: #6b7280; font-size: 13px">
        下架后作品「{{ takedownTarget?.title }}」将不再公开展示，请填写下架原因：
      </p>
      <a-radio-group v-model:value="takedownReason" style="display: flex; flex-direction: column; gap: 8px">
        <a-radio value="含不适宜内容">含不适宜内容</a-radio>
        <a-radio value="涉嫌抄袭/侵权">涉嫌抄袭/侵权</a-radio>
        <a-radio value="用户投诉/举报">用户投诉/举报</a-radio>
        <a-radio value="违反平台规范">违反平台规范</a-radio>
        <a-radio value="other">其他</a-radio>
      </a-radio-group>
      <a-input v-if="takedownReason === 'other'" v-model:value="takedownCustom" placeholder="请输入下架原因" style="margin-top: 12px" />
    </a-modal>

    <!-- 详情 Drawer -->
    <a-drawer v-model:open="detailVisible" title="作品详情" :width="580" :destroy-on-close="true">
      <template v-if="detailData">
        <a-descriptions :column="2" bordered size="small">
          <a-descriptions-item label="标题" :span="2">{{ detailData.title }}</a-descriptions-item>
          <a-descriptions-item label="作者">{{ detailData.creator?.nickname }}</a-descriptions-item>
          <a-descriptions-item label="状态">
            <a-tag :color="detailData.status === 'published' ? 'green' : 'red'">{{ detailData.status === 'published' ? '正常' : '已下架' }}</a-tag>
            <a-tag v-if="detailData.isRecommended" color="blue">推荐</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="浏览">{{ detailData.viewCount || 0 }}</a-descriptions-item>
          <a-descriptions-item label="点赞">{{ detailData.likeCount || 0 }}</a-descriptions-item>
          <a-descriptions-item label="收藏">{{ detailData.favoriteCount || 0 }}</a-descriptions-item>
          <a-descriptions-item label="发布时间">{{ formatDate(detailData.publishTime) }}</a-descriptions-item>
        </a-descriptions>

        <!-- 作品描述 -->
        <div v-if="detailData.description" class="detail-section">
          <h4>作品简介</h4>
          <p class="detail-desc">{{ detailData.description }}</p>
        </div>

        <!-- 标签 -->
        <div v-if="detailData.tags?.length" class="detail-section">
          <h4>标签</h4>
          <div style="display: flex; gap: 6px; flex-wrap: wrap">
            <a-tag v-for="t in detailData.tags" :key="t.tag?.id" color="purple">{{ t.tag?.name }}</a-tag>
          </div>
        </div>

        <!-- 绘本翻页预览 -->
        <div v-if="detailData.pages?.length" class="preview-section">
          <h4>绘本内容预览</h4>
          <div class="page-preview">
            <img v-if="detailData.pages[previewPage]?.imageUrl" :src="detailData.pages[previewPage].imageUrl" class="preview-img" />
            <p v-if="detailData.pages[previewPage]?.text" class="preview-text">{{ detailData.pages[previewPage].text }}</p>
            <div class="preview-nav">
              <a-button :disabled="previewPage === 0" size="small" @click="previewPage--">上一页</a-button>
              <span>{{ previewPage + 1 }} / {{ detailData.pages.length }}</span>
              <a-button :disabled="previewPage === detailData.pages.length - 1" size="small" @click="previewPage++">下一页</a-button>
            </div>
          </div>
        </div>

        <!-- 操作按钮 -->
        <div class="drawer-actions">
          <a-space style="width: 100%">
            <a-button
              v-if="detailData.status === 'published'"
              @click="handleRecommendInDrawer"
              :style="{ flex: 1, color: detailData.isRecommended ? undefined : '#1677ff', borderColor: detailData.isRecommended ? undefined : '#1677ff' }"
            >
              {{ detailData.isRecommended ? '取消推荐' : '设为推荐' }}
            </a-button>
            <a-button
              v-if="detailData.status === 'published'"
              danger
              style="flex: 1"
              @click="openTakedown(detailData); detailVisible = false"
            >
              下架
            </a-button>
            <a-button
              v-if="detailData.status === 'taken_down'"
              type="primary"
              style="flex: 1"
              @click="handleRestoreInDrawer"
            >
              恢复上架
            </a-button>
          </a-space>
        </div>

        <!-- 操作日志 -->
        <div class="log-section">
          <h4>操作日志</h4>
          <div v-if="detailLogs.length === 0" class="log-empty">暂无操作记录</div>
          <a-timeline v-else>
            <a-timeline-item
              v-for="log in detailLogs"
              :key="log.id"
              :color="logActionColor[log.action] || 'gray'"
            >
              <div class="log-item">
                <span class="log-action">{{ logActionText[log.action] || log.action }}</span>
                <span class="log-operator">{{ log.operator?.nickname || '系统' }}</span>
                <span class="log-time">{{ formatDate(log.createTime) }}</span>
              </div>
              <div v-if="log.reason" class="log-reason">原因：{{ log.reason }}</div>
              <div v-if="log.note" class="log-note">备注：{{ log.note }}</div>
            </a-timeline-item>
          </a-timeline>
        </div>
      </template>
    </a-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import {
  SearchOutlined, ReloadOutlined,
  AppstoreOutlined, PlusCircleOutlined, EyeOutlined, StopOutlined,
} from '@ant-design/icons-vue'
import request from '@/utils/request'
import dayjs from 'dayjs'

/** 供 a-form :model 使用，避免无 model 时 @finish/提交不触发 */
const filterFormModel = reactive<Record<string, unknown>>({})

const loading = ref(false)
const dataSource = ref<any[]>([])
const pagination = reactive({ current: 1, pageSize: 10, total: 0, showSizeChanger: true, showTotal: (t: number) => `共 ${t} 条` })
const keyword = ref('')
const sortBy = ref('latest')
const filterStatus = ref('')
const activeStatKey = ref('')

// 统计
const statsRaw = ref({ total: 0, todayNew: 0, totalViews: 0, takenDown: 0 })
const statsItems = computed(() => [
  { key: 'total', label: '总作品数', value: statsRaw.value.total, icon: AppstoreOutlined, color: '#6366f1', bgColor: 'rgba(99,102,241,0.1)' },
  { key: 'todayNew', label: '今日新增', value: statsRaw.value.todayNew, icon: PlusCircleOutlined, color: '#10b981', bgColor: 'rgba(16,185,129,0.1)' },
  { key: 'totalViews', label: '累计浏览', value: statsRaw.value.totalViews, icon: EyeOutlined, color: '#f59e0b', bgColor: 'rgba(245,158,11,0.1)' },
  { key: 'takenDown', label: '已下架', value: statsRaw.value.takenDown, icon: StopOutlined, color: '#ef4444', bgColor: 'rgba(239,68,68,0.1)' },
])

// 下架弹窗
const takedownVisible = ref(false)
const takedownLoading = ref(false)
const takedownTarget = ref<any>(null)
const takedownReason = ref('')
const takedownCustom = ref('')

// 详情 + 日志
const detailVisible = ref(false)
const detailData = ref<any>(null)
const detailLogs = ref<any[]>([])
const previewPage = ref(0)

const logActionText: Record<string, string> = { approve: '审核通过', reject: '审核拒绝', takedown: '下架', restore: '恢复', revoke: '撤销审核' }
const logActionColor: Record<string, string> = { approve: 'green', reject: 'red', takedown: 'gray', restore: 'blue', revoke: 'orange' }

// #6 表格加描述预览列
const columns = [
  { title: '序号', key: 'index', width: 50 },
  { title: '封面', key: 'cover', width: 70 },
  { title: '作品名称', key: 'titleDesc', width: 220 },
  { title: '作者', key: 'author', width: 90 },
  { title: '浏览', dataIndex: 'viewCount', key: 'viewCount', width: 65 },
  { title: '点赞', dataIndex: 'likeCount', key: 'likeCount', width: 65 },
  { title: '收藏', dataIndex: 'favoriteCount', key: 'favoriteCount', width: 65 },
  { title: '状态', key: 'status', width: 110 },
  { title: '发布时间', key: 'publishTime', width: 130 },
  { title: '操作', key: 'action', width: 210, fixed: 'right' as const },
]

const formatDate = (d: string) => d ? dayjs(d).format('YYYY-MM-DD HH:mm') : '-'

const fetchStats = async () => {
  try {
    statsRaw.value = await request.get('/content-review/management/stats') as any
  } catch { /* */ }
}

const fetchList = async () => {
  loading.value = true
  try {
    const dayStart = dayjs().startOf('day').format('YYYY-MM-DDTHH:mm:ss')
    const dayEnd = dayjs().endOf('day').format('YYYY-MM-DDTHH:mm:ss')
    const params: Record<string, unknown> = {
      page: pagination.current,
      pageSize: pagination.pageSize,
      keyword: keyword.value || undefined,
    }
    const key = activeStatKey.value
    // 统计卡片优先：与设计「点击卡片筛选列表」一致
    if (key === 'todayNew') {
      params.startTime = dayStart
      params.endTime = dayEnd
      params.status = 'published,taken_down'
      params.sortBy = sortBy.value
    } else if (key === 'takenDown') {
      params.status = 'taken_down'
      params.sortBy = sortBy.value
    } else if (key === 'totalViews') {
      params.status = 'published,taken_down'
      params.sortBy = 'views'
    } else if (key === 'total') {
      params.status = 'published,taken_down'
      params.sortBy = sortBy.value
    } else {
      const isRecommendedFilter = filterStatus.value === 'recommended'
      params.sortBy = sortBy.value
      if (isRecommendedFilter) {
        params.status = 'published'
        params.isRecommended = '1'
      } else {
        params.status = filterStatus.value || 'published,taken_down'
      }
    }
    const res: any = await request.get('/content-review/works', { params })
    dataSource.value = res.list
    pagination.total = res.total
  } catch { message.error('获取失败') }
  finally { loading.value = false }
}

// #7 统计卡片点击筛选（与 fetchList 中 activeStatKey 分支联动，不再改写 filterStatus）
const handleStatClick = (key: string) => {
  if (activeStatKey.value === key) {
    activeStatKey.value = ''
  } else {
    activeStatKey.value = key
  }
  pagination.current = 1
  fetchList()
}

// #1 筛选自动查询
const handleSearch = () => { activeStatKey.value = ''; pagination.current = 1; fetchList() }
const handleReset = () => { keyword.value = ''; sortBy.value = 'latest'; filterStatus.value = ''; activeStatKey.value = ''; pagination.current = 1; fetchList(); fetchStats() }
const handleTableChange = (pag: any) => { pagination.current = pag.current; pagination.pageSize = pag.pageSize; fetchList() }

// 详情
const showDetail = async (id: number) => {
  previewPage.value = 0
  detailLogs.value = []
  try {
    const [work, logs]: any[] = await Promise.all([
      request.get(`/content-review/works/${id}`),
      request.get('/content-review/logs', { params: { workId: id, pageSize: 50 } }),
    ])
    detailData.value = work
    detailLogs.value = logs.list || []
    detailVisible.value = true
  } catch { message.error('获取详情失败') }
}

// #3 推荐/取消推荐（取消推荐时二次确认）
const handleRecommend = async (record: any) => {
  if (record.isRecommended) {
    Modal.confirm({
      title: '确定取消推荐？',
      content: `作品「${record.title}」将不再显示在推荐位`,
      onOk: async () => {
        try { await request.post(`/content-review/works/${record.id}/recommend`); message.success('已取消推荐'); fetchList() }
        catch { message.error('操作失败') }
      },
    })
  } else {
    try { await request.post(`/content-review/works/${record.id}/recommend`); message.success('已推荐'); fetchList() }
    catch { message.error('操作失败') }
  }
}

// #4 详情内推荐操作
const handleRecommendInDrawer = async () => {
  const record = detailData.value
  if (!record) return
  if (record.isRecommended) {
    Modal.confirm({
      title: '确定取消推荐？',
      onOk: async () => {
        try { await request.post(`/content-review/works/${record.id}/recommend`); message.success('已取消推荐'); fetchList(); showDetail(record.id) }
        catch { message.error('操作失败') }
      },
    })
  } else {
    try { await request.post(`/content-review/works/${record.id}/recommend`); message.success('已推荐'); fetchList(); showDetail(record.id) }
    catch { message.error('操作失败') }
  }
}

// #2 下架填写原因
const openTakedown = (record: any) => {
  takedownTarget.value = record
  takedownReason.value = ''
  takedownCustom.value = ''
  takedownVisible.value = true
}
const handleTakedown = async () => {
  const reason = takedownReason.value === 'other' ? takedownCustom.value : takedownReason.value
  if (!reason) { message.warning('请选择下架原因'); return }
  takedownLoading.value = true
  try {
    await request.post(`/content-review/works/${takedownTarget.value.id}/takedown`, { reason })
    message.success('已下架')
    takedownVisible.value = false
    fetchList(); fetchStats()
  } catch { message.error('操作失败') }
  finally { takedownLoading.value = false }
}

const handleRestore = async (record: any) => {
  try { await request.post(`/content-review/works/${record.id}/restore`); message.success('已恢复'); fetchList(); fetchStats() }
  catch { message.error('操作失败') }
}

// #4 详情内恢复操作
const handleRestoreInDrawer = async () => {
  const id = detailData.value?.id
  if (!id) return
  try { await request.post(`/content-review/works/${id}/restore`); message.success('已恢复上架'); fetchList(); fetchStats(); showDetail(id) }
  catch { message.error('操作失败') }
}

onMounted(() => { fetchStats(); fetchList() })
</script>

<style scoped lang="scss">
$primary: #6366f1;
.title-card { margin-bottom: 16px; border: none; border-radius: 12px; box-shadow: 0 2px 12px rgba(0,0,0,0.06); :deep(.ant-card-head) { border-bottom: none; .ant-card-head-title { font-size: 18px; font-weight: 600; } } :deep(.ant-card-body) { padding: 0; } }

// #7 统计卡片可点击
.stats-row { display: flex; gap: 12px; margin-bottom: 16px; }
.stat-card { flex: 1; display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: #fff; border-radius: 12px; box-shadow: 0 2px 12px rgba(0,0,0,0.06); cursor: pointer; border: 2px solid transparent; transition: all 0.2s;
  &:hover { box-shadow: 0 4px 16px rgba($primary, 0.12); } &.active { border-color: $primary; background: rgba($primary, 0.02); }
  .stat-icon { width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
  .stat-info { display: flex; flex-direction: column; .stat-count { font-size: 18px; font-weight: 700; color: #1e1b4b; line-height: 1.2; } .stat-label { font-size: 12px; color: #9ca3af; } }
}

.filter-bar { padding: 20px 24px; background: #fff; border-radius: 12px; box-shadow: 0 2px 12px rgba(0,0,0,0.06); margin-bottom: 16px; }
.data-table { :deep(.ant-table-wrapper) { background: #fff; border-radius: 12px; box-shadow: 0 2px 12px rgba(0,0,0,0.06); overflow: hidden; .ant-table-thead > tr > th { background: #fafafa; font-weight: 600; } .ant-table-tbody > tr:hover > td { background: rgba($primary, 0.03); } .ant-table-pagination { padding: 16px; margin: 0; } } }

// #6 标题+描述
.title-cell {
  display: flex; flex-direction: column; gap: 2px;
  .work-title { font-size: 13px; font-weight: 600; color: #1e1b4b; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .work-desc { font-size: 11px; color: #9ca3af; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 200px; }
}

.cover-thumb { width: 48px; height: 64px; object-fit: cover; border-radius: 6px; }
.cover-empty { width: 48px; height: 64px; background: #f3f4f6; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 10px; color: #d1d5db; }

// 详情区块
.detail-section {
  margin-top: 16px;
  h4 { font-size: 13px; font-weight: 600; color: #374151; margin: 0 0 8px; }
  .detail-desc { font-size: 13px; color: #6b7280; line-height: 1.6; margin: 0; }
}

.preview-section { margin-top: 20px; h4 { font-size: 14px; font-weight: 600; color: #1e1b4b; margin: 0 0 12px; padding-bottom: 8px; border-bottom: 1px solid #f0ecf9; } }
.page-preview {
  .preview-img { width: 100%; max-height: 300px; object-fit: contain; border-radius: 8px; margin-bottom: 8px; }
  .preview-text { font-size: 13px; color: #374151; line-height: 1.6; padding: 8px 0; }
  .preview-nav { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; span { font-size: 12px; color: #6b7280; } }
}

// #4 详情内操作按钮
.drawer-actions {
  margin-top: 20px; padding-top: 16px; border-top: 1px solid #f0ecf9;
  :deep(.ant-space) { display: flex; .ant-space-item { flex: 1; .ant-btn { width: 100%; } } }
}

// 操作日志
.log-section {
  margin-top: 24px;
  h4 { font-size: 14px; font-weight: 600; color: #1e1b4b; margin: 0 0 16px; padding-bottom: 8px; border-bottom: 1px solid #f0ecf9; }
  .log-empty { font-size: 13px; color: #9ca3af; text-align: center; padding: 20px 0; }
}
.log-item {
  display: flex; align-items: center; gap: 8px;
  .log-action { font-size: 13px; font-weight: 600; color: #1e1b4b; }
  .log-operator { font-size: 12px; color: #6b7280; }
  .log-time { font-size: 11px; color: #9ca3af; margin-left: auto; }
}
.log-reason, .log-note { font-size: 12px; color: #6b7280; margin-top: 2px; }
</style>
