<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { showDialog, showToast } from 'vant'

import {
  fetchSellerListing,
  offlineListing,
  submitListingReview,
  type Listing,
} from '@/features/listings'
import AuthImage from '@/shared/components/business/AuthImage.vue'
import { formatCent, formatMoney, formatMoneyWithSymbol } from '@/shared/utils/money'
import { listingReviewStatusLabel, listingStatusLabel } from '@/shared/utils/statusLabels'
import {
  assetRegions,
  formatAssetNumber,
  formatEstimatedRentalDuration,
  formatHafCoinM,
  formatListingCode,
  formatRatio,
  getCoinWan,
  getDailyLoss,
  getListingChips,
  getListingResources,
  getListingSellerPrice,
  getListingSubtitle,
  getListingTitle,
  getLoginMethod,
  getOnlineTimeText,
  getServerRegion,
  readAssetNumber,
  readAssetString,
} from '@/shared/utils/listingDisplay'
import { readError } from '@/shared/utils/error'
import { formatDateTime } from '@/shared/utils/time'

const route = useRoute()
const router = useRouter()
const loading = ref(false)
const acting = ref(false)
const listing = ref<Listing | null>(null)

onMounted(load)

async function load() {
  loading.value = true
  try {
    listing.value = await fetchSellerListing(String(route.params.id))
  } catch (error) {
    showToast({ message: readError(error, '加载失败，仅能查看自己的商品'), icon: 'cross' })
    listing.value = null
  } finally {
    loading.value = false
  }
}

const sellerPrice = computed(() =>
  listing.value ? formatMoneyWithSymbol(getListingSellerPrice(listing.value)) : '—'
)

const detailMetrics = computed(() => {
  if (!listing.value) return []
  const dailyLoss = getDailyLoss(listing.value)
  const secretKD = readAssetNumber(listing.value, 'secret_kd')
  return [
    { label: '纯币', value: formatHafCoinM(getCoinWan(listing.value)) },
    {
      label: '绝密KD',
      value: secretKD > 0 ? formatAssetNumber(secretKD) : '--',
    },
    { label: '日损耗', value: dailyLoss ? `${dailyLoss}/天` : '--' },
    { label: '价格', value: sellerPrice.value, tone: 'price' },
    { label: '押金', value: `¥${formatCent(listing.value.deposit_amount_cent)}` },
  ]
})

const detailScreenshots = computed(() => {
  if (!listing.value) return []
  const groups = listing.value.asset_summary?.screenshot_groups
  if (typeof groups === 'object' && groups !== null) {
    const slots = [
      { key: 'coin', label: '纯币截图' },
      { key: 'gameId', label: '游戏ID截图' },
      { key: 'totalAsset', label: '总资产截图' },
      { key: 'tencentSecurity', label: '腾讯安全中心截图' },
      { key: 'skin', label: '皮肤截图' },
    ]
    return slots.flatMap(slot => {
      const urls = (groups as Record<string, unknown>)[slot.key]
      if (!Array.isArray(urls)) return []
      const valid = urls.filter((u): u is string => typeof u === 'string' && Boolean(u))
      return valid.map((url, i) => ({
        label: valid.length > 1 ? `${slot.label}${i + 1}` : slot.label,
        url,
      }))
    })
  }
  const labels = ['纯币截图', '游戏ID截图', '总资产截图', '腾讯安全中心截图', '皮肤截图']
  return (listing.value.screenshot_urls || []).map((url, index) => ({
    label: labels[index] || `账号截图${index + 1}`,
    url,
  }))
})
const detailScreenshotUrls = computed(() => detailScreenshots.value.map(s => s.url))

const detailSkinGroups = computed(() => {
  if (!listing.value) return []
  const groups = listing.value.asset_summary?.skin_groups
  if (typeof groups !== 'object' || groups === null) return []
  const titles: Record<string, string> = {
    melee: '近战皮肤',
    operator: '干员皮肤',
    operatorGold: '干员金皮',
    operatorRed: '干员红皮',
    weapon: '武器皮肤',
  }
  return Object.entries(groups as Record<string, unknown>)
    .map(([key, value]) => ({
      key,
      title: titles[key] || key,
      options: Array.isArray(value)
        ? value.filter((skin): skin is string => typeof skin === 'string')
        : [],
    }))
    .filter(g => g.options.length)
})

const accountRows = computed(() => {
  if (!listing.value) return []
  const regions = assetRegions(listing.value)
  const secretKD = readAssetNumber(listing.value, 'secret_kd')
  const fireLevel = readAssetNumber(listing.value, 'fire_level')
  return [
    { label: '所属区服', value: getServerRegion(listing.value) || '--' },
    { label: '上号方式', value: getLoginMethod(listing.value) || '--' },
    { label: '游戏段位', value: listing.value.rank_level || '--' },
    { label: '烽火等级', value: fireLevel > 0 ? `${fireLevel}级` : '--' },
    { label: '体力等级', value: readAssetString(listing.value, 'stamina_level') || '--' },
    { label: '负重等级', value: readAssetString(listing.value, 'load_level') || '--' },
    { label: '绝密KD', value: secretKD > 0 ? formatAssetNumber(secretKD) : '--' },
    { label: 'M单价', value: formatRatio(listing.value) },
    { label: '方便上号', value: getOnlineTimeText(listing.value) || '--' },
    { label: '预计可租', value: formatEstimatedRentalDuration(listing.value) },
    { label: '常用登录地', value: regions.length ? regions.join('、') : '--' },
    { label: '封禁记录', value: readAssetString(listing.value, 'ban_record') || '无' },
  ]
})

function isTerminal(row: Listing) {
  return row.status === 'rented' || row.status === 'completed'
}
function isPendingReview(row: Listing) {
  return !isTerminal(row) && row.status !== 'offline' && row.review_status === 'pending'
}
function canEdit(row: Listing) {
  return !isTerminal(row) && !isPendingReview(row) && row.status !== 'published'
}
function canSubmit(row: Listing) {
  return !isTerminal(row) && !isPendingReview(row) && row.status !== 'published'
}
function canOffline(row: Listing) {
  return !isTerminal(row) && row.status !== 'offline'
}

async function copyCode() {
  if (!listing.value) return
  try {
    await navigator.clipboard.writeText(formatListingCode(listing.value))
    showToast({ message: '商品编号已复制', icon: 'passed' })
  } catch {
    showToast({ message: '复制失败', icon: 'cross' })
  }
}

function goEdit() {
  if (!listing.value) return
  router.push(`/m/seller/listings/${listing.value.id}/edit`)
}

async function handleSubmit() {
  if (!listing.value) return
  acting.value = true
  try {
    listing.value = await submitListingReview(listing.value.id)
    showToast({
      message:
        listing.value.status === 'published' && listing.value.review_status === 'approved'
          ? '已上架'
          : '已提交审核',
      icon: 'passed',
    })
  } catch (error) {
    showToast({ message: readError(error, '提审失败'), icon: 'cross' })
  } finally {
    acting.value = false
  }
}

async function handleOffline() {
  if (!listing.value) return
  try {
    await showDialog({
      title: '下架确认',
      message: `确认下架「${listing.value.title}」吗？`,
      showCancelButton: true,
      confirmButtonText: '确认下架',
    })
  } catch {
    return
  }
  acting.value = true
  try {
    listing.value = await offlineListing(listing.value.id)
    showToast({ message: '已下架', icon: 'passed' })
  } catch (error) {
    showToast({ message: readError(error, '下架失败'), icon: 'cross' })
  } finally {
    acting.value = false
  }
}
</script>

<template>
  <main class="seller-detail">
    <header class="page-header">
      <button type="button" class="icon-btn" @click="router.back()">
        <van-icon name="arrow-left" :size="20" />
      </button>
      <h1>商品详情</h1>
      <span class="icon-btn" />
    </header>

    <van-loading v-if="loading" class="center-loading" size="24px" vertical>加载中...</van-loading>

    <template v-else-if="listing">
      <div class="status-bar">
        <button type="button" class="code-chip" @click="copyCode">
          编号 {{ formatListingCode(listing) }}
          <van-icon name="description" :size="12" />
        </button>
        <div class="tags">
          <span class="tag">{{ listingStatusLabel(listing.status) }}</span>
          <span v-if="listing.review_status && listing.review_status !== 'none'" class="tag soft">
            {{ listingReviewStatusLabel(listing.review_status) }}
          </span>
        </div>
      </div>

      <div v-if="detailScreenshots[0]" class="cover-area">
        <AuthImage
          :source="detailScreenshots[0].url"
          :alt="getListingTitle(listing)"
          image-class="cover-img"
          fit="cover"
          :preview-src-list="detailScreenshotUrls"
        />
      </div>

      <section class="card">
        <h2>{{ getListingTitle(listing) }}</h2>
        <p class="sub">{{ getListingSubtitle(listing) }}</p>
        <div class="tag-row">
          <van-tag plain type="primary" size="medium">{{ getServerRegion(listing) || '—' }}</van-tag>
          <van-tag v-if="getLoginMethod(listing)" plain type="primary" size="medium">
            {{ getLoginMethod(listing) }}
          </van-tag>
          <van-tag v-if="listing.rank_level" plain size="medium">{{ listing.rank_level }}</van-tag>
        </div>
        <p v-if="listing.review_reason" class="review-reason">
          <van-icon name="info-o" :size="13" />
          {{ listing.review_reason }}
        </p>
      </section>

      <section class="metric-row">
        <div v-for="m in detailMetrics" :key="m.label" class="metric">
          <span>{{ m.label }}</span>
          <strong :class="m.tone">{{ m.value }}</strong>
        </div>
      </section>

      <section class="card">
        <h3>账号资料</h3>
        <div class="chip-row">
          <span v-for="chip in getListingChips(listing)" :key="chip.label">
            {{ chip.label }}:{{ chip.value }}
          </span>
        </div>
        <div v-for="row in accountRows" :key="row.label" class="info-line">
          <span>{{ row.label }}</span>
          <em>{{ row.value }}</em>
        </div>
      </section>

      <section v-if="getListingResources(listing).length" class="card">
        <h3>额外消耗品</h3>
        <div class="resource-grid">
          <div v-for="r in getListingResources(listing)" :key="r.key" class="resource-pill">
            <span>{{ r.label }}</span>
            <strong>{{ r.quantity }}</strong>
            <small>
              {{ r.mode || '--' }}
              <template v-if="r.amount > 0"> · ¥{{ formatMoney(r.amount) }}</template>
            </small>
          </div>
        </div>
      </section>

      <section v-if="detailSkinGroups.length" class="card">
        <h3>皮肤</h3>
        <div v-for="g in detailSkinGroups" :key="g.key" class="skin-group">
          <p>{{ g.title }}</p>
          <div class="chip-row">
            <span v-for="skin in g.options" :key="skin">{{ skin }}</span>
          </div>
        </div>
      </section>

      <section v-if="listing.description" class="card">
        <h3>备注</h3>
        <p class="desc">{{ listing.description }}</p>
      </section>

      <section v-if="detailScreenshots.length" class="card">
        <h3>账号截图</h3>
        <div class="shot-grid">
          <figure v-for="(shot, index) in detailScreenshots" :key="shot.url + index">
            <AuthImage
              :source="shot.url"
              :alt="shot.label"
              image-class="shot-img"
              fit="cover"
              :preview-src-list="detailScreenshotUrls"
              :preview-initial-index="index"
            />
            <figcaption>{{ shot.label }}</figcaption>
          </figure>
        </div>
      </section>

      <section class="card">
        <h3>时间信息</h3>
        <div class="info-line">
          <span>创建时间</span>
          <em>{{ formatDateTime(listing.created_at) }}</em>
        </div>
        <div v-if="listing.published_at" class="info-line">
          <span>上架时间</span>
          <em>{{ formatDateTime(listing.published_at) }}</em>
        </div>
        <div class="info-line">
          <span>更新时间</span>
          <em>{{ formatDateTime(listing.updated_at) }}</em>
        </div>
      </section>

      <div class="bottom-spacer" />

      <footer class="action-bar">
        <van-button v-if="canEdit(listing)" plain round class="btn" @click="goEdit">编辑</van-button>
        <van-button
          v-if="canSubmit(listing)"
          type="primary"
          plain
          round
          class="btn"
          :loading="acting"
          @click="handleSubmit"
        >
          提审
        </van-button>
        <van-button
          v-if="canOffline(listing)"
          type="danger"
          plain
          round
          class="btn"
          :loading="acting"
          @click="handleOffline"
        >
          下架
        </van-button>
        <van-button plain round class="btn" @click="router.push('/m/seller/listings')">
          返回列表
        </van-button>
      </footer>
    </template>

    <div v-else class="empty">
      <van-empty description="未找到商品，或无权查看" />
      <van-button round type="primary" @click="router.push('/m/seller/listings')">
        返回我的商品
      </van-button>
    </div>
  </main>
</template>

<style scoped>
.seller-detail {
  min-height: 100dvh;
  background: #f5f7fa;
  padding-bottom: calc(72px + env(safe-area-inset-bottom));
}
.page-header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  height: 48px;
  padding: 0 12px;
  background: #fff;
  border-bottom: 1px solid #eee;
}
.page-header h1 {
  flex: 1;
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  text-align: center;
}
.icon-btn {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  color: #333;
}
.center-loading {
  padding: 60px 0;
  display: flex;
  justify-content: center;
}
.status-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 12px 14px 0;
}
.code-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 0;
  border-radius: 999px;
  padding: 4px 10px;
  background: #fff7ed;
  color: #c2410c;
  font-size: 12px;
  font-weight: 600;
}
.tags {
  display: flex;
  gap: 6px;
}
.tag {
  padding: 2px 8px;
  border-radius: 999px;
  background: #ecfdf5;
  color: #047857;
  font-size: 11px;
  font-weight: 600;
}
.tag.soft {
  background: #eff6ff;
  color: #1d4ed8;
}
.cover-area {
  margin: 12px 14px 0;
  height: 180px;
  border-radius: 12px;
  overflow: hidden;
  background: #e5e7eb;
}
.cover-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card {
  margin: 12px 14px 0;
  padding: 14px;
  border-radius: 12px;
  background: #fff;
}
.card h2 {
  margin: 0 0 6px;
  font-size: 17px;
  color: #111827;
}
.card h3 {
  margin: 0 0 10px;
  font-size: 14px;
  color: #111827;
}
.sub,
.desc {
  margin: 0;
  color: #6b7280;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
}
.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}
.review-reason {
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: 8px;
  background: #fff7ed;
  color: #c2410c;
  font-size: 12px;
  display: flex;
  gap: 6px;
  align-items: flex-start;
}
.metric-row {
  margin: 12px 14px 0;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 6px;
  padding: 12px 8px;
  border-radius: 12px;
  background: #fff;
}
.metric {
  display: grid;
  gap: 4px;
  text-align: center;
}
.metric span {
  font-size: 11px;
  color: #94a3b8;
}
.metric strong {
  font-size: 12px;
  color: #111827;
  word-break: break-all;
}
.metric strong.price {
  color: #ff6a00;
}
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}
.chip-row span {
  padding: 4px 8px;
  border-radius: 999px;
  background: #f3f4f6;
  color: #374151;
  font-size: 12px;
}
.info-line {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid #f3f4f6;
  font-size: 13px;
}
.info-line:last-child {
  border-bottom: 0;
}
.info-line span {
  color: #94a3b8;
  flex-shrink: 0;
}
.info-line em {
  font-style: normal;
  color: #111827;
  text-align: right;
}
.resource-grid {
  display: grid;
  gap: 8px;
}
.resource-pill {
  display: grid;
  gap: 2px;
  padding: 10px;
  border-radius: 10px;
  background: #f8fafc;
}
.resource-pill span {
  font-size: 12px;
  color: #64748b;
}
.resource-pill strong {
  font-size: 14px;
  color: #0f172a;
}
.resource-pill small {
  color: #94a3b8;
}
.skin-group {
  margin-bottom: 10px;
}
.skin-group p {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 600;
  color: #334155;
}
.shot-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.shot-grid figure {
  margin: 0;
}
.shot-img {
  width: 100%;
  height: 110px;
  border-radius: 8px;
  object-fit: cover;
  background: #e5e7eb;
}
.shot-grid figcaption {
  margin-top: 4px;
  font-size: 11px;
  color: #94a3b8;
  text-align: center;
}
.bottom-spacer {
  height: 16px;
}
.action-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  display: flex;
  gap: 8px;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.96);
  border-top: 1px solid #eef1f5;
  backdrop-filter: blur(8px);
}
.action-bar .btn {
  flex: 1;
}
.empty {
  padding: 40px 20px;
  display: grid;
  gap: 12px;
  justify-items: center;
}
</style>
