<template>
  <scroll-view class="page" scroll-y>
    <view class="banner" v-if="detail.banner">
      <image class="banner-img" :src="detail.banner" mode="widthFix" />
    </view>
    <view class="header">
      <view class="title">{{ detail.name || detail.title || '-' }}</view>
      <view class="meta" v-if="detail.price_draw !== undefined">参与价：￥{{ (Number(detail.price_draw || 0) / 100).toFixed(2) }}</view>
    </view>
    
    <view class="issues" v-if="showIssues">
      <view class="issues-title">期数</view>
      <view v-if="issues.length" class="issues-list">
        <picker-view class="issue-picker" :value="[selectedIssueIndex]" @change="onIssueChange">
          <picker-view-column>
            <view class="picker-item" v-for="it in issues" :key="it.id">{{ it.title || ('第' + (it.no || it.index || it.issue_no || '-') + '期') }}</view>
          </picker-view-column>
        </picker-view>

        <view class="tabs">
          <view class="tab" :class="{ active: tabActive === 'pool' }" @click="tabActive = 'pool'">本机奖池</view>
          <view class="tab" :class="{ active: tabActive === 'records' }" @click="tabActive = 'records'">中奖记录</view>
        </view>

        <view v-show="tabActive === 'pool'">
          <view class="rewards" v-if="currentIssueId && rewardsMap[currentIssueId] && rewardsMap[currentIssueId].length">
            <el-card v-for="rw in rewardsMap[currentIssueId]" :key="rw.id" class="el-reward-card" shadow="hover">
              <template #header>
                <view class="el-card-header">
                  <text class="el-card-title">{{ rw.title }}</text>
                  <text v-if="rw.boss" class="badge-boss">BOSS</text>
                </view>
              </template>
              <view class="card-image-wrap">
                <image v-if="rw.image" class="card-image" :src="rw.image" mode="widthFix" />
                <text class="prob-corner tl">概率 {{ rw.percent }}%</text>
              </view>
            </el-card>
          </view>
          <view class="rewards-empty" v-else>暂无奖励配置</view>
        </view>

        <view v-show="tabActive === 'records'">
          <view class="records" v-if="winRecords.length">
            <el-card v-for="it in winRecords" :key="it.id" class="el-reward-card" shadow="hover">
              <template #header>
                <view class="el-card-header">
                  <text class="el-card-title">{{ it.title }}</text>
                  <text v-if="it.count !== undefined" class="badge-count">x{{ it.count }}</text>
                </view>
              </template>
              <view class="card-image-wrap">
                <image v-if="it.image" class="card-image" :src="it.image" mode="widthFix" />
                <text v-if="it.percent !== undefined" class="prob-corner tl">占比 {{ it.percent }}%</text>
              </view>
            </el-card>
          </view>
          <view class="rewards-empty" v-else>暂无中奖记录</view>
        </view>
      </view>
      <view v-else class="issues-empty">暂无期数</view>
    </view>
  </scroll-view>
  <view class="float-actions">
    <button class="float-btn primary" @click="onParticipate">立即参与</button>
  </view>
</template>

<script setup>
import { ref, computed, getCurrentInstance } from 'vue'
import ElCard from '../../../components/ElCard.vue'
import { onLoad } from '@dcloudio/uni-app'
import { getActivityDetail, getActivityIssues, getActivityIssueRewards, drawActivityIssue, getActivityWinRecords } from '../../../api/appUser'

const detail = ref({})
const statusText = ref('')
const issues = ref([])
const rewardsMap = ref({})
const currentIssueId = ref('')
const selectedIssueIndex = ref(0)
const showIssues = computed(() => (detail.value && detail.value.status !== 2))
const activityId = ref('')
const tabActive = ref('pool')
const winRecords = ref([])

function statusToText(s) {
  if (s === 1) return '进行中'
  if (s === 0) return '未开始'
  if (s === 2) return '已结束'
  return String(s || '')
}

async function fetchDetail(id) {
  const data = await getActivityDetail(id)
  detail.value = data || {}
  statusText.value = statusToText(detail.value.status)
}

function unwrap(list) {
  if (Array.isArray(list)) return list
  const obj = list || {}
  const data = obj.data || {}
  const arr = obj.list || obj.items || data.list || data.items || data
  return Array.isArray(arr) ? arr : []
}

function cleanUrl(u) {
  const s = String(u || '').trim()
  const m = s.match(/https?:\/\/[^\s'"`]+/)
  if (m && m[0]) return m[0]
  return s.replace(/[`'\"]/g, '').trim()
}

function truthy(v) {
  if (typeof v === 'boolean') return v
  const s = String(v || '').trim().toLowerCase()
  if (!s) return false
  return s === '1' || s === 'true' || s === 'yes' || s === 'y' || s === '是' || s === 'boss是真的' || s === 'boss' || s === '大boss'
}
function detectBoss(i) {
  return truthy(i.is_boss) || truthy(i.boss) || truthy(i.isBoss) || truthy(i.boss_true) || truthy(i.boss_is_true) || truthy(i.bossText) || truthy(i.tag)
}

function normalizeIssues(list) {
  const arr = unwrap(list)
  return arr.map((i, idx) => ({
    id: i.id ?? String(idx),
    title: i.title ?? i.name ?? '',
    no: i.no ?? i.index ?? i.issue_no ?? i.issue_number ?? null,
    status_text: i.status_text ?? (i.status === 1 ? '进行中' : i.status === 0 ? '未开始' : i.status === 2 ? '已结束' : '')
  }))
}
function normalizeRewards(list) {
  const arr = unwrap(list)
  const items = arr.map((i, idx) => ({
    id: i.product_id ?? i.id ?? String(idx),
    title: i.name ?? i.title ?? '',
    image: cleanUrl(i.product_image ?? i.image ?? i.img ?? i.pic ?? i.banner ?? ''),
    weight: Number(i.weight) || 0,
    boss: detectBoss(i)
  }))
  const total = items.reduce((acc, it) => acc + (it.weight > 0 ? it.weight : 0), 0)
  const enriched = items.map(it => ({
    ...it,
    percent: total > 0 ? Math.round((it.weight / total) * 1000) / 10 : 0
  }))
  enriched.sort((a, b) => (b.percent - a.percent))
  return enriched
}
function normalizeWinRecords(list) {
  const arr = unwrap(list)
  return arr.map((i, idx) => ({
    id: i.id ?? i.record_id ?? i.product_id ?? String(idx),
    title: i.title ?? i.name ?? i.product_name ?? '',
    image: cleanUrl(i.image ?? i.img ?? i.pic ?? i.product_image ?? ''),
    count: Number(i.count ?? i.total ?? i.qty ?? 1) || 1,
    percent: i.percent !== undefined ? Math.round(Number(i.percent) * 10) / 10 : undefined
  }))
}
function isFresh(ts) {
  const now = Date.now()
  const v = Number(ts || 0)
  return now - v < 24 * 60 * 60 * 1000
}
function getRewardCache() {
  const obj = uni.getStorageSync('reward_cache_v1') || {}
  return typeof obj === 'object' && obj ? obj : {}
}
async function fetchRewardsForIssues(activityId) {
  const list = issues.value || []
  const cache = getRewardCache()
  const act = cache[activityId] || {}
  const toFetch = []
  list.forEach(it => {
    const c = act[it.id]
    if (c && isFresh(c.ts) && Array.isArray(c.value)) {
      rewardsMap.value = { ...(rewardsMap.value || {}), [it.id]: c.value }
    } else {
      toFetch.push(it)
    }
  })
  if (!toFetch.length) return
  const promises = toFetch.map(it => getActivityIssueRewards(activityId, it.id))
  const results = await Promise.allSettled(promises)
  const nextAct = { ...act }
  results.forEach((res, i) => {
    const issueId = toFetch[i] && toFetch[i].id
    if (!issueId) return
    const value = res.status === 'fulfilled' ? normalizeRewards(res.value) : []
    rewardsMap.value = { ...(rewardsMap.value || {}), [issueId]: value }
    nextAct[issueId] = { value, ts: Date.now() }
  })
  cache[activityId] = nextAct
  uni.setStorageSync('reward_cache_v1', cache)
}

async function fetchIssues(id) {
  const data = await getActivityIssues(id)
  issues.value = normalizeIssues(data)
  const latestId = pickLatestIssueId(issues.value)
  setSelectedById(latestId)
  await fetchRewardsForIssues(id)
}

async function fetchWinRecords(activityId) {
  try {
    const data = await getActivityWinRecords(activityId, 1, 50)
    winRecords.value = normalizeWinRecords(data)
  } catch (e) {
    winRecords.value = []
  }
}

function pickLatestIssueId(list) {
  const arr = Array.isArray(list) ? list : []
  let latest = arr[arr.length - 1] && arr[arr.length - 1].id
  let maxNo = -Infinity
  arr.forEach(i => {
    const n = Number(i.no)
    if (!Number.isNaN(n) && Number.isFinite(n) && n > maxNo) {
      maxNo = n
      latest = i.id
    }
  })
  return latest || (arr[0] && arr[0].id) || ''
}
function setSelectedById(id) {
  const arr = issues.value || []
  const idx = Math.max(0, arr.findIndex(x => x && x.id === id))
  selectedIssueIndex.value = idx
  const cur = arr[idx]
  currentIssueId.value = (cur && cur.id) || ''
}
function onIssueChange(e) {
  const v = e && e.detail && e.detail.value
  const idx = Array.isArray(v) ? (v[0] || 0) : 0
  const arr = issues.value || []
  const bounded = Math.min(Math.max(0, idx), arr.length - 1)
  selectedIssueIndex.value = bounded
  const cur = arr[bounded]
  currentIssueId.value = (cur && cur.id) || ''
}

async function ensureElCard() {
  const inst = getCurrentInstance()
  const app = inst && inst.appContext && inst.appContext.app
  let comp = null
  if (typeof window !== 'undefined' && window.ElementPlus && window.ElementPlus.ElCard) {
    comp = window.ElementPlus.ElCard
  } else {
    comp = ElCard
  }
  if (app && !app.component('el-card')) app.component('el-card', comp)
}




function onPreviewBanner() {
  const url = detail.value.banner || ''
  if (url) uni.previewImage({ urls: [url], current: url })
}

function onParticipate() {
  const aid = activityId.value || ''
  const iid = currentIssueId.value || ''
  if (!aid || !iid) { uni.showToast({ title: '期数未选择', icon: 'none' }); return }
  uni.showLoading({ title: '抽选中...' })
  drawActivityIssue(aid, iid).then(res => {
    try { uni.hideLoading() } catch (_) {}
    const obj = res || {}
    const data = obj.data || obj.result || obj.reward || obj.item || obj
    const name = String((data && (data.title || data.name || data.product_name)) || '未知奖励')
    const img = String((data && (data.image || data.img || data.pic || data.product_image)) || '')
    uni.showModal({ title: '抽选结果', content: '恭喜获得：' + name, showCancel: false, success: () => { if (img) uni.previewImage({ urls: [img], current: img }) } })
  }).catch(err => {
    try { uni.hideLoading() } catch (_) {}
    const msg = String((err && (err.message || err.msg)) || '抽选失败')
    uni.showToast({ title: msg, icon: 'none' })
  })
}

onLoad((opts) => {
  const id = (opts && opts.id) || ''
  if (id) {
    activityId.value = id
    fetchDetail(id)
    fetchIssues(id)
    fetchWinRecords(id)
  }
  ensureElCard()
})
</script>

<style scoped>
/* 奇盒潮玩 - 对对碰活动页面 */
.page { height: 100vh; padding-bottom: 140rpx; background: linear-gradient(180deg, #FFF8F3 0%, #FFFFFF 100%); }
.banner { padding: 24rpx }
.banner-img { width: 100%; border-radius: 20rpx; box-shadow: 0 12rpx 32rpx rgba(0, 0, 0, 0.1); }
.header { padding: 0 24rpx }
.title { font-size: 40rpx; font-weight: 800; background: linear-gradient(135deg, #FF6B35, #FF9F43); -webkit-background-clip: text; -webkit-text-fill-color: transparent; text-align: center; }
.meta { margin-top: 12rpx; font-size: 28rpx; color: #6B7280; text-align: center; }
.actions { display: flex; padding: 24rpx; gap: 16rpx }
.btn { flex: 1 }
.primary { background: linear-gradient(135deg, #FF9F43, #FF6B35) !important; color: #fff !important; box-shadow: 0 6rpx 20rpx rgba(255, 107, 53, 0.35); }
.float-actions { position: fixed; left: 0; right: 0; bottom: 0; padding: 20rpx 24rpx; padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(20rpx); box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.08); z-index: 9999 }
.float-btn { width: 100%; border-radius: 999rpx; background: linear-gradient(135deg, #FF9F43, #FF6B35) !important; color: #fff !important; font-weight: 600; box-shadow: 0 8rpx 24rpx rgba(255, 107, 53, 0.35); }
.issues { background: #FFFFFF; border-radius: 20rpx; margin: 0 24rpx 24rpx; padding: 20rpx; box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06); }
.issues-title { font-size: 32rpx; font-weight: 700; color: #1F2937; margin-bottom: 16rpx; padding-left: 16rpx; position: relative; }
.issues-title::before { content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 6rpx; height: 28rpx; background: linear-gradient(180deg, #FF9F43, #FF6B35); border-radius: 999rpx; }
.issue-picker { height: 200rpx; background: linear-gradient(145deg, #FFF8F3, #FFF4E6); border-radius: 16rpx; margin-bottom: 64rpx }
.picker-item { height: 40rpx; line-height: 40rpx; text-align: center; font-size: 28rpx; color: #1F2937; }
.tabs { display: flex; padding: 0 12rpx; margin-bottom: 20rpx; gap: 12rpx; }
.tab { flex: 1; text-align: center; font-size: 28rpx; padding: 18rpx 0; border: 2rpx solid rgba(255, 159, 67, 0.3); color: #B45309; background: linear-gradient(145deg, #FFFFFF, #FFF8F3); border-radius: 16rpx; font-weight: 500; transition: all 0.2s ease; }
.tab.active { background: linear-gradient(135deg, #FF9F43, #FF6B35); border-color: #FF6B35; color: #fff; font-weight: 600; box-shadow: 0 6rpx 16rpx rgba(255, 107, 53, 0.3); }
.rewards { width: 100%; margin-top: 24rpx }
.reward-card { background: #FFFFFF; border-radius: 16rpx; overflow: hidden; box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06); margin-bottom: 16rpx }
.el-reward-card { margin-bottom: 16rpx }
.el-card-header { display: flex; align-items: center; justify-content: space-between }
.el-card-title { font-size: 28rpx; color: #1F2937; flex: 1; margin-right: 8rpx; word-break: break-all; font-weight: 600; }
.card-image-wrap { position: relative; padding-bottom: 48rpx }
.card-image { width: 100%; height: auto; display: block; background: linear-gradient(145deg, #FFF8F3, #FFF4E6); position: relative; z-index: 1 }
.prob-corner { position: absolute; background: linear-gradient(135deg, #FF6B35, #FF9F43); color: #fff; font-size: 22rpx; font-weight: 600; padding: 8rpx 16rpx; border-radius: 999rpx; z-index: 2; box-shadow: 0 4rpx 12rpx rgba(255, 107, 53, 0.35); }
.prob-corner.tl { top: 12rpx; left: 12rpx }
.card-body { display: flex; align-items: center; justify-content: space-between; padding: 16rpx }
.card-title { font-size: 28rpx; color: #1F2937; flex: 1; margin-right: 8rpx; word-break: break-all; font-weight: 600; }
.badge-boss { background: linear-gradient(135deg, #FF9F43, #FFD166); color: #6b4b1f; font-size: 22rpx; font-weight: 600; padding: 6rpx 14rpx; border-radius: 999rpx }
.badge-count { background: linear-gradient(135deg, #FFD166, #FFE8A3); color: #6b4b1f; font-size: 22rpx; font-weight: 600; padding: 6rpx 14rpx; border-radius: 999rpx }
.rewards-empty, .issues-empty { font-size: 26rpx; color: #9CA3AF; text-align: center; padding: 40rpx }
</style>
