<template>
  <div class="container">
    <section class="hero fade-up">
      <div class="hero-badge">REVIEW CENTER</div>
      <h1 class="hero-title">复核与申诉后台</h1>
      <p class="hero-sub">支持阈值调节、拦截复核、申诉处理与分页筛选，满足商用审核流程。</p>
    </section>

    <section class="card fade-up fade-up-delay-1">
      <div class="card-title">检测阈值调节</div>
      <div class="card-desc">阈值越低，拦截越严格。推荐范围：0.65 - 0.85。</div>
      <div class="row">
        <span class="label">垃圾阈值（0-1）</span>
        <input class="input threshold-input" type="number" step="0.01" v-model="thresholdInput" />
      </div>
      <button class="btn btn-primary" @click="saveThreshold">更新阈值</button>
    </section>

    <section class="card fade-up fade-up-delay-1">
      <div class="card-title">拦截记录筛选</div>
      <div class="field">
        <label class="field-label">关键词</label>
        <input class="input" v-model="interceptKeyword" placeholder="搜索拦截文本关键词" />
      </div>
      <div class="grid-2">
        <div class="field">
          <label class="field-label">发布状态</label>
          <select class="select" v-model="interceptStatus">
            <option v-for="opt in interceptStatusOptions" :key="opt.label" :value="opt.value">{{ opt.label }}</option>
          </select>
        </div>
        <div class="field">
          <label class="field-label">复核状态</label>
          <select class="select" v-model="interceptReviewStatus">
            <option v-for="opt in interceptReviewStatusOptions" :key="opt.label" :value="opt.value">{{ opt.label }}</option>
          </select>
        </div>
      </div>
      <div class="btn-row">
        <button class="btn btn-primary" @click="applyInterceptFilters">查询</button>
        <button class="btn btn-ghost" @click="clearInterceptFilters">重置</button>
      </div>
    </section>

    <section class="card fade-up fade-up-delay-2">
      <div class="card-title">信息拦截人工复核</div>
      <div class="muted">共 {{ interceptPager.total }} 条，第 {{ interceptPager.page }} / {{ interceptPager.totalPages }} 页</div>

      <div v-if="intercepts.length">
        <div class="list-item" v-for="item in intercepts" :key="item.id">
          <div class="item-title">{{ item.text }}</div>
          <div class="item-sub">用户：{{ item.nickname || item.username }} · 垃圾概率：{{ item.spam_probability_text }}</div>
          <div class="item-sub" v-if="item.category_label">分类标签：<span class="status-spam">{{ item.category_label }}</span></div>
          <div class="item-sub">复核状态：{{ item.review_status_text }} · 申诉状态：{{ item.appeal_status_text }}</div>
          <div class="item-sub">发布时间：{{ item.created_text }}</div>

          <textarea
            class="textarea note-textarea"
            v-model="reviewNoteMap[item.id]"
            placeholder="可填写复核备注（将写入处理记录）"
          ></textarea>

          <div class="btn-row">
            <button class="btn btn-accent" @click="reviewIntercept(item.id, 'spam')">确认垃圾</button>
            <button class="btn btn-ghost" @click="reviewIntercept(item.id, 'ham')">误判放行</button>
          </div>
        </div>

        <div class="pager-row">
          <button class="btn btn-ghost pager-btn" :disabled="!interceptPager.hasPrev" @click="changeInterceptPage(-1)">上一页</button>
          <button class="btn btn-ghost pager-btn" :disabled="!interceptPager.hasNext" @click="changeInterceptPage(1)">下一页</button>
        </div>
      </div>

      <div v-else class="empty">没有匹配的拦截记录。</div>
    </section>

    <section class="card fade-up fade-up-delay-2">
      <div class="card-title">申诉记录筛选</div>
      <div class="field">
        <label class="field-label">关键词</label>
        <input class="input" v-model="appealKeyword" placeholder="搜索申诉文本或申诉理由" />
      </div>
      <div class="field">
        <label class="field-label">申诉状态</label>
        <select class="select" v-model="appealStatus">
          <option v-for="opt in appealStatusOptions" :key="opt.label" :value="opt.value">{{ opt.label }}</option>
        </select>
      </div>
      <div class="btn-row">
        <button class="btn btn-primary" @click="applyAppealFilters">查询</button>
        <button class="btn btn-ghost" @click="clearAppealFilters">重置</button>
      </div>
    </section>

    <section class="card fade-up fade-up-delay-3">
      <div class="card-title">拦截信息申诉处理</div>
      <div class="muted">共 {{ appealPager.total }} 条，第 {{ appealPager.page }} / {{ appealPager.totalPages }} 页</div>

      <div v-if="appeals.length">
        <div class="list-item" v-for="item in appeals" :key="item.id">
          <div class="item-title">{{ item.text }}</div>
          <div class="item-sub">申诉人：{{ item.nickname || item.username }} · 当前状态：{{ item.appeal_status_text }}</div>
          <div class="item-sub" v-if="item.category_label">分类标签：<span class="status-spam">{{ item.category_label }}</span></div>
          <div class="item-sub">申诉理由类型：{{ item.appeal_reason_type || '未选择' }}</div>
          <div class="item-sub">申诉理由：{{ item.appeal_reason || '未填写' }}</div>
          <div class="item-sub">时间：{{ item.created_text }}</div>

          <div class="field" v-if="item.appeal_evidence_urls && item.appeal_evidence_urls.length">
            <span class="field-label">证据截图</span>
            <div class="evidence-grid">
              <div
                class="evidence-item"
                v-for="url in item.appeal_evidence_urls"
                :key="url"
              >
                <img
                  class="evidence-thumb evidence-clickable"
                  :src="url"
                  @click="previewEvidence(item.appeal_evidence_urls, url)"
                  alt="evidence"
                />
              </div>
            </div>
          </div>

          <textarea
            class="textarea note-textarea"
            v-model="appealNoteMap[item.id]"
            placeholder="可填写申诉处理备注"
          ></textarea>

          <div class="btn-row">
            <button class="btn btn-primary" @click="processAppeal(item.id, 'approve')">通过申诉</button>
            <button class="btn btn-ghost" @click="processAppeal(item.id, 'reject')">驳回申诉</button>
          </div>
        </div>

        <div class="pager-row">
          <button class="btn btn-ghost pager-btn" :disabled="!appealPager.hasPrev" @click="changeAppealPage(-1)">上一页</button>
          <button class="btn btn-ghost pager-btn" :disabled="!appealPager.hasNext" @click="changeAppealPage(1)">下一页</button>
        </div>
      </div>

      <div v-else class="empty">没有匹配的申诉记录。</div>
    </section>
  </div>
</template>

<script>
import { request } from '@/utils/request'
import { toast, previewImage } from '@/utils/feedback'

const INTERCEPT_STATUS_OPTIONS = [
  { value: '', label: '全部发布状态' },
  { value: 'blocked', label: '已拦截' },
  { value: 'published', label: '已发布' }
]

const INTERCEPT_REVIEW_STATUS_OPTIONS = [
  { value: '', label: '全部复核状态' },
  { value: 'pending', label: '待复核' },
  { value: 'confirmed_spam', label: '确认垃圾' },
  { value: 'approved_ham', label: '误判放行' },
  { value: 'none', label: '未进入复核' }
]

const APPEAL_STATUS_OPTIONS = [
  { value: 'pending', label: '待处理申诉' },
  { value: '', label: '全部申诉' },
  { value: 'approved', label: '已通过申诉' },
  { value: 'rejected', label: '已驳回申诉' }
]

const REVIEW_STATUS_TEXT = { none: '无', pending: '待复核', confirmed_spam: '确认垃圾', approved_ham: '误判放行' }
const APPEAL_STATUS_TEXT = { none: '无', pending: '待处理', approved: '已通过', rejected: '已驳回' }
const CATEGORY_LABELS = { fraud: '疑似诈骗', harassment: '疑似骚扰', advertisement: '疑似广告', spam: '疑似垃圾' }

function buildPager(total, page, pageSize) {
  const totalValue = Number(total || 0)
  const totalPages = Math.max(Math.ceil(totalValue / pageSize), 1)
  return {
    page,
    pageSize,
    total: totalValue,
    totalPages,
    hasPrev: page > 1,
    hasNext: page < totalPages
  }
}

export default {
  name: 'AdminReview',
  data() {
    return {
      thresholdInput: '0.75',
      interceptKeyword: '',
      interceptStatus: 'blocked',
      interceptReviewStatus: 'pending',
      interceptStatusOptions: INTERCEPT_STATUS_OPTIONS,
      interceptReviewStatusOptions: INTERCEPT_REVIEW_STATUS_OPTIONS,
      intercepts: [],
      interceptPager: buildPager(0, 1, 10),

      appealKeyword: '',
      appealStatus: 'pending',
      appealStatusOptions: APPEAL_STATUS_OPTIONS,
      appeals: [],
      appealPager: buildPager(0, 1, 10),

      reviewNoteMap: {},
      appealNoteMap: {}
    }
  },
  mounted() {
    this.bootstrap()
  },
  methods: {
    formatPercent(value, digits = 2) {
      return `${(Number(value || 0) * 100).toFixed(digits)}%`
    },
    async bootstrap() {
      await Promise.all([this.fetchThreshold(), this.fetchIntercepts(), this.fetchAppeals()])
    },
    async fetchThreshold() {
      const data = await request({ url: '/admin/detection/threshold' })
      this.thresholdInput = String(data.spam_threshold || 0.75)
    },
    normalizeIntercepts(rows = []) {
      return rows.map((item) => ({
        ...item,
        created_text: (item.created_at || '').replace('T', ' ').slice(0, 19),
        review_status_text: REVIEW_STATUS_TEXT[item.manual_review_status] || item.manual_review_status,
        spam_probability_text: this.formatPercent(item.spam_probability, 2),
        appeal_status_text: APPEAL_STATUS_TEXT[item.appeal_status] || item.appeal_status,
        category_label: CATEGORY_LABELS[item.category] || ''
      }))
    },
    normalizeAppeals(rows = []) {
      return rows.map((item) => ({
        ...item,
        created_text: (item.created_at || '').replace('T', ' ').slice(0, 19),
        appeal_status_text: APPEAL_STATUS_TEXT[item.appeal_status] || item.appeal_status,
        category_label: CATEGORY_LABELS[item.category] || '',
        appeal_evidence_urls: (item.appeal_evidence_urls || []).map((url) =>
          url.startsWith('http') ? url : url
        )
      }))
    },
    async fetchIntercepts() {
      const data = await request({
        url: '/admin/intercepts',
        params: {
          keyword: (this.interceptKeyword || '').trim(),
          status: this.interceptStatus,
          review_status: this.interceptReviewStatus,
          page: this.interceptPager.page,
          page_size: this.interceptPager.pageSize
        }
      })
      this.intercepts = this.normalizeIntercepts(data.items || [])
      this.interceptPager = buildPager(data.total || 0, this.interceptPager.page, this.interceptPager.pageSize)
    },
    async fetchAppeals() {
      const data = await request({
        url: '/admin/appeals',
        params: {
          keyword: (this.appealKeyword || '').trim(),
          status: this.appealStatus,
          page: this.appealPager.page,
          page_size: this.appealPager.pageSize
        }
      })
      this.appeals = this.normalizeAppeals(data.items || [])
      this.appealPager = buildPager(data.total || 0, this.appealPager.page, this.appealPager.pageSize)
    },
    applyInterceptFilters() {
      this.interceptPager = buildPager(0, 1, this.interceptPager.pageSize)
      this.fetchIntercepts()
    },
    clearInterceptFilters() {
      this.interceptKeyword = ''
      this.interceptStatus = 'blocked'
      this.interceptReviewStatus = 'pending'
      this.interceptPager = buildPager(0, 1, this.interceptPager.pageSize)
      this.fetchIntercepts()
    },
    changeInterceptPage(delta) {
      const next = this.interceptPager.page + delta
      if (next < 1 || next > this.interceptPager.totalPages) return
      this.interceptPager = { ...this.interceptPager, page: next }
      this.fetchIntercepts()
    },
    applyAppealFilters() {
      this.appealPager = buildPager(0, 1, this.appealPager.pageSize)
      this.fetchAppeals()
    },
    clearAppealFilters() {
      this.appealKeyword = ''
      this.appealStatus = 'pending'
      this.appealPager = buildPager(0, 1, this.appealPager.pageSize)
      this.fetchAppeals()
    },
    changeAppealPage(delta) {
      const next = this.appealPager.page + delta
      if (next < 1 || next > this.appealPager.totalPages) return
      this.appealPager = { ...this.appealPager, page: next }
      this.fetchAppeals()
    },
    async saveThreshold() {
      const value = Number(this.thresholdInput)
      if (Number.isNaN(value) || value <= 0 || value >= 1) {
        toast('阈值需在 0 到 1 之间', 'error')
        return
      }
      await request({ url: '/admin/detection/threshold', method: 'PUT', data: { spam_threshold: value } })
      toast('阈值更新成功', 'success')
      this.fetchThreshold()
    },
    async reviewIntercept(id, decision) {
      const note = (this.reviewNoteMap[id] || '').trim()
      await request({
        url: `/admin/intercepts/${id}/review`,
        method: 'PUT',
        data: {
          decision,
          note: note || (decision === 'spam' ? '人工复核确认为垃圾信息' : '人工复核后解除拦截')
        }
      })
      toast('复核完成', 'success')
      this.$set(this.reviewNoteMap, id, '')
      await Promise.all([this.fetchIntercepts(), this.fetchAppeals()])
    },
    async processAppeal(id, action) {
      const note = (this.appealNoteMap[id] || '').trim()
      await request({
        url: `/admin/appeals/${id}/process`,
        method: 'PUT',
        data: {
          action,
          note: note || (action === 'approve' ? '申诉通过，解除拦截' : '申诉驳回，维持拦截')
        }
      })
      toast('申诉处理完成', 'success')
      this.$set(this.appealNoteMap, id, '')
      await Promise.all([this.fetchIntercepts(), this.fetchAppeals()])
    },
    previewEvidence(urls, current) {
      previewImage(urls, current)
    }
  }
}
</script>
