<template>
  <div class="review-page">
    <!-- 页面头部 -->
    <div class="page-header">
      <div>
        <h2 class="page-title">🔍 应用审核管理</h2>
        <p class="page-desc">审核开发者提交的应用上架申请</p>
      </div>
      <a-space>
        <a-button @click="loadApps" :loading="loading">
          <template #icon><ReloadOutlined /></template>
          刷新
        </a-button>
      </a-space>
    </div>

    <!-- 状态统计 -->
    <a-row :gutter="[16, 16]" class="mb-6">
      <a-col :xs="12" :md="6" v-for="stat in reviewStats" :key="stat.key">
        <div
          class="stat-card"
          :class="[stat.color, { active: filterStatus === stat.key }]"
          @click="handleStatFilter(stat.key)"
        >
          <div class="stat-icon">{{ stat.icon }}</div>
          <div class="stat-info">
            <div class="stat-value">{{ stat.value }}</div>
            <div class="stat-label">{{ stat.label }}</div>
          </div>
        </div>
      </a-col>
    </a-row>

    <!-- 筛选栏 -->
    <div class="panel">
      <div class="panel-header">
        <span class="panel-title">📋 审核列表</span>
        <a-space>
          <a-select
            v-model:value="filterStatus"
            style="width: 140px"
            @change="loadApps"
          >
            <a-select-option value="">全部状态</a-select-option>
            <a-select-option value="pending_review">待审核</a-select-option>
            <a-select-option value="published">已上架</a-select-option>
            <a-select-option value="rejected">已拒绝</a-select-option>
            <a-select-option value="deprecated">已下架</a-select-option>
          </a-select>
          <a-input-search
            v-model:value="searchKeyword"
            placeholder="搜索应用名称"
            style="width: 200px"
            @search="loadApps"
          />
        </a-space>
      </div>

      <a-table
        :columns="columns"
        :data-source="apps"
        :loading="loading"
        :pagination="pagination"
        row-key="productId"
        @change="handleTableChange"
      >
        <template #bodyCell="{ column, record }">
          <!-- 应用信息 -->
          <template v-if="column.key === 'appInfo'">
            <div class="app-info-cell">
              <img v-if="record.icon" :src="record.icon" class="app-icon" />
              <div v-else class="app-icon-placeholder" :style="{ background: iconBgColor(record.productName) }">
                {{ (record.productName || 'A').charAt(0).toUpperCase() }}
              </div>
              <div class="app-info-text">
                <div class="app-name">{{ record.productName }}</div>
                <div class="app-code">{{ record.productCode }}</div>
                <div class="app-developer" v-if="record.developer">
                  <UserOutlined style="font-size:11px;margin-right:3px" />{{ record.developer }}
                </div>
              </div>
            </div>
          </template>

          <!-- 应用类型 -->
          <template v-if="column.key === 'appType'">
            <a-tag color="blue">{{ APP_TYPE_NAME[record.appType ?? 10] || '未知' }}</a-tag>
          </template>

          <!-- 发布状态 -->
          <template v-if="column.key === 'publishStatus'">
            <a-tag :color="statusColor(record.publishStatus)">
              {{ statusText(record.publishStatus) }}
            </a-tag>
          </template>

          <!-- 定价 -->
          <template v-if="column.key === 'price'">
            <span v-if="record.priceType === 'free' || !record.priceType" class="price-free">免费</span>
            <span v-else class="price-paid">¥{{ ((record.price || 0) / 100).toFixed(2) }}
              <span class="price-period">{{ subscriptionText(record.subscriptionPeriod) }}</span>
            </span>
          </template>

          <!-- 申请时间 -->
          <template v-if="column.key === 'applyTime'">
            <span class="text-sm text-gray-500">{{ record.publishTime || record.updateTime || '-' }}</span>
          </template>

          <!-- 操作 -->
          <template v-if="column.key === 'action'">
            <a-space>
              <a-button type="link" size="small" @click="handleViewDetail(record)">详情</a-button>
              <!-- 待审核：通过/拒绝 -->
              <template v-if="record.publishStatus === 'pending_review'">
                <a-popconfirm title="确认通过此应用上架申请？" @confirm="handleApprove(record)">
                  <a-button type="primary" size="small">通过</a-button>
                </a-popconfirm>
                <a-button danger size="small" @click="handleReject(record)">拒绝</a-button>
              </template>
              <!-- 已上架：下架 -->
              <a-popconfirm
                v-if="record.publishStatus === 'published'"
                title="确认下架此应用？"
                @confirm="handleAdminUnpublish(record)"
              >
                <a-button danger size="small">下架</a-button>
              </a-popconfirm>
            </a-space>
          </template>
        </template>
      </a-table>
    </div>

    <!-- 审核详情弹窗 -->
    <a-modal
      v-model:open="showDetailModal"
      :title="`应用详情：${currentApp?.productName || ''}`"
      width="700px"
      :footer="null"
    >
      <template v-if="currentApp">
        <a-descriptions :column="2" bordered size="small">
          <a-descriptions-item label="应用名称">{{ currentApp.productName }}</a-descriptions-item>
          <a-descriptions-item label="应用标识">{{ currentApp.productCode }}</a-descriptions-item>
          <a-descriptions-item label="应用类型">
            <a-tag color="blue">{{ APP_TYPE_NAME[currentApp.appType ?? 10] || '未知' }}</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="开发者">{{ currentApp.developer || '-' }}</a-descriptions-item>
          <a-descriptions-item label="发布状态">
            <a-tag :color="statusColor(currentApp.publishStatus)">{{ statusText(currentApp.publishStatus) }}</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="定价模式">{{ priceTypeText(currentApp.priceType) }}</a-descriptions-item>
          <a-descriptions-item label="价格">
            <span v-if="currentApp.priceType === 'free' || !currentApp.priceType">免费</span>
            <span v-else>¥{{ ((currentApp.price || 0) / 100).toFixed(2) }}</span>
          </a-descriptions-item>
          <a-descriptions-item label="提交时间">{{ currentApp.publishTime || '-' }}</a-descriptions-item>
          <a-descriptions-item label="应用简介" :span="2">
            {{ currentApp.description || '-' }}
          </a-descriptions-item>
          <a-descriptions-item label="详细说明" :span="2">
            <div class="detail-desc">{{ currentApp.content || '-' }}</div>
          </a-descriptions-item>
          <a-descriptions-item v-if="currentApp.rejectReason" label="拒绝原因" :span="2">
            <a-alert type="error" :message="currentApp.rejectReason" show-icon />
          </a-descriptions-item>
        </a-descriptions>

        <!-- 应用入口信息 -->
        <div v-if="currentAppEntries.length > 0" class="entry-section">
          <h4 class="entry-title">🚀 应用入口</h4>
          <div class="entry-list">
            <div
              v-for="entry in currentAppEntries"
              :key="entry.type"
              class="entry-item"
              :class="{ disabled: !entry.available }"
            >
              <div class="entry-info">
                <component :is="entryIcon(entry.icon)" style="font-size: 18px; margin-right: 8px;" />
                <div>
                  <div class="entry-label">{{ entry.label }}</div>
                  <div class="entry-url" v-if="entry.url">{{ entry.type === 'scan-qr' ? '已配置小程序码' : entry.url }}</div>
                  <div class="entry-url text-gray-400" v-else>未配置</div>
                </div>
              </div>
              <a-button
                v-if="entry.available"
                type="primary"
                size="small"
                ghost
                @click="handleEntryClick(entry)"
              >
                {{ entry.type === 'visit-site' ? '访问' : entry.type === 'download' ? '下载' : entry.type === 'scan-qr' ? '扫码' : '进入' }}
              </a-button>
            </div>
          </div>
        </div>

        <!-- 待审核时的操作区 -->
        <div v-if="currentApp.publishStatus === 'pending_review'" class="detail-actions">
          <a-popconfirm title="确认通过此应用上架申请？" @confirm="handleApprove(currentApp)">
            <a-button type="primary" :loading="approving">✅ 审核通过</a-button>
          </a-popconfirm>
          <a-button danger @click="handleReject(currentApp)">❌ 拒绝上架</a-button>
        </div>
      </template>
    </a-modal>

    <!-- 拒绝原因弹窗 -->
    <a-modal
      v-model:open="showRejectModal"
      title="填写拒绝原因"
      :confirm-loading="rejecting"
      @ok="confirmReject"
      @cancel="showRejectModal = false"
    >
      <a-form layout="vertical">
        <a-form-item label="拒绝原因" required>
          <a-textarea
            v-model:value="rejectReasonInput"
            :rows="4"
            placeholder="请填写具体的拒绝原因，以便开发者修改后重新提交"
            :maxlength="500"
            show-count
          />
        </a-form-item>
        <div class="reject-tips">
          <p>💡 常见拒绝原因：</p>
          <a-space wrap>
            <a-tag
              v-for="tip in rejectTips"
              :key="tip"
              class="reject-tip-tag"
              @click="rejectReasonInput = tip"
            >{{ tip }}</a-tag>
          </a-space>
        </div>
      </a-form>
    </a-modal>

    <!-- 扫码弹窗 -->
    <QrCodeModal
      v-model:open="showQrModal"
      :title="qrModalTitle"
      :tip="qrModalTip"
      :image-url="qrModalUrl"
    />
  </div>
</template>

<script setup lang="ts">
import { ReloadOutlined, UserOutlined, GlobalOutlined, QrcodeOutlined, DownloadOutlined, SettingOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import {
  pagePublishReviews,
  approvePublishReview,
  rejectPublishReview,
  unpublishAppProduct,
} from '@/api/app/appProduct'
import type { AppProduct } from '@/api/app/appProduct/model'
import { APP_TYPE_NAME } from '@/api/app/appProduct/model'
import { getAppEntries, executeEntry, getScanTip } from '@/utils/appEntry'
import type { AppEntry } from '@/utils/appEntry'
import QrCodeModal from '@/components/QrCodeModal.vue'

definePageMeta({ layout: 'admin' })
useHead({ title: '应用审核管理 - 平台管理' })

// 加载状态
const loading = ref(false)
const apps = ref<AppProduct[]>([])

// 筛选
const filterStatus = ref('pending_review')
const searchKeyword = ref('')

// 分页
const pagination = reactive({
  current: 1,
  pageSize: 20,
  total: 0,
  showSizeChanger: true,
  showQuickJumper: true,
})

// 统计
const reviewStats = reactive([
  { key: 'pending_review', icon: '⏳', label: '待审核', value: 0, color: 'orange' },
  { key: 'published', icon: '✅', label: '已上架', value: 0, color: 'green' },
  { key: 'rejected', icon: '❌', label: '已拒绝', value: 0, color: 'red' },
  { key: '', icon: '📦', label: '全部应用', value: 0, color: 'blue' },
])

// 表格列
const columns = [
  { title: '应用信息', key: 'appInfo', width: 260 },
  { title: '应用类型', key: 'appType', width: 120 },
  { title: '审核状态', key: 'publishStatus', width: 110 },
  { title: '定价', key: 'price', width: 130 },
  { title: '提交时间', key: 'applyTime', width: 160 },
  { title: '操作', key: 'action', width: 200 },
]

// 详情弹窗
const showDetailModal = ref(false)
const currentApp = ref<AppProduct | null>(null)
const approving = ref(false)

// 拒绝弹窗
const showRejectModal = ref(false)
const rejectReasonInput = ref('')
const rejecting = ref(false)
const rejectTargetApp = ref<AppProduct | null>(null)

const rejectTips = [
  '功能描述不完整，缺少使用说明文档',
  '应用简介过于简单，请补充详细功能介绍',
  '应用名称与实际功能不符',
  '价格设置不合理，请重新评估',
  '存在违规内容，请修改后重新提交',
  '截图不清晰或与功能描述不符',
]

// 加载审核列表
async function loadApps() {
  loading.value = true
  try {
    const res = await pagePublishReviews({
      page: pagination.current,
      limit: pagination.pageSize,
      publishStatus: filterStatus.value || undefined,
      keywords: searchKeyword.value || undefined,
    })
    apps.value = res?.list || []
    pagination.total = res?.count || 0
    updateStats()
  } catch {
    message.error('加载审核列表失败')
  } finally {
    loading.value = false
  }
}

// 更新统计
async function updateStats() {
  try {
    const [pendingRes, publishedRes, rejectedRes, allRes] = await Promise.allSettled([
      pagePublishReviews({ page: 1, limit: 1, publishStatus: 'pending_review' }),
      pagePublishReviews({ page: 1, limit: 1, publishStatus: 'published' }),
      pagePublishReviews({ page: 1, limit: 1, publishStatus: 'rejected' }),
      pagePublishReviews({ page: 1, limit: 1 }),
    ])
    if (pendingRes.status === 'fulfilled') reviewStats[0].value = pendingRes.value?.count || 0
    if (publishedRes.status === 'fulfilled') reviewStats[1].value = publishedRes.value?.count || 0
    if (rejectedRes.status === 'fulfilled') reviewStats[2].value = rejectedRes.value?.count || 0
    if (allRes.status === 'fulfilled') reviewStats[3].value = allRes.value?.count || 0
  } catch { /* ignore */ }
}

// 统计卡片点击筛选
function handleStatFilter(key: string) {
  filterStatus.value = key
  pagination.current = 1
  loadApps()
}

// 分页变化
function handleTableChange(pag: any) {
  pagination.current = pag.current
  pagination.pageSize = pag.pageSize
  loadApps()
}

// 查看详情
function handleViewDetail(record: AppProduct) {
  currentApp.value = record
  showDetailModal.value = true
}

// 审核通过
async function handleApprove(record: AppProduct) {
  approving.value = true
  try {
    await approvePublishReview(record.productId!)
    message.success(`「${record.productName}」已通过审核并上架`)
    showDetailModal.value = false
    loadApps()
  } catch (e: any) {
    message.error(e?.message || '操作失败')
  } finally {
    approving.value = false
  }
}

// 打开拒绝弹窗
function handleReject(record: AppProduct) {
  rejectTargetApp.value = record
  rejectReasonInput.value = ''
  showRejectModal.value = true
}

// 确认拒绝
async function confirmReject() {
  if (!rejectReasonInput.value.trim()) {
    message.warning('请填写拒绝原因')
    return
  }
  if (!rejectTargetApp.value) return
  rejecting.value = true
  try {
    await rejectPublishReview({
      productId: rejectTargetApp.value.productId!,
      rejectReason: rejectReasonInput.value,
    })
    message.success('已拒绝并通知开发者')
    showRejectModal.value = false
    showDetailModal.value = false
    loadApps()
  } catch (e: any) {
    message.error(e?.message || '操作失败')
  } finally {
    rejecting.value = false
  }
}

// 管理员下架
async function handleAdminUnpublish(record: AppProduct) {
  try {
    await unpublishAppProduct(record.productId!)
    message.success(`「${record.productName}」已下架`)
    loadApps()
  } catch (e: any) {
    message.error(e?.message || '操作失败')
  }
}

// 状态相关
function statusText(status?: string) {
  const map: Record<string, string> = {
    developing: '开发中',
    pending_review: '待审核',
    published: '已上架',
    rejected: '已拒绝',
    deprecated: '已下架',
  }
  return map[status || ''] || '开发中'
}

function statusColor(status?: string) {
  const map: Record<string, string> = {
    developing: 'default',
    pending_review: 'orange',
    published: 'success',
    rejected: 'error',
    deprecated: 'default',
  }
  return map[status || ''] || 'default'
}

function priceTypeText(type?: string) {
  const map: Record<string, string> = {
    free: '免费',
    one_time: '一次性付费',
    subscription: '订阅制',
  }
  return map[type || ''] || '免费'
}

function subscriptionText(period?: string) {
  if (period === 'month') return '/月'
  if (period === 'year') return '/年'
  return ''
}

const PALETTE = ['#4e6ef2', '#f4a261', '#e76f51', '#2a9d8f', '#e9c46a', '#457b9d']
function iconBgColor(name?: string) {
  if (!name) return PALETTE[0]
  let h = 0
  for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) & 0xffffffff
  return PALETTE[Math.abs(h) % PALETTE.length]
}

const showQrModal = ref(false)
const qrModalTitle = ref('')
const qrModalTip = ref('')
const qrModalUrl = ref('')

const currentAppEntries = computed(() => {
  if (!currentApp.value) return []
  return getAppEntries(currentApp.value)
})

function entryIcon(iconName: string) {
  const map: Record<string, any> = {
    GlobalOutlined,
    QrcodeOutlined,
    DownloadOutlined,
    SettingOutlined,
  }
  return map[iconName] || GlobalOutlined
}

function handleEntryClick(entry: AppEntry) {
  const needQr = executeEntry(entry)
  if (needQr && entry.type === 'scan-qr' && currentApp.value) {
    qrModalTitle.value = currentApp.value.productName || '小程序码'
    qrModalTip.value = getScanTip(currentApp.value.appType || 20)
    qrModalUrl.value = entry.url || ''
    showQrModal.value = true
  }
}

onMounted(() => {
  loadApps()
})
</script>

<style scoped>
.review-page {
  min-height: 100%;
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.page-title {
  font-size: 18px;
  font-weight: 700;
  color: #1f2937;
  margin: 0;
  line-height: 1.4;
}

.page-desc {
  font-size: 13px;
  color: #9ca3af;
  margin: 2px 0 0;
}

/* 统计卡片 */
.stat-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  border-radius: 12px;
  border: 2px solid transparent;
  cursor: pointer;
  transition: all 0.2s;
}

.stat-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.stat-card.active { border-color: currentColor; box-shadow: 0 4px 12px rgba(0,0,0,0.12); }

.stat-card.blue { background: #eff6ff; border-color: #dbeafe; }
.stat-card.orange { background: #fff7ed; border-color: #fed7aa; }
.stat-card.green { background: #f0fdf4; border-color: #bbf7d0; }
.stat-card.red { background: #fff1f2; border-color: #fecdd3; }

.stat-card.active.blue { border-color: #3b82f6; }
.stat-card.active.orange { border-color: #f97316; }
.stat-card.active.green { border-color: #22c55e; }
.stat-card.active.red { border-color: #ef4444; }

.stat-icon { font-size: 28px; flex-shrink: 0; }

.stat-value {
  font-size: 22px;
  font-weight: 700;
  color: rgba(0, 0, 0, 0.85);
  line-height: 1.2;
}

.stat-label {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
  margin-top: 2px;
}

/* 面板 */
.panel {
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 12px;
  overflow: hidden;
}

.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid #f5f5f5;
}

.panel-title {
  font-size: 14px;
  font-weight: 600;
  color: rgba(0, 0, 0, 0.85);
}

/* 应用信息格 */
.app-info-cell {
  display: flex;
  align-items: center;
  gap: 12px;
}

.app-icon {
  width: 44px;
  height: 44px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
}

.app-icon-placeholder {
  width: 44px;
  height: 44px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  font-weight: 600;
  color: #fff;
  flex-shrink: 0;
}

.app-info-text { flex: 1; min-width: 0; }

.app-name {
  font-size: 14px;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.85);
}

.app-code {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
}

.app-developer {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
  margin-top: 2px;
}

/* 价格 */
.price-free { color: #22c55e; font-weight: 500; font-size: 13px; }
.price-paid { color: #f59e0b; font-weight: 600; font-size: 14px; }
.price-period { font-size: 11px; color: rgba(0,0,0,0.45); font-weight: 400; margin-left: 2px; }

/* 详情弹窗 */
.detail-actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid #f0f0f0;
}

.detail-desc {
  max-height: 200px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

/* 拒绝原因提示 */
.reject-tips {
  margin-top: 12px;
  padding: 12px;
  background: #fafafa;
  border-radius: 8px;
}

.reject-tips p {
  font-size: 12px;
  color: rgba(0,0,0,0.45);
  margin: 0 0 8px;
}

.reject-tip-tag {
  cursor: pointer;
  transition: all 0.15s;
}

.reject-tip-tag:hover {
  color: #4f46e5;
  border-color: #4f46e5;
}

.mb-6 { margin-bottom: 24px; }
.text-sm { font-size: 12px; }
.text-gray-500 { color: rgba(0,0,0,0.45); }
.text-gray-400 { color: #9ca3af; }

.entry-section {
  margin-top: 20px;
  padding: 16px;
  background: #fafafa;
  border-radius: 8px;
  border: 1px solid #f0f0f0;
}

.entry-title {
  font-size: 14px;
  font-weight: 600;
  color: rgba(0,0,0,0.85);
  margin: 0 0 12px;
}

.entry-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.entry-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  background: #fff;
  border-radius: 8px;
  border: 1px solid #f0f0f0;
  transition: all 0.2s;
}

.entry-item:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.entry-item.disabled { opacity: 0.5; }

.entry-info {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.entry-label {
  font-size: 14px;
  font-weight: 500;
  color: rgba(0,0,0,0.85);
}

.entry-url {
  font-size: 12px;
  color: rgba(0,0,0,0.45);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 400px;
}
</style>
