<template>
  <div class="pc-home-container">

    <div class="hero-section">
      <el-skeleton :loading="isLoading" animated>
        <template #default>
          <div class="main-carousel-wrapper" v-if="banners2 && banners2.length">
            <el-carousel height="100%" class="main-carousel" trigger="click">
              <el-carousel-item v-for="(item, index) in banners2" :key="index" @click="goActive(item)">
                <el-image :src="item.image" fit="cover" class="carousel-img" />
              </el-carousel-item>
            </el-carousel>
          </div>

          <!-- <div class="sub-banners-wrapper" v-if="banners1 && banners1.length">
            <div class="sub-banner-card" v-for="(item, index) in banners1" :key="index">
              <div class="img-box">
                <el-image :src="item.detail_image" fit="contain" class="sub-img" />
              </div>
              <div class="title-box">
                <span class="sub-title" :title="item.title">{{ item.title }}</span>
              </div>
            </div>
          </div> -->
        </template>
      </el-skeleton>
    </div>

    <div class="main-split-layout">

      <div class="layout-left-sports">
        <div class="section-header">
          <div class="header-title">
            <div class="decorate-bar"></div>
            <span>{{ t('体育赛事') }}</span>
          </div>
          <el-button link type="primary" class="more-btn" @click="toMoreRollBall('SportsBetting')">
            {{ t('更多体育赛事') }} <el-icon class="ml-1"><ArrowRight /></el-icon>
          </el-button>
        </div>

        <el-skeleton :loading="isLoading" animated>
          <template #template>
            <div class="sports-grid">
              <div class="match-card" v-for="i in 4" :key="i">
                <div class="league-info">
                  <el-skeleton-item variant="text" style="width: 40%;" />
                  <el-skeleton-item variant="text" style="width: 20%;" />
                </div>
                <div class="teams-container">
                  <div class="team-item">
                    <div class="team-info">
                      <el-skeleton-item variant="circle" style="width: 28px; height: 28px; margin-right: 10px; flex-shrink: 0;" />
                      <el-skeleton-item variant="text" style="width: 100px;" />
                    </div>
                  </div>
                  <div class="team-item mt-2">
                    <div class="team-info">
                      <el-skeleton-item variant="circle" style="width: 28px; height: 28px; margin-right: 10px; flex-shrink: 0;" />
                      <el-skeleton-item variant="text" style="width: 120px;" />
                    </div>
                  </div>
                </div>
                <div class="odds-group">
                  <div class="odds-grid-inner">
                    <el-skeleton-item variant="button" class="odds-btn" v-for="j in 3" :key="j" />
                  </div>
                </div>
              </div>
            </div>
          </template>

          <template #default>
            <div class="sports-grid" v-if="gamblingList.length > 0">
              <div class="match-card" v-for="item in gamblingList" :key="item.id" @click="goDetail(item)">

                <div class="league-info">
                  <div class="league-left">
                    <el-icon color="#f8b932" size="16" class="mr-1"><Trophy /></el-icon>
                    <span class="league-name" :title="item.league">{{ item.league }}</span>
                  </div>
                  <div class="match-time-status">
                    <span class="match-score" v-if="[1, 2].includes(item.state)">{{ item.score || '0-0' }}</span>
                    <span class="match-status" :class="{'is-live': item.state === 1}">{{ getStatusText(item.state) }}</span>
                  </div>
                </div>

                <div class="teams-container">
                  <div class="team-item">
                    <div class="team-info">
                      <el-avatar :src="item.home_team_logo" :size="28" class="team-logo"></el-avatar>
                      <span class="team-name" :title="item.home_team">{{ item.home_team }}</span>
                      <el-tag size="small" type="success">{{ t('主') }}</el-tag>
                    </div>
                    <span class="team-score" v-if="item.score && item.score !== '-'">{{ item.score.split('-')[0] }}</span>
                  </div>

                  <div class="team-item mt-2">
                    <div class="team-info">
                      <el-avatar :src="item.guest_team_logo" :size="28" class="team-logo"></el-avatar>
                      <span class="team-name" :title="item.guest_team">{{ item.guest_team }}</span>
                      <el-tag size="small" type="danger">{{ t('客') }}</el-tag>
                    </div>
                    <span class="team-score" v-if="item.score && item.score !== '-'">{{ item.score.split('-')[1] }}</span>
                  </div>
                </div>

                <div class="odds-group" v-if="[0, 1].includes(item.state)">
                  <template v-if="item.odds && item.odds.length > 0 && item.odds[0].values">
                    <div class="odds-grid-inner">
                      <div
                          class="odds-btn"
                          v-for="(opt, optIndex) in getVisibleSportsValues(item.odds[0].values)"
                          :key="optIndex"
                          :class="{
                            'is-locked': isOptionLocked(item, opt),
                            'is-active': isSelected(item.id, item.odds[0].id, opt),
                            'odds-up': isOddsUp(getOddsKey(item.id, item.odds[0].id, opt)) && !isOptionLocked(item, opt),
                            'odds-down': isOddsDown(getOddsKey(item.id, item.odds[0].id, opt)) && !isOptionLocked(item, opt)
                          }"
                      >
                        <div class="odds-name-wrapper">
                          <span class="selection-name" :title="getFormattedSelectionName(item.odds[0].name, opt)">
                            {{ getFormattedSelectionName(item.odds[0].name, opt) }}
                            <span v-if="opt.handicap_text"  class="handicap-val">
                              {{ opt.handicap_text }}
                            </span>
                          </span>
                        </div>
                        <div class="odds-val-wrapper">
                          <span class="odds-val">{{ opt.odd || '-' }}</span>

                          <el-icon v-if="isOddsUp(getOddsKey(item.id, item.odds[0].id, opt)) && !isOptionLocked(item, opt)" class="change-icon up">
                            <CaretTop />
                          </el-icon>
                          <el-icon v-else-if="isOddsDown(getOddsKey(item.id, item.odds[0].id, opt)) && !isOptionLocked(item, opt)" class="change-icon down">
                            <CaretBottom />
                          </el-icon>

                          <el-icon v-if="isOptionLocked(item, opt)" class="lock-icon"><Lock /></el-icon>
                        </div>
                      </div>

                      <div
                          class="odds-btn expand-btn"
                          v-if="item.odds_count > 0"
                          @click.stop="goDetail(item)"
                      >
                        <span class="plus-icon">+</span>
                        <span class="remain-count">{{ item.odds_count }}</span>
                      </div>
                    </div>
                  </template>
                </div>

              </div>
            </div>

            <el-empty v-else :description="t('暂无赛事数据')" />
          </template>
        </el-skeleton>
      </div>

    </div>

    <div class="main-split-layout">
      <div class="layout-left-sports">
        <div class="section-header">
              <div class="header-title">
                <div class="decorate-bar"></div>
                <span>{{ t('彩票') }}</span>
              </div>
              <el-button link type="primary" class="more-btn" @click="toMoreRollBall('EntertainmentList')">
                {{ t('更多彩票玩法') }} <el-icon class="ml-1"><ArrowRight /></el-icon>
              </el-button>
        </div>

        <EntertList />
      </div>
   
    </div>


  </div>
</template>

<script setup>
import { ref, watch, onMounted, onUnmounted } from "vue";
import { useRouter } from "vue-router";
import { useI18n } from "vue-i18n";
import { ArrowRight, Trophy, Lock, CaretTop, CaretBottom } from '@element-plus/icons-vue';

import { getActivity, getBanner, getSportSchedule } from "@/request/api.js";
import { useOrderStore } from "@/store/bettingSheet.js";
import socket from '@/utils/websocket.js'
import EntertList from '../EntertainmentList/components/list.vue';

const { t } = useI18n();
const router = useRouter();
const orderStore = useOrderStore();

const isLoading = ref(true);

const banners1 = ref([]);
const banners2 = ref([]);
const gamblingList = ref([]);
const limit = ref(8);
const selectedMap = ref({});

// ====================== 赔率变化闪烁逻辑（3秒） ======================
const oddsChangeMap = ref(new Map())

const getOddsKey = (matchId, marketId, selection) => {
  if (selection.handicap !== null && selection.handicap !== undefined && selection.handicap !== '') {
    return `${matchId}_${marketId}_${selection.value}_${selection.handicap}`
  }
  return `${matchId}_${marketId}_${selection.value}`
}

const isOddsUp = (key) => {
  const change = oddsChangeMap.value.get(key)
  return change?.direction === 'up' && (Date.now() - change.timestamp < 3000)
}

const isOddsDown = (key) => {
  const change = oddsChangeMap.value.get(key)
  return change?.direction === 'down' && (Date.now() - change.timestamp < 3000)
}
// ====================== 闪烁逻辑结束 ======================

const getVisibleSportsValues = (values) => {
  if (!values) return [];
  return values.slice(0, 3);
};

const translateSelection = (valStr) => {
  if (valStr === undefined || valStr === null) return '';
  return String(valStr);
};

const getFormattedSelectionName = (marketName, opt) => {
  const translatedValue = translateSelection(opt.value_text);
  if (!opt.handicap && (translatedValue === '1' || translatedValue === '2' || translatedValue === 'Yes' || translatedValue === 'No')) {
    return `${marketName} - ${translatedValue}`;
  }
  return translatedValue;
};

const getUniqueKey = (matchId, marketId, selection) => {
  if (selection.handicap !== null && selection.handicap !== undefined && selection.handicap !== '') {
    return `${matchId}_${marketId}_${selection.value}_${selection.handicap}`;
  }
  return `${matchId}_${marketId}_${selection.value}`;
};

const checkIsLocked = (item) => {
  if (!item) return true;
  if (Number(item.is_locked) === 1) return true;
  if (item.status !== undefined && Number(item.status) !== 1) return true;
  if (item.state !== undefined && item.state !== 0 && item.state !== 1) return true;
  return false;
};

const isOptionLocked = (item, opt) => {
  if (checkIsLocked(item)) return true;
  if (!opt || !opt.odd || opt.odd === '-' || Number(opt.odd) === 0) return true;
  if (opt.suspended === true || String(opt.suspended).toLowerCase() === 'true') return true;
  if (item.odds && item.odds[0] && item.odds[0].is_findLocked) return true;
  return false;
};

const syncFromStore = () => {
  const map = {};
  if (orderStore.selectOrders && orderStore.selectOrders.length) {
    orderStore.selectOrders.forEach(order => {
      if (order.uniqueKey) map[order.uniqueKey] = true;
    });
  }
  selectedMap.value = map;
};

watch(() => orderStore.selectOrders, () => syncFromStore(), { deep: true, immediate: true });

// ==========================================
// 核心数据初始化
// ==========================================
const initData = async () => {
  isLoading.value = true;
  try {
    const [resB1, resB2, resGambling] = await Promise.all([
      getActivity({ type: 2 }),
      getBanner({ type: 'pc' }),
      getSportSchedule({ page: 1, limit: limit.value, state: 1, is_rec: 1 })
    ]);

    banners1.value = resB1.data?.list || [];
    banners2.value = resB2.data?.list || [];

    let currentGamblingList = resGambling.data?.list || [];
    if (currentGamblingList.length === 0) {
      const fallback = await getSportSchedule({ page: 1, limit: limit.value, state: 0, is_rec: 1 });
      currentGamblingList = fallback.data?.list || [];
    }

    gamblingList.value = (currentGamblingList || []).map(item => {
      if (typeof item.odds === 'string') {
        try { item.odds = JSON.parse(item.odds); } catch(e) { item.odds = []; }
      }
      if (item.odds && item.odds.length > 0) {
        item.odds.forEach(jtem => {
          if (item.odd_ids_locked && item.odd_ids_locked.find(trim => jtem.id === trim)) {
            jtem.is_findLocked = true;
          }
        });
      }
      return item;
    });

  } catch (error) {
    console.error('首页数据加载失败', error);
  } finally {
    isLoading.value = false;
  }
};

const goDetail = (item) => router.push({ name: 'SportDetail', query: { data_id: item.data_id } });
const toMoreRollBall = (name) => router.push({ name });

const getStatusText = (state) => {
  const states = { 0: t("未开始"), 1: t("进行中"), 2: t("已完场"), 3: t("延期"), 4: t("取消") };
  return states[state] || "";
};

const isSelected = (matchId, marketId, selection) => {
  if (!selection) return false;
  const uniqueKey = getUniqueKey(matchId, marketId, selection);
  return !!selectedMap.value[uniqueKey];
};

// ==========================================
// WebSocket 监听（包含3秒闪烁检测）
// ==========================================
const handleSocketMessage = (e) => {
  try {
    const res = e.detail;
    if (!res) return;

    if (res.type === 'sport_list' && Array.isArray(res.message)) {
      res.message.forEach((newMatch) => {
        const idx = gamblingList.value.findIndex(item => item.data_id === newMatch.data_id);
        if (idx !== -1) {
          const oldMatch = gamblingList.value[idx];

          // === 3秒闪烁检测 ===
          let parsedNewOdds = newMatch.odds;
          if (typeof parsedNewOdds === 'string') {
            try { parsedNewOdds = JSON.parse(parsedNewOdds); } catch(e) { parsedNewOdds = []; }
          }
          if (oldMatch.odds?.[0] && parsedNewOdds?.[0]) {
            const oldMarket = oldMatch.odds[0];
            const newMarket = parsedNewOdds[0];
            if (oldMarket.values && newMarket.values) {
              newMarket.values.forEach(newOpt => {
                const oldOpt = oldMarket.values.find(o =>
                    o.value === newOpt.value &&
                    (o.handicap == newOpt.handicap || (!o.handicap && !newOpt.handicap))
                );
                if (oldOpt?.odd && newOpt?.odd) {
                  const oldNum = parseFloat(oldOpt.odd);
                  const newNum = parseFloat(newOpt.odd);
                  if (!isNaN(oldNum) && !isNaN(newNum) && oldNum !== newNum) {
                    const key = getOddsKey(oldMatch.id, newMarket.id, newOpt);
                    const direction = newNum > oldNum ? 'up' : 'down';
                    oddsChangeMap.value.set(key, { direction, timestamp: Date.now() });
                    setTimeout(() => oddsChangeMap.value.delete(key), 3100);
                  }
                }
              });
            }
          }

          gamblingList.value[idx] = { ...oldMatch, ...newMatch };
          if (typeof orderStore.updateMatchStatus === 'function') {
            orderStore.updateMatchStatus(newMatch.data_id, newMatch);
          }
        }
      });
    }

  } catch (error) {}
};

const goActive = (item) => {
  console.log(item, 394);
  
  if (item.link) {
      router.push({ name: 'PromotionDetail', query: { id: item.link } });
  }
};

onMounted(() => {
  syncFromStore();
  initData();
  socket.eventBus.addEventListener('onSocketMessage', handleSocketMessage);
});

onUnmounted(() => {
  socket.eventBus.removeEventListener('onSocketMessage', handleSocketMessage);
});
</script>

<style scoped lang="scss">
$main-color: #f8b932;
$card-bg: var(--el-bg-color-overlay);
$border-color: var(--el-border-color-lighter);
$hover-bg: var(--el-fill-color-light);

.pc-home-container {
  container-type: inline-size;
  min-height: 100%;
  padding: 24px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 24px;
  @container (max-width: 1200px) { padding: 16px; gap: 16px; }
  @container (max-width: 800px) { padding: 12px; gap: 12px; }
  @container (max-width: 550px) { padding: 8px; gap: 8px; }
}

/* =======================================
   1. 顶部视界区 (Hero Section)
   ======================================= */
.hero-section {
  display: flex; flex-direction: column; gap: 16px;
  .main-carousel-wrapper {
    width: 100%;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: var(--el-box-shadow-light);
    aspect-ratio: 1920 / 292;
    @media (max-width: 768px) {
      aspect-ratio: 480 / 73;
    }
    .carousel-img {
      width: 100%;
      height: 100%;
    }
    :deep(.el-carousel) { height: 100%; }
    :deep(.el-carousel__container) { height: 100% !important; }
  }
  .sub-banners-wrapper {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px;
    @container (max-width: 1350px) { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
    @container (max-width: 992px) { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
    @container (max-width: 550px) { grid-template-columns: repeat(2, 1fr); gap: 10px; }
    .sub-banner-card {
      background-color: $card-bg; border-radius: 8px; border: 1px solid $border-color; overflow: hidden; display: flex; flex-direction: column; box-shadow: 0 2px 8px rgba(0,0,0,0.02); transition: transform 0.2s; cursor: pointer;
      &:hover { transform: translateY(-2px); box-shadow: var(--el-box-shadow-light); }
      .img-box {
        width: 100%; height: 120px;
        @container (max-width: 992px) { height: 90px; }
        @container (max-width: 550px) { height: 70px; }
        .sub-img { width: 100%; height: 100%; }
      }
      .title-box {
        padding: 12px; text-align: center;
        @container (max-width: 800px) { padding: 8px; }
        .sub-title { font-size: 14px; font-weight: bold; color: var(--el-text-color-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; @container (max-width: 800px) { font-size: 11px; } }
      }
    }
  }
}

/* =======================================
   2. 主体分栏 (Split Layout)
   ======================================= */
.main-split-layout {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: flex-start;
  width: 100%;
  @container (max-width: 1350px) { gap: 20px; }
  @container (max-width: 992px) { gap: 16px; }
  @container (max-width: 800px) { gap: 10px; }
  @container (max-width: 550px) { gap: 0; }

  /* --- 左侧体育赛事 --- */
  .layout-left-sports {
    flex: 1;
    min-width: 300px;
    @container (max-width: 550px) {
      min-width: 100%;
      margin-bottom: 16px;
    }
    .section-header {
      display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;
      .header-title { display: flex; align-items: center; font-size: 18px; font-weight: bold; color: var(--el-text-color-primary); @container (max-width: 800px) { font-size: 14px; } .decorate-bar { width: 4px; height: 18px; background-color: $main-color; border-radius: 2px; margin-right: 10px; } }
      .more-btn { font-size: 14px; font-weight: bold; @container (max-width: 800px) { font-size: 12px; } }
    }
    .sports-grid {
      display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px;
      @container (max-width: 1200px) { grid-template-columns: 1fr; }
    }
    .match-card {
      background-color: $card-bg; border-radius: 8px; border: 1px solid $border-color; padding: 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.02); transition: border-color 0.2s; cursor: pointer;
      @container (max-width: 800px) { padding: 12px; }
      @container (max-width: 400px) { padding: 10px; }
      &:hover { border-color: var(--el-border-color); }
      .league-info {
        display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; border-bottom: 1px dashed $border-color; padding-bottom: 12px;
        @container (max-width: 800px) { margin-bottom: 12px; padding-bottom: 8px; }
        .league-left { display: flex; align-items: center; flex: 1; overflow: hidden; .league-name { font-size: 14px; font-weight: bold; color: var(--el-text-color-regular); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @container (max-width: 800px){ font-size: 12px; } } }
        .match-time-status { font-size: 13px; @container (max-width: 800px){ font-size: 11px; } .match-score { color: var(--el-text-color-secondary); margin-right: 6px; } .match-status { color: var(--el-text-color-regular); &.is-live { color: var(--el-color-danger); font-weight: bold; } } }
      }
      .teams-container {
        display: flex; flex-direction: column; margin-bottom: 16px;
        .team-item {
          display: flex; justify-content: space-between; align-items: center;
          @container (max-width: 400px) { margin-top: 6px; }
          .team-info { display: flex; align-items: center; gap: 10px; flex: 1; overflow: hidden; .team-name { font-size: 15px; font-weight: 500; color: var(--el-text-color-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @container (max-width: 800px){ font-size: 13px; } } }
          .team-score { font-size: 16px; font-weight: 800; color: var(--el-text-color-primary); }
        }
      }
      .odds-group .odds-grid-inner {
        display: flex; gap: 8px; width: 100%;
        .odds-btn {
          flex: 1; min-width: 0; background-color: var(--el-fill-color); border: 1px solid var(--el-border-color); border-radius: 6px; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 8px 4px; height: 54px; box-sizing: border-box; transition: all 0.2s; cursor: pointer; position: relative; overflow: hidden; gap: 4px;
          @container (max-width: 800px) { height: 44px; padding: 4px; }
          @container (max-width: 400px) { height: 36px; padding: 2px; }
          .odds-name-wrapper {
            display: flex; align-items: center; justify-content: center; width: 100%; z-index: 1;
            .selection-name { font-size: 12px; color: var(--el-text-color-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @container (max-width: 800px){ font-size: 10px; transform: scale(0.9); } @container (max-width: 400px){ transform: scale(0.8); } }
            .handicap-val { color: var(--el-text-color-primary); font-weight: bold; margin-left: 4px; font-size: 12px; @container (max-width: 800px){ font-size: 10px; transform: scale(0.9); } }
          }
          .odds-val-wrapper {
            display: flex; align-items: center; justify-content: center; gap: 4px; z-index: 1;
            .odds-val { font-size: 15px; font-weight: bold; color: $main-color; @container (max-width: 800px){ font-size: 12px; } @container (max-width: 400px){ font-size: 11px; } }
          }
          &.is-active { background-color: $main-color; border-color: $main-color; .odds-name-wrapper .selection-name, .odds-name-wrapper .handicap-val, .odds-val-wrapper .odds-val { color: #fff; } }
          &.is-locked { cursor: not-allowed; border-color: transparent; .selection-name, .handicap-val, .odds-val { opacity: 0.3; } &::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.4); z-index: 2; } .lock-icon { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #fff; font-size: 16px; z-index: 3; } }
          &.expand-btn { flex-direction: row; background-color: transparent; border: 1px dashed var(--el-border-color-darker); .plus-icon { font-size: 16px; color: var(--el-text-color-secondary); margin-right: 4px; } .remain-count { font-size: 14px; font-weight: bold; color: var(--el-text-color-secondary); } &:hover { border-color: $main-color; .plus-icon, .remain-count { color: $main-color; } } }

          &.odds-up .odds-val { color: #4caf50 !important; transition: color 0.3s; }
          &.odds-down .odds-val { color: #f56c6c !important; transition: color 0.3s; }
          .change-icon {
            margin-left: 4px;
            font-size: 14px;
            &.up { color: #4caf50; }
            &.down { color: #f56c6c; }
          }
        }
      }
    }
  }

}

.mr-1 { margin-right: 4px; } .mt-2 { margin-top: 8px; } .ml-1 { margin-left: 4px; } .mt-4 { margin-top: 16px; }
:deep(.el-avatar) { @container (max-width: 800px) { width: 22px !important; height: 22px !important; } @container (max-width: 400px) { width: 18px !important; height: 18px !important; } }

@keyframes oddsFlash {
  0% { transform: scale(1); }
  50% { transform: scale(1.08); }
  100% { transform: scale(1); }
}
</style>