<template>
  <!-- 页面根容器：赛事详情页使用 100vh 固定视口，内部主内容滚动并隐藏滚动条 -->
  <div
    style="
      position: relative;
      width: 100vw;
      height: 100vh;
      overflow: hidden;
      background: #101e14;
      color: #fff;
    "
  >
    <!-- 首屏加载动画：详情接口和关键图片完成后再展示页面内容 -->
    <div
      v-if="isLoading"
      style="
        position: relative;
        z-index: 2;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      "
    >
      <LoadingContent>{{ $t('loading') }}...</LoadingContent>
    </div>

    <!-- 正式页面内容：加载完成后才渲染背景图、头部和业务模块 -->
    <div
      v-else
      style="
        position: relative;
        z-index: 1;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        overflow: hidden;
      "
    >
      <!-- 最底层背景图：detailPageBg 只按 100vw 宽度展示，高度按图片自身比例，不强制拉伸 -->
      <img
        v-smart-img.noFade
        :src="pngUrl('detailPageBg')"
        alt=""
        style="position: absolute; inset: 0; z-index: 0; display: block; width: 100vw; height: auto"
      />

      <!-- 顶部导航：使用公共 GeneralHeader，标题为 World Cup，非首页返回，返回图标使用 arrowBack -->
      <div style="position: relative; z-index: 1">
        <GeneralHeader title="World Cup" :isHomePage="false" :backImg="arrowBackImg" />
      </div>

      <!-- 主内容滚动区：后续模块按 column 顺序补充，隐藏可见滚动条 -->
      <main
        class="world-cup-event-detail-scroll"
        style="
          width: 100%;
          flex: 1;
          display: flex;
          flex-direction: column;
          gap: 2vw;
          overflow-x: hidden;
          overflow-y: auto;
          padding: 2vw 2vw 8vw;
          box-sizing: border-box;
          scrollbar-width: none;
          -ms-overflow-style: none;
        "
      >
        <!-- 赛事结果模块：按未开始、进行中、已结束中奖、已结束未中奖/未参与展示不同状态 -->
        <itemCenter
          style="position: relative; width: 100%; min-height: 53vw; max-height: 54vw"
          :imgUrl="pngUrl(resultStatusConfig.image)"
          contentStyle=" padding: 9vw 5vw 2vw 5vw; box-sizing: border-box; display: flex; flex-direction: column; align-items: stretch; justify-content: space-between; gap: 0vw;"
        >
          <!-- 状态角标：绝对定位贴左上角，颜色随赛事结果状态变化 -->
          <div :style="resultStatusConfig.badgeStyle">
            {{ resultStatusConfig.badgeText }}
          </div>

          <!-- 状态主文案：第（2）行只切换展示内容，文本字体颜色、大小、字重保持同一套样式 -->
          <div
            style="
              display: flex;
              align-items: center;
              justify-content: flex-start;
              gap: 1vw;
              color: #f8e89a;
              font-size: 2em;
              font-weight: 500;
            "
          >
            <template v-if="resultStatusConfig.type === 'endedWin'">
              <span style="color: #f8e89a; font-size: 1em; font-weight: 500"> + </span>
              <img
                v-smart-img
                src="/src/assets/icon/Aslan/coin.png"
                alt=""
                style="display: block; width: 1.5em; aspect-ratio: 1/1; object-fit: cover"
              />
              <span style="color: #f8e89a; font-size: 1em; font-weight: 500">
                {{ winAmount }}
              </span>
            </template>
            <span v-else style="color: #f8e89a; font-size: 1em; font-weight: 500">
              {{ resultStatusConfig.mainText }}
            </span>
          </div>

          <!-- 开赛时间说明：所有状态固定展示，时间内容统一根据 kickoffTime 字段格式化 -->
          <div style="color: #f6efaa; font-size: 0.9em; font-weight: 500">
            {{ kickoffText }}
          </div>

          <!-- 分割线：区分状态信息和奖池/人数信息 -->
          <div style="width: 70%; height: 0.5px; background: rgba(246, 239, 170, 0.5)"></div>

          <!-- 奖池和人数行：左侧总奖池，右侧参与人数 -->
          <div
            style="
              width: 70%;
              display: flex;
              align-items: flex-start;
              justify-content: space-between;
              gap: 4vw;
            "
          >
            <!-- 总奖池信息：上方标题，下方 coin 和 totalPool -->
            <div style="display: flex; flex-direction: column; align-items: flex-start; gap: 1vw">
              <div style="color: #f8e89a; font-size: 1em; font-weight: 500">total prize pool:</div>
              <div style="display: flex; align-items: center; gap: 1vw">
                <img
                  v-smart-img
                  src="/src/assets/icon/Aslan/coin.png"
                  alt=""
                  style="display: block; width: 2.5em; aspect-ratio: 1/1; object-fit: cover"
                />
                <span style="color: #f8e89a; font-size: 1.5em; font-weight: 500">
                  {{ matchInfo.totalPool || 0 }}
                </span>
              </div>
            </div>

            <!-- 参与人数信息：numPeopleGold 图片加 joinCount -->
            <div
              style="
                display: flex;
                align-items: center;
                justify-content: flex-end;
                gap: 1vw;
                white-space: nowrap;
              "
            >
              <img
                v-smart-img.noFade
                :src="pngUrl('numPeopleGold')"
                alt=""
                style="display: block; width: 2em; aspect-ratio: 1/1; object-fit: contain"
              />
              <span style="color: #f8e89a; font-size: 1.5em; font-weight: 500">
                {{ matchInfo.joinCount || 0 }}
              </span>
            </div>
          </div>
        </itemCenter>

        <!-- 押注模块：未开始赛事可选择押注对象并点击金额下注，已开始/已结束赛事只展示已押注状态 -->
        <section :style="betModuleStyle">
          <!-- 押注对象模块：三列展示主胜、平局、客胜，结构对齐首页 Ended 列表项 -->
          <div
            style="
              width: 100%;
              display: flex;
              align-items: stretch;
              justify-content: center;
              gap: 2vw;
              box-sizing: border-box;
            "
          >
            <!-- 单个押注对象：未开始时可点击选中，其他状态只展示用户已押注项 -->
            <div
              v-for="betOption in detailBetOptions"
              :key="betOption.option"
              :style="getDetailBetOptionStyle(betOption.option)"
              @click="handleBetOptionClick(betOption.option)"
            >
              <!-- 押注对象赛事信息：旗帜、国家名和占比 -->
              <div
                style="
                  width: 100%;
                  display: flex;
                  flex-direction: column;
                  align-items: center;
                  justify-content: flex-start;
                  gap: 1vw;
                "
              >
                <div
                  style="
                    width: 100%;
                    aspect-ratio: 1 / 1.1;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    position: relative;
                  "
                >
                  <img
                    v-if="betOption.isOssImage"
                    v-smart-img.noFade
                    :src="betOption.flagUrl"
                    alt=""
                    style="display: block; width: 64%; aspect-ratio: 1 / 1; object-fit: contain"
                  />
                  <img
                    v-else
                    :src="betOption.flagUrl"
                    alt=""
                    style="display: block; width: 68%; aspect-ratio: 1 / 1; object-fit: contain"
                  />
                  <!-- 已结束胜方标识框：根据 result 字段叠加在主胜、平局或客胜对应图片上方 -->
                  <img
                    v-if="isDetailBetOptionWinner(betOption.option)"
                    v-smart-img.noFade
                    :src="pngUrl('frameWinner')"
                    alt=""
                    style="
                      position: absolute;
                      top: 0;
                      left: 0;
                      z-index: 3;
                      display: block;
                      width: 100%;
                      object-fit: contain;
                      pointer-events: none;
                    "
                  />
                </div>
                <div
                  style="
                    max-width: 100%;
                    overflow: hidden;
                    color: #fff;
                    font-size: 1em;
                    font-weight: 500;
                    text-align: center;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                  "
                >
                  {{ betOption.name }}
                </div>
                <div :style="`color: ${betOption.percentColor}; font-size: 1em; font-weight: 500;`">
                  {{ formatMatchPercent(betOption.percent) }}
                </div>
              </div>

              <!-- 押注对象金额信息：上方选项奖池，下方用户累计下注额 -->
              <div
                style="
                  border-radius: 4px;
                  border: 0.5px solid #e9d089;
                  background: linear-gradient(
                    180deg,
                    rgba(79, 77, 33, 0.5) 0%,
                    rgba(79, 77, 33, 0) 100%
                  );
                  backdrop-filter: blur(13.449894905090332px);
                  width: 100%;
                  display: flex;
                  flex-direction: column;
                  align-items: center;
                  justify-content: center;
                  gap: 0vw;
                  margin-top: 1vw;
                "
              >
                <!-- 选项奖池金额：使用详情接口格式化字段优先展示 -->
                <div
                  style="display: flex; align-items: center; justify-content: center; padding: 4px"
                >
                  <img
                    v-smart-img
                    src="/src/assets/icon/Aslan/coin.png"
                    alt=""
                    style="display: block; width: 1.5em; aspect-ratio: 1/1; object-fit: cover"
                  />
                  <span style="color: #fff; font-size: 1em; font-weight: 500">
                    {{ betOption.poolAmount }}
                  </span>
                </div>
                <div style="width: 100%; height: 1px; background: #e9d089"></div>
                <!-- 用户下注金额：未押注时展示 0 -->
                <div
                  style="display: flex; align-items: center; justify-content: center; padding: 4px"
                >
                  <img
                    v-smart-img
                    src="/src/assets/icon/Aslan/coin.png"
                    alt=""
                    style="display: block; width: 1.5em; aspect-ratio: 1/1; object-fit: cover"
                  />
                  <span style="color: #fff; font-size: 1em; font-weight: 500">
                    {{ betOption.myBetAmount }}
                  </span>
                </div>
              </div>
            </div>
          </div>

          <!-- 押注金额模块：仅未开始赛事展示，选中押注对象后点击金额才提交押注 -->
          <div
            v-if="canSubmitBet"
            style="
              width: 100%;
              display: flex;
              align-items: center;
              justify-content: space-between;
              gap: 2vw;
            "
          >
            <!-- 单个押注金额按钮：点击后调用 apiPostWorldCupBet -->
            <div
              v-for="amount in betAmountOptions"
              :key="amount"
              :style="betAmountButtonStyle"
              @click="handleBetAmountClick(amount)"
            >
              <img
                v-smart-img
                src="/src/assets/icon/Aslan/coin.png"
                alt=""
                style="display: block; width: 1.4em; aspect-ratio: 1/1; object-fit: cover"
              />
              <span style="color: #fff; font-size: 1em; font-weight: 500">{{ amount }}</span>
            </div>
          </div>
        </section>

        <!-- 押注记录模块：展示当前赛事内用户押注对象、金额和押注时间 -->
        <section :style="predictionRecordModuleStyle">
          <!-- 固定标题模块：说明下方列表为本场竞猜记录 -->
          <div style="color: #ffe083; font-size: 1em; font-weight: 500">
            My prediction for this game:
          </div>

          <!-- 竞猜记录空态：没有本场记录时展示 footballSign 和空文案 -->
          <div
            v-if="!predictionRecords.length"
            style="
              width: 100%;
              flex: 1;
              display: flex;
              flex-direction: column;
              align-items: center;
              justify-content: center;
              gap: 2vw;
            "
          >
            <img
              v-smart-img.noFade
              :src="pngUrl('footballSign')"
              alt=""
              style="display: block; width: 30vw; aspect-ratio: 1/1; object-fit: contain"
            />
            <div style="color: #ffe083; font-size: 1.5em; font-weight: 500">No records yet.</div>
          </div>

          <!-- 竞猜记录列表：有记录时内部滚动并隐藏可见滚动条 -->
          <div
            v-else
            class="world-cup-event-detail-record-scroll"
            style="
              width: 100%;
              flex: 1;
              display: flex;
              flex-direction: column;
              gap: 2vw;
              overflow-x: hidden;
              overflow-y: auto;
              scrollbar-width: none;
              -ms-overflow-style: none;
            "
          >
            <!-- 单条竞猜记录：左侧押注对象和时间，右侧押注金额 -->
            <div
              v-for="recordItem in predictionRecords"
              :key="recordItem.betId || `${recordItem.matchId}-${recordItem.betTime}`"
              style="
                width: 100%;
                display: flex;
                align-items: center;
                justify-content: space-between;
                gap: 3vw;
                padding: 2vw 3vw;
                box-sizing: border-box;
                border-radius: 8px;
                border: 0.5px solid #e9d089;
                background: linear-gradient(
                  180deg,
                  rgba(79, 77, 33, 0.5) 0%,
                  rgba(79, 77, 33, 0) 100%
                );
                backdrop-filter: blur(13.449894905090332px);
              "
            >
              <!-- 记录左侧：押注选项名和押注时间 -->
              <div
                style="
                  flex: 1;
                  display: flex;
                  flex-direction: column;
                  align-items: flex-start;
                  gap: 1vw;
                  overflow: hidden;
                "
              >
                <div
                  style="
                    max-width: 100%;
                    overflow: hidden;
                    color: #ffe083;
                    font-size: 1em;
                    font-weight: 500;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                  "
                >
                  Bets placed: {{ recordItem.betOptionName || '' }}
                </div>
                <div style="color: #ffe083; font-size: 1em; font-weight: 500">
                  {{ formatPredictionTime(recordItem.betTime) }}
                </div>
              </div>

              <!-- 记录右侧：coin 图片和押注金额 -->
              <div
                style="
                  display: flex;
                  align-items: center;
                  justify-content: flex-end;
                  gap: 1vw;
                  flex: 0 0 auto;
                  white-space: nowrap;
                "
              >
                <img
                  v-smart-img
                  src="/src/assets/icon/Aslan/coin.png"
                  alt=""
                  style="display: block; width: 1.5em; aspect-ratio: 1/1; object-fit: cover"
                />
                <span style="color: #fff; font-size: 1em; font-weight: 500">
                  {{ recordItem.betAmount || 0 }}
                </span>
              </div>
            </div>
          </div>
        </section>
      </main>
    </div>
  </div>
</template>

<script setup>
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import { getPngUrl } from '@/config/imagePaths.js'
import { preloadImages } from '@/utils/image/imagePreloader.js'
import {
  apiGetWorldCupMatchDetail,
  apiPostWorldCupBet,
  apiPostWorldCupMyBetList,
} from '@/api/worldCup.js'
import { connectToApp } from '@/utils/appConnector.js'
import GeneralHeader from '@/components/GeneralHeader.vue'
import itemCenter from '@/components/itemCenter.vue'
import arrowBackImg from '@/assets/icon/Aslan/arrowBack.png'
import { showError, showSuccess, showWarning } from '@/utils/toast.js'

const route = useRoute()
const assetPath = 'Activities/WorldCup/'
const pngUrl = (filename) => getPngUrl(assetPath, filename)
const matchId = computed(() => route.query.matchId || '')
const isLoading = ref(true)
const matchInfo = ref({})
const myBets = ref([])
const nowTime = ref(Date.now())
const selectedBetOption = ref(null)
const isSubmittingBet = ref(false)
let countdownTimer = null

const blockingImages = [
  'detailPageBg',
  'statusNotStarted',
  'statusInProgress',
  'statusEndedWin',
  'statusEndedfail',
  'numPeopleGold',
  'drawSign',
  'frameWinner',
  'footballSign',
]

const notStartedBadgeStyle =
  'position: absolute; left: 0; top: 0; z-index: 2; padding: 1.5vw 3vw; border-radius: 7px 0; background: linear-gradient(152deg, #FB9631 7.01%, #B86F21 92.99%), linear-gradient(129deg, #823C1B 0%, #853D1D 14.44%, #AB6426 28.88%, #FF9A46 43.32%, #F28F28 57.76%, #AD6324 72.2%, #813D1C 96.26%); color: #FFF; font-size: 1em; font-weight: 500;'
const inProgressBadgeStyle =
  'position: absolute; left: 0; top: 0; z-index: 2; padding: 1.5vw 3vw; border-radius: 7px 0; background: linear-gradient(152deg, #31FB5E 7.01%, #21B843 92.99%), linear-gradient(129deg, #1B8230 0%, #1D8532 14.44%, #26AB26 28.88%, #46FF5F 43.32%, #28F22B 57.76%, #2DAD24 72.2%, #1C8132 96.26%); color: #FFF; font-size: 1em; font-weight: 500;'
const endedBadgeStyle =
  'position: absolute; left: 0; top: 0; z-index: 2; padding: 1.5vw 3vw; border-radius: 7px 0; background: linear-gradient(135deg, #484646 2.82%, #292424 99.15%), linear-gradient(129deg, #823C1B 0%, #853D1D 14.44%, #AB6426 28.88%, #FF9A46 43.32%, #F28F28 57.76%, #AD6324 72.2%, #813D1C 96.26%); color: #FFF; font-size: 1em; font-weight: 500;'
const betModuleStyle =
  'width: 100%; display: flex; flex-direction: column; gap: 3vw; padding: 3vw; box-sizing: border-box; border-radius: 12px; border: 1px solid #5D6948; background: linear-gradient(180deg, #0B2415 0%, #051C12 100%); backdrop-filter: blur(14.252873420715332px);'
const betOptionDefaultStyle =
  'flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: space-between; align-items: center; padding: 2vw 1.5vw; box-sizing: border-box; border-radius: 7.121px; border: 0.445px solid #E9D089; background: linear-gradient(180deg, rgba(79, 77, 33, 0.50) 0%, rgba(79, 77, 33, 0.00) 100%); backdrop-filter: blur(11.97230052947998px);'
const betOptionSelectedStyle =
  'flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: space-between; align-items: center; padding: 2vw 1.5vw; box-sizing: border-box; border-radius: 7.121px; border: 1px solid #FFFA5D; background: linear-gradient(180deg, rgba(79, 77, 33, 0.50) 0%, rgba(79, 77, 33, 0.00) 100%); backdrop-filter: blur(11.97230052947998px); box-shadow: -0.223px -0.223px 0.89px 0 #D6C100, 0.223px 0.223px 0.89px 0 #D6C100, 0 0 2.67px 0 rgba(255, 250, 93, 0.60), 0 0 4.451px 0 rgba(255, 250, 93, 0.40), 0 0 3.561px 0 rgba(210, 204, 0, 0.30);'
const betAmountButtonStyle =
  'flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 0.8vw; padding: 2vw 1vw; box-sizing: border-box; border-radius: 4px; border: 0.5px solid #E9D089; background: linear-gradient(180deg, rgba(79, 77, 33, 0.50) 0%, rgba(79, 77, 33, 0.00) 100%); backdrop-filter: blur(13.449894905090332px);'
const betAmountOptions = [100, 1000, 10000, 100000]
const predictionRecordModuleStyle =
  'width: 100%; height: 72vw; display: flex; flex-direction: column; gap: 3vw; padding: 3vw; box-sizing: border-box; border-radius: 12px; border: 1px solid #5D6948; background: linear-gradient(180deg, #0B2415 0%, #051C12 100%); backdrop-filter: blur(14.252873420715332px);'

// 是否允许提交押注：只有赛事未开始时展示金额按钮并允许点击押注对象。
const canSubmitBet = computed(() => Number(matchInfo.value.status) === 0)

// 当前用户是否至少有一个中奖押注：详情接口 myBets 或我的竞猜列表中 betStatus=1 / payout>0 都算中奖。
const hasWinBet = computed(() => {
  return myBets.value.some(
    (betItem) => Number(betItem.betStatus) === 1 || Number(betItem.payout) > 0,
  )
})

// 中奖金额汇总：结束且中奖状态展示所有中奖记录的 payout 合计。
const winAmount = computed(() => {
  return myBets.value.reduce((total, betItem) => total + (Number(betItem.payout) || 0), 0)
})

// 详情页押注对象数据：三列分别为主胜、平局、客胜，上方为选项奖池，下方为我的下注额。
const detailBetOptions = computed(() => [
  {
    option: 1,
    flagUrl: matchInfo.value.homeFlag,
    isOssImage: false,
    name: matchInfo.value.homeTeam || '',
    percent: matchInfo.value.homePercent,
    percentColor: '#71ce6e',
    myBetAmount: getMyBetAmountText(1),
    poolAmount: matchInfo.value.homePoolFormat || matchInfo.value.homePool || 0,
  },
  {
    option: 2,
    flagUrl: pngUrl('drawSign'),
    isOssImage: true,
    name: 'DRAW',
    percent: matchInfo.value.drawPercent,
    percentColor: '#a0a181',
    myBetAmount: getMyBetAmountText(2),
    poolAmount: matchInfo.value.drawPoolFormat || matchInfo.value.drawPool || 0,
  },
  {
    option: 3,
    flagUrl: matchInfo.value.awayFlag,
    isOssImage: false,
    name: matchInfo.value.awayTeam || '',
    percent: matchInfo.value.awayPercent,
    percentColor: '#71ce6e',
    myBetAmount: getMyBetAmountText(3),
    poolAmount: matchInfo.value.awayPoolFormat || matchInfo.value.awayPool || 0,
  },
])

// 本场竞猜记录列表：使用我的竞猜记录接口返回的 records，空数组时展示空态。
const predictionRecords = computed(() => myBets.value || [])

// 倒计时文案：未开始状态展示类似 2D 18 : 59 : 59。
const countdownText = computed(() => {
  const remaining = Math.max(0, Number(matchInfo.value.kickoffTime || 0) - nowTime.value)
  const totalSeconds = Math.floor(remaining / 1000)
  const days = Math.floor(totalSeconds / 86400)
  const hours = String(Math.floor((totalSeconds % 86400) / 3600)).padStart(2, '0')
  const minutes = String(Math.floor((totalSeconds % 3600) / 60)).padStart(2, '0')
  const seconds = String(totalSeconds % 60).padStart(2, '0')

  return `${days}D  ${hours} : ${minutes} : ${seconds}`
})

// 赛事结果状态配置：根据 status 和用户押注结果选择背景图、角标和主文案。
const resultStatusConfig = computed(() => {
  const status = Number(matchInfo.value.status)

  if (status === 0) {
    return {
      type: 'notStarted',
      image: 'statusNotStarted',
      badgeText: 'Not Started',
      badgeStyle: notStartedBadgeStyle,
      mainText: countdownText.value,
    }
  }

  if (status === 1) {
    return {
      type: 'inProgress',
      image: 'statusInProgress',
      badgeText: 'In Progress',
      badgeStyle: inProgressBadgeStyle,
      mainText: 'The match is underway',
    }
  }

  if (hasWinBet.value) {
    return {
      type: 'endedWin',
      image: 'statusEndedWin',
      badgeText: 'Ended',
      badgeStyle: endedBadgeStyle,
      mainText: '',
    }
  }

  return {
    type: 'endedFail',
    image: 'statusEndedfail',
    badgeText: 'Ended',
    badgeStyle: endedBadgeStyle,
    mainText: 'Better luck next time!',
  }
})

// 开赛时间文案：所有赛事状态都固定展示，时间内容统一由 kickoffTime 字段格式化。
const kickoffText = computed(() => {
  const kickoffTime = Number(matchInfo.value.kickoffTime || 0)
  if (!kickoffTime) return ''

  const kickoffDate = new Date(kickoffTime)
  const timeText = `${String(kickoffDate.getHours()).padStart(2, '0')}:${String(
    kickoffDate.getMinutes(),
  ).padStart(2, '0')}:${String(kickoffDate.getSeconds()).padStart(2, '0')}`
  const monthText = kickoffDate.toLocaleString('en-US', { month: 'long' })
  const dateText = `${kickoffDate.getDate()} ${monthText} ${kickoffDate.getFullYear()}`

  return `Kick-off is at ${timeText} on ${dateText}.`
})

// 赛事占比展示：接口返回数字时补百分号，已带百分号的字符串直接展示。
const formatMatchPercent = (percent) => {
  if (typeof percent === 'string' && percent.includes('%')) return percent
  const percentValue = percent === '' || percent === null || percent === undefined ? 0 : percent
  return `${percentValue}%`
}

// 格式化竞猜记录时间：展示为 MM-DD-YYYY HH:mm:ss。
const formatPredictionTime = (betTime) => {
  const timestamp = Number(betTime)
  if (!timestamp) return ''

  const betDate = new Date(timestamp)
  const month = String(betDate.getMonth() + 1).padStart(2, '0')
  const day = String(betDate.getDate()).padStart(2, '0')
  const year = betDate.getFullYear()
  const hours = String(betDate.getHours()).padStart(2, '0')
  const minutes = String(betDate.getMinutes()).padStart(2, '0')
  const seconds = String(betDate.getSeconds()).padStart(2, '0')

  return `${month}-${day}-${year} ${hours}:${minutes}:${seconds}`
}

// 按押注选项汇总我的竞猜金额：详情接口未返回格式化金额时用于兜底展示。
const getMyBetAmountSum = (option) => {
  return myBets.value.reduce((total, betItem) => {
    if (Number(betItem.betOption) !== Number(option)) return total
    return total + (Number(betItem.betAmount) || 0)
  }, 0)
}

// 获取我的押注金额展示：优先使用详情接口 my*BetFormat 字段，没有时按 myBets 兜底汇总。
const getMyBetAmountText = (option) => {
  const formatMap = {
    1: matchInfo.value.myHomeBetFormat,
    2: matchInfo.value.myDrawBetFormat,
    3: matchInfo.value.myAwayBetFormat,
  }
  const formatValue = formatMap[Number(option)]
  if (formatValue !== null && formatValue !== undefined && formatValue !== '') return formatValue

  const amountSum = getMyBetAmountSum(option)
  return amountSum || 0
}

// 判断用户是否押注过当前选项：已开赛或已结束时用于展示已押注项选中态。
const hasUserBetOnOption = (option) => {
  const formatMap = {
    1: matchInfo.value.myHomeBetFormat,
    2: matchInfo.value.myDrawBetFormat,
    3: matchInfo.value.myAwayBetFormat,
  }
  const formatValue = formatMap[Number(option)]
  if (formatValue !== null && formatValue !== undefined && formatValue !== '') return true
  return getMyBetAmountSum(option) > 0
}

// 押注对象样式：未开始时只展示用户当前点击选中态，已开始后展示用户历史押注态。
const getDetailBetOptionStyle = (option) => {
  if (canSubmitBet.value) {
    return Number(selectedBetOption.value) === Number(option)
      ? betOptionSelectedStyle
      : betOptionDefaultStyle
  }

  return hasUserBetOnOption(option) ? betOptionSelectedStyle : betOptionDefaultStyle
}

// 已结束胜方标识：只有已结束赛事根据 result 字段给对应押注项叠加 frameWinner。
const isDetailBetOptionWinner = (option) => {
  return Number(matchInfo.value.status) === 2 && Number(matchInfo.value.result) === Number(option)
}

// 点击押注对象：仅未开始赛事允许选择押注对象，默认不选中任何项。
const handleBetOptionClick = (option) => {
  if (!canSubmitBet.value) return
  selectedBetOption.value = option
}

// 加载赛事详情：详情接口提供比赛基础信息、奖池明细和我的本场竞猜列表。
const loadMatchDetail = async () => {
  if (!matchId.value) return

  const detailRes = await apiGetWorldCupMatchDetail(matchId.value)
  const detailBody = detailRes.body || detailRes
  matchInfo.value = {
    ...(detailBody.match || {}),
    homePool: detailBody.homePool ?? 0,
    drawPool: detailBody.drawPool ?? 0,
    awayPool: detailBody.awayPool ?? 0,
    homePoolFormat: detailBody.match?.homePoolFormat ?? detailBody.homePoolFormat ?? '',
    drawPoolFormat: detailBody.match?.drawPoolFormat ?? detailBody.drawPoolFormat ?? '',
    awayPoolFormat: detailBody.match?.awayPoolFormat ?? detailBody.awayPoolFormat ?? '',
    myHomeBetFormat: detailBody.match?.myHomeBetFormat ?? detailBody.myHomeBetFormat ?? null,
    myDrawBetFormat: detailBody.match?.myDrawBetFormat ?? detailBody.myDrawBetFormat ?? null,
    myAwayBetFormat: detailBody.match?.myAwayBetFormat ?? detailBody.myAwayBetFormat ?? null,
  }
  myBets.value = detailBody.myBets || []
}

// 加载我的竞猜记录：页面后续押注状态模块需要用到，当前作为详情接口 myBets 的补充。
const loadMyBetList = async () => {
  if (!matchId.value) return

  const betRes = await apiPostWorldCupMyBetList({
    size: 100,
    current: 1,
    matchId: matchId.value,
  })
  const betBody = betRes.body || betRes
  const records = betBody.records || []
  myBets.value = records
}

// 页面初始化接口：连接 App 并写入请求头后，再独立拉取赛事详情和我的竞猜记录。
const loadInitialEventDetailData = async () => {
  try {
    await loadMatchDetail()
    await loadMyBetList()
  } catch (error) {
    console.error('WorldCup 赛事详情加载失败:', error)
  }
}

// 首屏预加载：只处理阻塞图片，不等待接口数据返回。
const completePreloading = async () => {
  try {
    await preloadImages(blockingImages.map((imageName) => pngUrl(imageName)))
  } catch (error) {
    console.error('WorldCup 赛事详情图片预加载失败:', error)
  } finally {
    isLoading.value = false
  }
}

// 连接 App 并设置接口请求头：详情页所有接口请求必须在 connectToApp 成功后执行。
const connectToAppHandler = async () => {
  await connectToApp(() => {
    loadInitialEventDetailData()
  })
}

// 押注接口占位：后续第三模块接入押注按钮时统一调用该方法。
const submitWorldCupBet = async (betOption, betAmount) => {
  if (!matchId.value) return
  return apiPostWorldCupBet({
    matchId: String(matchId.value),
    betOption,
    betAmount,
  })
}

// 点击押注金额：先校验是否已选押注对象，再提交押注并刷新详情数据。
const handleBetAmountClick = async (betAmount) => {
  if (!canSubmitBet.value) return
  if (!selectedBetOption.value) {
    showWarning('Please select a prediction option first.')
    return
  }
  if (isSubmittingBet.value) return

  try {
    isSubmittingBet.value = true
    await submitWorldCupBet(selectedBetOption.value, betAmount)
    showSuccess('Bet placed successfully.')
    selectedBetOption.value = null
    await loadMatchDetail()
    await loadMyBetList()
  } catch (error) {
    showError(error.response?.errorMsg || error.errorMsg || error.message || 'Bet failed')
  } finally {
    isSubmittingBet.value = false
  }
}

onMounted(() => {
  countdownTimer = window.setInterval(() => {
    nowTime.value = Date.now()
  }, 1000)
  completePreloading()
  connectToAppHandler()
})

onBeforeUnmount(() => {
  if (countdownTimer) {
    window.clearInterval(countdownTimer)
    countdownTimer = null
  }
})
</script>

<style lang="scss" scoped>
* {
  color: #fff;
}

.world-cup-event-detail-scroll::-webkit-scrollbar {
  display: none;
}

@media screen and (max-width: 360px) {
  * {
    font-size: 10px;
  }
}

@media screen and (min-width: 360px) {
  * {
    font-size: 12px;
  }
}

@media screen and (min-width: 768px) {
  * {
    font-size: 24px;
  }
}

@media screen and (min-width: 1024px) {
  * {
    font-size: 32px;
  }
}
</style>
