<template>
  <div style="padding: 4vw 0">
    <!-- 栏目按钮 -->
    <div
      style="
        width: 100vw;
        padding: 0 4vw;

        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 10vw;
      "
    >
      <!-- 周榜按钮 -->
      <div style="flex: 1; min-width: 0" @click="changeTag('weekly')">
        <img
          v-show="weeklyShow"
          v-smart-img
          :src="imageUrl(getImgName('rankingWeeklyBtActive'))"
          alt=""
          style="width: 100%; display: block; object-fit: cover"
        />
        <img
          v-show="!weeklyShow"
          v-smart-img
          :src="imageUrl(getImgName('rankingWeeklyBt'))"
          alt=""
          style="width: 100%; display: block; object-fit: cover"
        />
      </div>

      <!-- 季榜按钮 -->
      <div style="flex: 1; min-width: 0" @click="changeTag('season')">
        <img
          v-show="seasonShow"
          v-smart-img
          :src="imageUrl(getImgName('rankingSeasonBtActive'))"
          alt=""
          style="width: 100%; display: block; object-fit: cover"
        />
        <img
          v-show="!seasonShow"
          v-smart-img
          :src="imageUrl(getImgName('rankingSeasonBt'))"
          alt=""
          style="width: 100%; display: block; object-fit: cover"
        />
      </div>
    </div>

    <itemCenter :imgUrl="imageUrl(`timeBg`)" :contentStyle="`inset:0 0 4vw;`">
      <div v-show="weeklyShow" style="display: flex; justify-content: center; align-items: center">
        <div class="timeBox">
          <div class="timeText" style="">{{ WDays }}D</div>
          <div class="timeText timeGap"></div>
          <div class="timeText" style="">{{ WHours }}</div>
          <div class="timeText timeGap">:</div>
          <div class="timeText" style="">{{ WMinutes }}</div>
          <div class="timeText timeGap">:</div>
          <div class="timeText" style="">{{ WSeconds }}</div>
        </div>
      </div>
      <div v-show="seasonShow" style="display: flex; justify-content: center; align-items: center">
        <div class="timeBox">
          <div class="timeText" style="">{{ MDays }}D</div>
          <div class="timeText timeGap"></div>
          <div class="timeText" style="">{{ MHours }}</div>
          <div class="timeText timeGap">:</div>
          <div class="timeText" style="">{{ MMinutes }}</div>
          <div class="timeText timeGap">:</div>
          <div class="timeText" style="">{{ MSeconds }}</div>
        </div>
      </div>
    </itemCenter>

    <!-- 排行榜 -->
    <div style="position: relative; display: flex; flex-direction: column; gap: 2vw">
      <!-- 帮助按钮 -->
      <img v-smart-img :src="imageUrl('helpBt')" alt="" class="helpBt" @click="helpShow = true" />

      <!-- 第一名排名图片 -->
      <itemCenter
        style="width: 9vw"
        class="rankingBg"
        :imgUrl="imageUrl(`top1RankingBg`)"
        :flip="true"
        :contentStyle="``"
      >
        <img :src="imageUrl('num1')" alt="" style="width: 3vw; display: block" />
      </itemCenter>

      <!-- 前三名 -->
      <div style="margin-top: 2vw; display: flex; flex-direction: column; gap: 2vw">
        <TopUser
          v-for="(value, index) in 3"
          :ranking="index + 1 + ''"
          :rankingItem="RankingHasTop3[index] || {}"
          :rewards="showRewardsTop3[index] || {}"
        />
      </div>

      <!-- 从第4名开始 -->
      <itemCenter
        v-for="item in showRanking"
        :imgUrl="imageUrl(`rankingItemBg`)"
        :flip="true"
        :contentStyle="`padding: 0 5%;justify-content: flex-start;`"
      >
        <!-- 排名 -->
        <itemCenter
          style="width: 9vw"
          :imgUrl="imageUrl(`top1RankingBg`)"
          :flip="true"
          :contentStyle="``"
        >
          <div class="rankingText">
            <img
              v-smart-img
              v-for="(digit, index) in getRankDigits(item.rank)"
              :src="getDigitImageUrl(digit)"
              style="display: block; width: 3vw; object-fit: cover"
            />
          </div>
        </itemCenter>

        <!-- 头像 -->
        <div style="width: 36vw">
          <div
            style="
              width: 100%;
              padding: 3vw 5vw;
              height: 80%;
              display: flex;
              justify-content: space-between;
              align-items: center;

              position: relative;
            "
          >
            <!-- 点击事件 -->
            <div
              style="
                position: absolute;
                z-index: 9;
                inset: 0;
                display: flex;
                justify-content: center;
                align-items: center;
              "
            >
              <!-- 情侣1 -->
              <div
                style="flex: 1; min-width: 0; align-self: stretch"
                @click="viewUserInfo(item.userId)"
              ></div>
              <!-- 情侣2 -->
              <div
                style="flex: 1; min-width: 0; align-self: stretch"
                @click="viewUserInfo(item.cpUserId)"
              ></div>
            </div>

            <!-- 情侣标志 -->
            <div
              style="
                position: absolute;
                inset: 0;
                display: flex;
                justify-content: center;
                align-items: center;
              "
            >
              <img
                :src="imageUrl(`rankingCoupleSign`)"
                alt=""
                style="width: 15vw; display: block; object-fit: cover"
              />
            </div>

            <!-- 情侣1头像 -->
            <img
              v-smart-img
              :src="item.userAvatar || ''"
              alt=""
              style="
                display: block;
                min-width: 0;
                width: 12vw;
                object-fit: cover;
                aspect-ratio: 1/1;
                border-radius: 50%;
                border: 1px solid #fefa9f;
              "
              @error="handleAvatarImageError"
            />
            <!-- 情侣2头像 -->
            <img
              v-smart-img
              :src="item.cpUserAvatar || ''"
              alt=""
              style="
                display: block;
                min-width: 0;
                width: 12vw;
                object-fit: cover;
                aspect-ratio: 1/1;
                border-radius: 50%;
                border: 1px solid #fefa9f;
              "
              @error="handleAvatarImageError"
            />
          </div>
        </div>

        <!-- 名称 -->
        <div
          style="
            flex: 1;
            min-width: 0;
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            gap: 1vw;
          "
        >
          <div style="width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
            {{ item.userNickname || '' }}
          </div>
          <div style="width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
            {{ item.cpUserNickname || '' }}
          </div>
        </div>

        <!-- 贡献 -->
        <div style="width: auto; min-width: 0; display: flex; align-items: center">
          <img
            v-smart-img
            :src="imageUrl('distribution')"
            alt=""
            style="width: 10vw; display: block; object-fit: cover"
          />
          <div style="font-weight: 700">{{ item.total || '0' }}</div>
        </div>
      </itemCenter>
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useLangStore } from '@/stores/lang'
import { useI18n } from 'vue-i18n'
import { getPngUrl } from '@/config/imagePaths.js'
import { setUserInfo } from '@/utils/userStore.js'
import { viewUserInfo } from '@/utils/appBridge.js'
import { connectToApp } from '@/utils/appConnector.js'
import { preloadImages } from '@/utils/imagePreloader.js'
import { formatUTCCustom } from '@/utils/utcFormat.js'
import { showError, showSuccess } from '@/utils/toast.js'
import { handleAvatarImageError, handleRewardImageError } from '@/utils/imageHandler.js'
import { useCoupleStore } from '@/stores/couple'
import { useThrottle } from '@/utils/useDebounce.js'
import { storeToRefs } from 'pinia'

import {
  apiGetCpRanking, // 获取cp排行榜
  apiGetCpRewardPool, // 获取cp奖励池(前三名)
} from '@/api/couple.js'

import TopUser from './components/topUser.vue'
import itemCenter from '@/components/itemCenter.vue'
import maskLayer from '@/components/MaskLayer.vue'

const { t } = useI18n()
const router = useRouter()
const route = useRoute()
const coupleStore = useCoupleStore()

const langStore = useLangStore()
// 当前语言类型
const currentLangType = computed(() => {
  return langStore.selectedLang?.type || 'en'
})

const isLoading = ref(true) // 预加载状态

// 获取OSS图片URL的函数
const imageUrl = (filename) => getPngUrl('Ranking/Couple/', filename)

// 根据语言获取图片名
const getImgName = (filename) => {
  return currentLangType.value === 'ar' ? `${filename}_ar` : filename
}

const {
  helpShow, // 帮助按钮
  myRanking, // 我的排名
} = storeToRefs(coupleStore)

// 倒计时相关数据
const WDays = ref(0)
const WHours = ref(0)
const WMinutes = ref(0)
const WSeconds = ref(0)
let countdownTimer = null

const MDays = ref(0)
const MHours = ref(0)
const MMinutes = ref(0)
const MSeconds = ref(0)
let monthlyCountdownTimer = null // 月度倒计时定时器

// 获取对应的时间戳
const getNextMondayInBeijing = () => {
  const now = new Date()
  const targetDate = new Date(now.getTime()) // 创建一个基于当前时间的新日期对象

  // 转换为北京时间来判断星期几
  const utcTime = now.getTime() + now.getTimezoneOffset() * 60000
  const beijingTime = new Date(utcTime + 8 * 3600000) // UTC+8

  const beijingDay = beijingTime.getDay() // 0=周日, 1=周一, ..., 6=周六
  const beijingHour = beijingTime.getHours()

  // 转换为 0=周一, 1=周二, ..., 6=周日
  const normalizedDay = beijingDay === 0 ? 6 : beijingDay - 1

  let daysToAdd
  if (normalizedDay === 0) {
    // 今天是周一
    if (beijingHour >= 5) {
      daysToAdd = 7 // 超过5点，计算到下周一的所需时间
    } else {
      daysToAdd = 0 // 今天
    }
  } else {
    daysToAdd = 7 - normalizedDay // 到下周一的天数
  }

  // 正确地添加天数
  targetDate.setDate(targetDate.getDate() + daysToAdd) // 添加天数到下周一的当前时间
  targetDate.setHours(5, 0, 0, 0) // 将时间重新设置为早上5点，作为目标时间戳

  return targetDate.getTime()
}

const targetTime = ref(getNextMondayInBeijing()) // 闭包保存目标时间 (核心修正)

// 格式化时间
const formatTime = (value) => {
  return value < 10 ? `0${value}` : value
}

// 倒计时
const getCountdown = () => {
  const now = Date.now()
  let diff = targetTime.value - now

  if (diff <= 0) {
    // 初始化数据
    initData()

    targetTime.value += 7 * 86400000 // +7天 (更新闭包变量)
    diff = targetTime.value - now
  }

  const totalSeconds = Math.floor(diff / 1000)
  WDays.value = Math.floor(totalSeconds / (24 * 3600))
  WHours.value = formatTime(Math.floor((totalSeconds % (24 * 3600)) / 3600))
  WMinutes.value = formatTime(Math.floor((totalSeconds % 3600) / 60))
  WSeconds.value = formatTime(Math.floor(totalSeconds % 60))
}

// 启动倒计时
const startCountdown = () => {
  getCountdown() // 立即执行一次周倒计时
  getMonthlyCountdown() // 立即执行一次月倒计时
  countdownTimer = setInterval(getCountdown, 1000)
  monthlyCountdownTimer = setInterval(getMonthlyCountdown, 1000)
}

// 获取下一个星座周期的截止时间
const getNextMonthFirstInBeijing = () => {
  const now = new Date()

  // 北京时间星座周期截止日期配置 - [月, 日]
  const zodiacCutoffDates = [
    [1, 20], // 摩羯座到水瓶座: 1月20日
    [2, 19], // 水瓶座到双鱼座: 2月19日
    [3, 21], // 双鱼座到白羊座: 3月21日
    [4, 20], // 白羊座到金牛座: 4月20日
    [5, 21], // 金牛座到双子座: 5月21日
    [6, 22], // 双子座到巨蟹座: 6月22日
    [7, 23], // 巨蟹座到狮子座: 7月23日
    [8, 23], // 狮子座到处女座: 8月23日
    [9, 23], // 处女座到天秤座: 9月23日
    [10, 23], // 天秤座到天蝎座: 10月23日
    [11, 22], // 天蝎座到射手座: 11月22日
    [12, 22], // 射手座到摩羯座: 12月22日
  ]

  // 获取当前的北京时间
  const beijingTime = new Date(now.getTime() + 8 * 60 * 60 * 1000)
  const currentYear = beijingTime.getUTCFullYear()
  const currentMonth = beijingTime.getUTCMonth() + 1 // 月份从1开始
  const currentDate = beijingTime.getUTCDate()
  const currentHour = beijingTime.getUTCHours()

  // 查找当前属于哪个星座周期
  let targetDate = null
  let targetYear = currentYear

  // 获取本年度的截止时间
  for (let i = 0; i < zodiacCutoffDates.length; i++) {
    const [cutoffMonth, cutoffDate] = zodiacCutoffDates[i]

    // 如果当前日期在某个星座周期内，则返回下一个周期的截止日期
    if (
      currentMonth < cutoffMonth ||
      (currentMonth === cutoffMonth && currentDate < cutoffDate) ||
      (currentMonth === cutoffMonth && currentDate === cutoffDate && currentHour < 5)
    ) {
      // 当前时间处于当前年份的该星座周期内
      targetDate = [cutoffMonth, cutoffDate]
      break
    }
  }

  // 如果仍未找到，说明当前是年末的摩羯座周期，需要找下一年的1月20日
  if (!targetDate) {
    targetDate = [1, 20]
    targetYear = currentYear + 1
  }

  // 创建目标日期（北京时间）
  // 使用Date.UTC创建UTC时间，然后减去时差转换为UTC时间
  const targetDateAsBeijing =
    Date.UTC(targetYear, targetDate[0] - 1, targetDate[1], 5, 0, 0) - 8 * 60 * 60 * 1000

  return targetDateAsBeijing
}

// 月度倒计时
const getMonthlyCountdown = () => {
  const now = Date.now()
  let diff = targetMonthTime.value - now

  if (diff <= 0) {
    // 如果时间已过，重新计算下一个月
    targetMonthTime.value = getNextMonthFirstInBeijing()
    diff = targetMonthTime.value - now
  }

  const totalSeconds = Math.floor(diff / 1000)

  // 计算天数（这里需要考虑月份跨越的情况，使用总天数）
  const totalDays = Math.floor(totalSeconds / (24 * 3600))
  MDays.value = totalDays

  const remainingHours = Math.floor((totalSeconds % (24 * 3600)) / 3600)
  MHours.value = formatTime(remainingHours)

  const remainingMinutes = Math.floor((totalSeconds % 3600) / 60)
  MMinutes.value = formatTime(remainingMinutes)

  const remainingSeconds = totalSeconds % 60
  MSeconds.value = formatTime(remainingSeconds)
}

// 添加月度倒计时的目标时间
const targetMonthTime = ref(getNextMonthFirstInBeijing())

const weeklyShow = ref(true) //本周数据
const seasonShow = ref(false) //季度数据

const changeTag = (module) => {
  switch (module) {
    case 'weekly':
      if (weeklyShow.value) return
      weeklyShow.value = true
      seasonShow.value = false
      apiGetRanking() // 获取排行榜
      apiGetTop3Rewards() // 获取前三名奖励
      break
    case 'season':
      if (seasonShow.value) return
      weeklyShow.value = false
      seasonShow.value = true
      apiGetRanking() // 获取排行榜
      apiGetTop3Rewards() // 获取前三名奖励
      break
  }
}

const rewardsTop3 = ref([]) // 原前三名奖励列表
// 处理后的前三名奖励列表
const showRewardsTop3 = computed(() => {
  // 对 rewardsTop3 进行深拷贝，避免引用问题
  let newRewardsTop3 = JSON.parse(JSON.stringify(rewardsTop3.value))
  // 季度榜添加奖励
  if (seasonShow.value) {
    newRewardsTop3[0].activityRewardProps.push(
      {
        cover: '',
        content: 'Banner*30Days',
        quantity: 0,
        type: 'GIFT',
      },
      {
        cover: '',
        content: 'ID: 7 digits * 1',
        quantity: 0,
        type: 'GIFT',
      },
    )
  }
  // 周榜添加奖励
  else {
    // 第一名
    newRewardsTop3[0]?.activityRewardProps.push(
      {
        cover: new URL('/src/assets/icon/coin.png', import.meta.url).href,
        content: t('heartbeat_value_points_4_percent', {
          amount: formatLargeNumber(Number(RankingHasTop3.value[0]?.totalNumber) * 0.04),
        }),
        quantity: 0,
        type: 'GIFT',
      },
      {
        cover: '',
        content: 'Homepage Ad* 7 days',
        quantity: 0,
        type: 'GIFT',
      },
    )
    // 第二名
    newRewardsTop3[1]?.activityRewardProps.push({
      cover: new URL('/src/assets/icon/coin.png', import.meta.url).href,
      content: t('heartbeat_value_points_3_percent', {
        amount: formatLargeNumber(Number(RankingHasTop3.value[1]?.totalNumber) * 0.03),
      }),
      quantity: 0,
      type: 'GIFT',
    })
    // 第三名
    newRewardsTop3[2]?.activityRewardProps.push({
      cover: new URL('/src/assets/icon/coin.png', import.meta.url).href,
      content: t('heartbeat_value_points_2_percent', {
        amount: formatLargeNumber(Number(RankingHasTop3.value[2]?.totalNumber) * 0.02),
      }),
      quantity: 0,
      type: 'GIFT',
    })
  }

  return newRewardsTop3
})

const RankingLoadmore = ref(null) //触底模块
const rankingPageNo = ref(1) //分页页码
const Ranking = ref([]) //原始排行榜
const rankingAdd = ref([]) //加载排行榜项
// 完整排行榜
const rankingTotal = computed(() => {
  return [...Ranking.value, ...rankingAdd.value]
})

// 处理排行榜小于3人时的情况
const RankingHasTop3 = computed(() => {
  let RankingShow = [...Ranking.value]
  if (Ranking.value.length < 3) {
    let addNullUser = Array.from({ length: 3 - Ranking.value.length }, () => ({
      rank: '',

      userAvatar: '',
      userId: '',
      userNickname: '',
      userSex: '',

      cpUserAvatar: '',
      cpUserId: '',
      cpUserNickname: '',
      cpUserSex: '',

      total: '0',
      totalNumber: '0',
    }))
    RankingShow.push(...addNullUser)
  }
  return RankingShow
})

// 展示用的榜单
const showRanking = computed(() => {
  return Ranking.value.filter((_, index) => index >= 3)
  // return []
})

// 获取排名数字的各个位数
const getRankDigits = (rank) => {
  return String(rank).split('')
}

// 获取数字图片URL
const getDigitImageUrl = (digit) => {
  if (/^[0-9]$/.test(digit)) {
    return imageUrl(`num${digit}`) // 假设数字图片在相同目录下
  }
  return ''
}

// 在 script 部分定义这个函数
const formatLargeNumber = (num) => {
  if (typeof num !== 'number' || isNaN(num)) {
    return '0'
  }

  const absNum = Math.abs(num)

  if (absNum >= 1000000) {
    const millionValue = num / 1000000
    const roundedValue = Math.round(millionValue * 100) / 100
    return roundedValue.toFixed(2) + 'M'
  } else if (absNum >= 1000) {
    const thousandValue = num / 1000
    const roundedValue = Math.round(thousandValue * 100) / 100
    return roundedValue.toFixed(2) + 'K'
  } else {
    return Math.floor(num).toString()
  }
}

// 获取榜单
const apiGetRanking = async () => {
  let type = weeklyShow.value ? 'WEEK' : 'SEASON'
  try {
    const response = await apiGetCpRanking(type)
    if (response.status && response.body) {
      Ranking.value = response.body.thisWeekUserTop || [] // 原始排行榜
      myRanking.value = response.body.thisUser || {} // 我的排名
    }
  } catch (error) {
    showError(error.response.errorMsg)
  }
}

// 获取前三名奖励
const apiGetTop3Rewards = async () => {
  let type = weeklyShow.value ? 'WEEK_CP_GIFT' : 'SEASON_CP_GIFT'
  try {
    const response = await apiGetCpRewardPool(type)
    if (response.status && response.body) {
      let rewards = response.body

      rewardsTop3.value = response.body || [] // 前三名奖励
    }
  } catch (error) {
    showError(error.response.errorMsg)
  }
}

// 触发节流获取排行榜
const debouceGetRanking = useThrottle(() => {
  // getRanking() //加载新的排行榜项
}, 1000)

// IntersectionObserver配置
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.intersectionRatio > 0 && rankingTotal.value.length != 0) {
      console.log('触发RankingLoadmore加载')
      debouceGetRanking()
    }
  })
})

// 页面初始化数据
const initData = async () => {
  await Promise.all([
    apiGetRanking(), // 获取排行榜
    apiGetTop3Rewards(), // 获取前三名奖励
  ])
}

// 预加载关键图片
const preloadCriticalImages = async () => {
  const criticalImages = []

  const criticalImages_ar = []

  if (currentLangType.value == 'en') {
    await preloadImages(criticalImages)
  } else if (currentLangType.value == 'ar') {
    await preloadImages(criticalImages_ar)
  }
}

// 完成预加载
const completePreloading = async () => {
  try {
    // 执行所有初始化操作
    await Promise.all([initData(), preloadCriticalImages()])
    console.log('预加载完成，初始化数据成功')
  } catch (error) {
    console.error('预加载过程中发生错误:', error)
  } finally {
    // 无论成功或失败都结束加载状态
    isLoading.value = false
  }
}

// 使用工具函数连接APP
const connectToAppHandler = async () => {
  await connectToApp(() => {
    // 连接成功回调
    completePreloading() // 完成预加载
  })
}

// 组件挂载时检测环境
onMounted(() => {
  startCountdown() //开启倒计时
  connectToAppHandler()
  // 监听加载模块
  if (RankingLoadmore.value) {
    console.log('监控加载模块')
    observer.observe(RankingLoadmore.value)
  }
})

onUnmounted(() => {
  // 销毁计时器
  if (countdownTimer) {
    clearInterval(countdownTimer)
    countdownTimer = null
  }
  if (monthlyCountdownTimer) {
    clearInterval(monthlyCountdownTimer)
    monthlyCountdownTimer = null
  }
})
</script>

<style lang="scss" scoped>
.timeBox {
  width: 50vw;
  display: flex;
  justify-content: center;
}

.timeText {
  color: #fff;
  font-weight: 590;
  font-size: 2em;
  margin-top: 1vw;

  background: linear-gradient(
    180deg,
    #ffdf6b 31.61%,
    #ffe562 36.73%,
    #fff 52.37%,
    #ffe562 58.67%,
    #ffa615 72.2%
  );
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.timeGap {
  width: 6px;
  align-self: stretch;

  display: flex;
  justify-content: center;
  align-items: center;
}

[dir='rtl'] .timeBox {
  flex-direction: row-reverse;
}

.helpBt {
  display: block;
  width: 8vw;
  object-fit: cover;
  position: absolute;
  z-index: 3;
  top: 0;
  right: 3vw;
}

[dir='rtl'] .helpBt {
  right: unset;
  left: 3vw;
}

.rankingBg {
  position: absolute;
  z-index: 3;
  top: 6vw;
  left: 3vw;
}

.rankingText {
  width: 100%;
  height: 100%;

  display: flex;
  justify-content: center;
  align-items: center;
}

[dir='rtl'] .rankingText {
  flex-direction: row-reverse;
}

[dir='rtl'] .rankingBg {
  left: unset;
  right: 3vw;
}
</style>
