<template>
  <view class="page">
    <view class="notice-bar">
      <swiper class="notice-swiper" vertical circular autoplay interval="3000" duration="300">
        <swiper-item v-for="n in displayNotices" :key="n.id">
          <view class="notice-item">{{ n.text }}</view>
        </swiper-item>
      </swiper>
    </view>

    <view class="banner-box">
      <swiper class="banner-swiper" circular autoplay interval="4000" duration="500">
        <swiper-item v-for="b in displayBanners" :key="b.id">
          <image v-if="b.image" class="banner-image" :src="b.image" mode="aspectFill" @tap="onBannerTap(b)" />
          <view v-else class="banner-fallback">
            <text class="banner-fallback-text">{{ b.title || '敬请期待' }}</text>
          </view>
        </swiper-item>
      </swiper>
    </view>

    <view class="activity-section">
      <view class="section-title">活动</view>
      <view v-if="activityGroups.length">
        <scroll-view class="tabs" scroll-x>
          <view class="tab" v-for="g in activityGroups" :key="g.name" :class="{ active: g.name === selectedGroupName }" @tap="onSelectGroup(g.name)">{{ g.name }}</view>
        </scroll-view>
        <view v-if="activeGroupItems.length" class="activity-grid">
          <view class="activity-item" v-for="a in activeGroupItems" :key="a.id" @tap="onActivityTap(a)">
            <image v-if="a.image" class="activity-thumb" :src="a.image" mode="aspectFill" />
            <view v-else class="banner-fallback">
              <text class="banner-fallback-text">{{ a.title || '活动敬请期待' }}</text>
            </view>
            <text class="activity-name">{{ a.title }}</text>
            <text class="activity-desc" v-if="a.subtitle">{{ a.subtitle }}</text>
          </view>
        </view>
        <view v-else class="activity-empty">该分组暂无活动</view>
      </view>
      <view v-else class="activity-empty">暂无活动</view>
    </view>
  </view>
</template>

<script>
import { authRequest, request } from '../../utils/request.js'
export default {
  data() {
    return {
      notices: [],
      banners: [],
      activities: [],
      selectedGroupName: ''
    }
  },
  computed: {
    displayNotices() {
      if (Array.isArray(this.notices) && this.notices.length) return this.notices
      return [
        { id: 'n1', text: '欢迎光临' },
        { id: 'n2', text: '最新活动敬请期待' }
      ]
    },
    displayBanners() {
      if (Array.isArray(this.banners) && this.banners.length) return this.banners
      return [
        { id: 'ph-1', title: '精彩内容即将上线', image: '' },
        { id: 'ph-2', title: '敬请期待', image: '' },
        { id: 'ph-3', title: '更多活动请关注', image: '' }
      ]
    },
    activityGroups() {
      const list = Array.isArray(this.activities) ? this.activities : []
      const map = new Map()
      list.forEach(a => {
        const key = (a.category_name || '').trim() || '其他'
        if (!map.has(key)) map.set(key, [])
        map.get(key).push(a)
      })
      return Array.from(map.entries()).map(([name, items]) => ({ name, items }))
    },
    activeGroupItems() {
      const groups = this.activityGroups
      const name = this.selectedGroupName || (groups[0] && groups[0].name) || ''
      const g = groups.find(x => x.name === name)
      return g ? g.items : []
    }
  },
  onShow() {
    const token = uni.getStorageSync('token')
    const phoneBound = !!uni.getStorageSync('phone_bound')
    if (!token || !phoneBound) {
      uni.showModal({
        title: '提示',
        content: '请先登录并绑定手机号',
        confirmText: '去登录',
        success: (res) => {
          if (res.confirm) {
            uni.navigateTo({ url: '/pages/login/index' })
          }
        }
      })
    }
    try { console.log('home onShow', { token: !!token, phoneBound }) } catch (_) {}
    this.loadHomeData()
  },
  methods: {
    onSelectGroup(name) {
      this.selectedGroupName = String(name || '')
    },
    updateSelectedGroup() {
      const groups = this.activityGroups
      if (!groups.length) { this.selectedGroupName = ''; return }
      if (!groups.find(g => g.name === this.selectedGroupName)) {
        this.selectedGroupName = groups[0].name
      }
    },
    toArray(x) { return Array.isArray(x) ? x : [] },
    unwrap(list) {
      if (Array.isArray(list)) return list
      const obj = list || {}
      const arr = obj.list || obj.items || obj.data || []
      return Array.isArray(arr) ? arr : []
    },
    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()
    },
    apiGet(url) {
      const token = uni.getStorageSync('token')
      const fn = token ? authRequest : request
      return fn({ url })
    },
    normalizeNotices(list) {
      const arr = this.unwrap(list)
      return arr.map((i, idx) => ({
        id: i.id ?? String(idx),
        text: i.content ?? i.text ?? i.title ?? ''
      })).filter(i => i.text)
    },
    normalizeBanners(list) {
      const arr = this.unwrap(list)
      console.log('normalizeBanners input', list, 'unwrapped', arr)
      const mapped = arr.map((i, idx) => ({
        id: i.id ?? String(idx),
        title: i.title ?? '',
        image: this.cleanUrl(i.imageUrl ?? i.image_url ?? i.image ?? i.img ?? i.pic ?? ''),
        link: this.cleanUrl(i.linkUrl ?? i.link_url ?? i.link ?? i.url ?? ''),
        sort: typeof i.sort === 'number' ? i.sort : 0
      })).filter(i => i.image)
      mapped.sort((a, b) => a.sort - b.sort)
      console.log('normalizeBanners mapped', mapped)
      return mapped
    },
    normalizeActivities(list) {
      const arr = this.unwrap(list)
      console.log('normalizeActivities input', list, 'unwrapped', arr)
      const mapped = arr.map((i, idx) => ({
        id: i.id ?? String(idx),
        image: this.cleanUrl(i.image ?? i.banner ?? i.coverUrl ?? i.cover_url ?? i.img ?? i.pic ?? ''),
        title: i.title ?? i.name ?? '',
        subtitle: this.buildActivitySubtitle(i),
        link: this.cleanUrl(i.linkUrl ?? i.link_url ?? i.link ?? i.url ?? ''),
        category_name: (i.category_name ?? i.categoryName ?? '').trim(),
        category_id: i.activity_category_id ?? i.category_id ?? i.categoryId ?? null
      })).filter(i => i.image || i.title)
      console.log('normalizeActivities mapped', mapped)
      return mapped
    },
    buildActivitySubtitle(i) {
      const base = i.subTitle ?? i.sub_title ?? i.subtitle ?? i.desc ?? i.description ?? ''
      if (base) return base
      const cat = i.category_name ?? i.categoryName ?? ''
      const price = (i.price_draw !== undefined && i.price_draw !== null) ? `￥${(Number(i.price_draw || 0) / 100).toFixed(2)}` : ''
      const parts = [cat, price].filter(Boolean)
      return parts.join(' · ')
    },
    async loadHomeData() {
      const results = await Promise.allSettled([
        this.apiGet('/api/app/notices'),
        this.apiGet('/api/app/banners'),
        this.apiGet('/api/app/activities')
      ])
      const [nRes, bRes, acRes] = results
      if (nRes.status === 'fulfilled') {
        console.log('notices ok', nRes.value)
        this.notices = this.normalizeNotices(nRes.value)
      } else {
        console.error('notices error', nRes.reason)
        this.notices = []
      }
      if (bRes.status === 'fulfilled') {
        console.log('banners ok', bRes.value)
        this.banners = this.normalizeBanners(bRes.value)
      } else {
        console.error('banners error', bRes.reason)
        this.banners = []
      }
      if (acRes.status === 'fulfilled') {
        console.log('activities ok', acRes.value)
        this.activities = this.normalizeActivities(acRes.value)
        this.updateSelectedGroup()
      } else {
        console.error('activities error', acRes.reason)
        this.activities = []
        this.updateSelectedGroup()
      }
      console.log('home normalized', { notices: this.notices, banners: this.banners, activities: this.activities })
    },
    onBannerTap(b) {
      const imgs = (Array.isArray(this.banners) ? this.banners : []).map(x => x.image).filter(Boolean)
      const current = b && b.image
      if (current) {
        uni.previewImage({ urls: imgs.length ? imgs : [current], current })
        return
      }
      if (b.link && /^\/.+/.test(b.link)) {
        uni.navigateTo({ url: b.link })
      }
    },
    onActivityTap(a) {
      const name = (a.category_name || a.categoryName || '').trim()
      const id = a.id
      let path = ''
      if (name === '一番赏') path = '/pages/activity/yifanshang/index'
      else if (name === '无限赏') path = '/pages/activity/wuxianshang/index'
      else if (name === '对对碰') path = '/pages/activity/duiduipeng/index'
      if (path && id) {
        uni.navigateTo({ url: `${path}?id=${id}` })
        return
      }
      if (a.link && /^\/.+/.test(a.link)) {
        uni.navigateTo({ url: a.link })
      }
    }
  }
}
</script>

<style>
.page { padding: 24rpx }
.notice-bar { height: 64rpx; background: #fff4e6; border-radius: 8rpx; overflow: hidden; margin-bottom: 24rpx; }
.notice-swiper { height: 64rpx }
.notice-item { height: 64rpx; line-height: 64rpx; padding: 0 24rpx; color: #a15c00; font-size: 26rpx }
.banner-box { margin-bottom: 24rpx }
.banner-swiper { width: 100%; height: 320rpx; border-radius: 12rpx; overflow: hidden }
.banner-image { width: 100%; height: 320rpx }
.banner-fallback { width: 100%; height: 320rpx; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #f5f5f5, #eaeaea) }
.banner-fallback-text { color: #666; font-size: 28rpx }
.activity-section { background: #ffffff; border-radius: 12rpx; padding: 24rpx }
.section-title { font-size: 30rpx; font-weight: 600; margin-bottom: 16rpx }
.tabs { white-space: nowrap; display: flex; gap: 12rpx; margin-bottom: 16rpx }
.tab { display: inline-flex; align-items: center; height: 56rpx; padding: 0 20rpx; border-radius: 999rpx; background: #f5f7fa; color: #555; font-size: 26rpx }
.tab.active { background: #007AFF; color: #fff }
.activity-grid { display: flex; flex-wrap: wrap; margin: -12rpx }
.activity-item { width: 50%; padding: 12rpx }
.activity-thumb { width: 100%; height: 200rpx; border-radius: 8rpx }
.activity-name { display: block; margin-top: 8rpx; font-size: 26rpx; color: #222 }
.activity-desc { display: block; margin-top: 4rpx; font-size: 22rpx; color: #888 }
</style>
