<template>
  <div class="pc-sports-list-container">
    <div class="list-wrapper layout-column">
      <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-image :src="item.pc_banner" fit="cover" class="carousel-img" />
              </el-carousel-item>
            </el-carousel>
      </div>
      <div class="search-segment-bar" v-if="false">
        <el-scrollbar>
          <div class="sport-segment-container">
            <div
                class="sport-segment-item"
                v-for="(item, index) in sportCategoryList"
                :key="index"
                :class="{ 'is-active': currentSportIndex === index }"
                @click="onSportCategoryChange(index)"
            >
              <span class="sport-icon">{{ item.icon }}</span>
              <span class="sport-name">{{ t(item.name) }}</span>
            </div>
          </div>
        </el-scrollbar>
      </div>

      <div class="top-filter-bar">
        <div class="top-tabs">
          <div
              v-for="tab in tabList"
              :key="tab.value"
              class="top-tab-item"
              :class="{ 'is-active': currentState === tab.value }"
              @click="onTabChange(tab.value)"
          >
            {{ tab.name }}
          </div>
        </div>

        <div class="top-actions">
          <div class="search-box">
            <el-input
                v-model="keyword"
                :placeholder="t('搜索赛事关键字')"
                clearable
                @keyup.enter="onSearch"
                @clear="onSearch"
                class="search-input"
            >
              <template #append>
                <el-button @click="onSearch">
                  <el-icon><Search /></el-icon>
                </el-button>
              </template>
            </el-input>
          </div>
          <el-button plain @click="onRefresh" :title="t('刷新数据')">
            <el-icon class="mr-1"><RefreshRight /></el-icon>
            <span>{{ t('刷新') }}</span>
          </el-button>

          <el-button
              link
              type="primary"
              @click="router.push({name: 'AllHistory', query: { tab: 1 }})"
          >
            <el-icon class="mr-1"><DataBoard /></el-icon>
            <span>{{ t('投注历史') }}</span>
          </el-button>
        </div>
      </div>

      <SportDateFilter :state="currentState" v-model:date="currentDate" @change="dateChange" v-show="currentState !== 1 && currentState !== 'league'" />

      <div class="right-content">
        
        <LeagueList v-if="currentState === 'league'" :keyword="keyword" ref="leagueListRef" />

        <div class="match-list-body" v-show="currentState !== 'league'">
          <el-scrollbar height="100%" ref="scrollbarRef" @scroll="onScroll" @end-reached="onLoadMore">
            <el-skeleton :loading="skeletonLoading" animated>
              <template #template>
                <div class="match-card" v-for="i in 5" :key="i">
                  <div class="match-card-header">
                    <div class="league-info">
                      <div class="decorate-bar"></div>
                      <el-skeleton-item variant="circle" style="width: 16px; height: 16px; margin-right: 6px;" />
                      <el-skeleton-item variant="text" style="width: 80px;" />
                    </div>
                    <div class="match-status-time">
                      <el-skeleton-item variant="text" style="width: 40px; margin-right: 8px;" />
                      <el-skeleton-item variant="text" style="width: 100px;" />
                    </div>
                  </div>

                  <div class="match-card-main">
                    <div class="match-teams">
                      <div class="team-row">
                        <div class="team-info">
                          <el-skeleton-item variant="circle" style="width: 18px; height: 18px;" />
                          <el-skeleton-item variant="text" style="width: 60px; margin-left: 6px;" />
                        </div>
                        <el-skeleton-item variant="text" style="width: 20px;" />
                      </div>
                      <div class="team-row mt-3">
                        <div class="team-info">
                          <el-skeleton-item variant="circle" style="width: 18px; height: 18px;" />
                          <el-skeleton-item variant="text" style="width: 80px; margin-left: 6px;" />
                        </div>
                        <el-skeleton-item variant="text" style="width: 20px;" />
                      </div>
                      <span class="time-text"></span>
                    </div>

                    <div class="match-odds-grids">
                      <div class="market-col" v-for="j in 3" :key="j">
                        <div style="display: flex; justify-content: center;">
                          <el-skeleton-item variant="text" style="width: 60px; margin-bottom: 4px;" />
                        </div>
                        <div class="market-values">
                          <el-skeleton-item variant="button" class="odds-btn" style="border: none;" v-for="k in 3" :key="k" />
                        </div>
                      </div>
                    </div>

                    <div class="match-more-toggle">
                      <el-skeleton-item variant="text" style="width: 30px;" />
                    </div>
                  </div>
                </div>
              </template>

              <template #default>
                <div :style="{ paddingTop: listPaddingTop + 'px', paddingBottom: listPaddingBottom + 'px' }">
                  <div class="match-card" v-for="item in visibleSportList" :key="item.data_id || item.id" :ref="el => handleItemRef(el, item.data_id || item.id)">

                    <div class="match-card-header">
                      <div class="league-info">
                        <div class="decorate-bar"></div>
                        <el-avatar v-if="item.league_logo" :src="item.league_logo" :size="16" style="margin-right: 6px; background-color: transparent;"></el-avatar>
                        <span class="league-name" :title="locale === 'zh' ? item.league : item.league_en">{{ locale === 'zh' ? item.league : item.league_en }}</span>
                        <el-tag style="margin-left: 10px" size="small" v-if="item.state === 1 && item.fixture_status">
                          {{ t(item.fixture_status?.long) }}
                        </el-tag>
                        <el-tag v-if="item.is_roll === 1" style="margin-left: 10px">{{ t('滚球') }}</el-tag>
                        <span v-if="item.state === 1" style="font-size: 12px;color: #999;margin-left: 10px">
                          <template v-if="item.fixture_status">
                            {{ item.fixture_status?.seconds }}
                          </template>
                        </span>
                      </div>
                      <div class="match-status-time">
                        <span style="font-size: 13px;color: #999">
                          {{ item.game_time || '--:--' }}
                        </span>
                      </div>
                    </div>

                    <div class="match-card-main" @click="goDetail(item)">
                      <div class="match-teams">
                        <div class="team-row">
                          <div style="display: flex;align-items: center;gap: 6px;">
                            <div class="team-info">
                              <el-avatar :src="item.home_team_logo" :size="24" class="team-logo"></el-avatar>
                              <span class="team-name" :title="locale === 'zh' ? item.home_team : item.home_team_en">
                                {{ locale === 'zh' ? item.home_team : item.home_team_en }}
                              </span>
                            </div>
                            <el-tag size="small" type="success">{{ t('主') }}</el-tag>
                          </div>
                          <span class="team-score" v-if="item.state !== 0" :class="{'text-live': item.state === 1}">
                            {{ getScore(item.score, 0) }}
                          </span>
                        </div>

                        <div class="team-row mt-3">
                          <div style="display: flex;align-items: center;gap: 6px;">
                            <div class="team-info">
                              <el-avatar :src="item.guest_team_logo" :size="24" class="team-logo"></el-avatar>
                              <span class="team-name" :title="locale === 'zh' ? item.guest_team : item.guest_team_en">{{ locale === 'zh' ? item.guest_team : item.guest_team_en }}</span>
                            </div>
                            <el-tag size="small" type="danger">{{ t('客') }}</el-tag>
                          </div>
                          <span class="team-score" v-if="item.state !== 0" :class="{'text-live': item.state === 1}">
                            {{ getScore(item.score, 1) }}
                          </span>
                        </div>
                      </div>

                      <div class="match-odds-grids">
                        <template v-if="[0, 1].includes(item.state) && item.odds && item.odds.length > 0">
                          <div class="market-col" v-for="(market, m) in item.odds.slice(0, 3)" :key="market.id">
                            <div class="market-name" :title="locale === 'zh' ? market.name : market.name_en">{{ locale === 'zh' ? market.name : market.name_en }}</div>

                            <div class="preview-pair-headers" v-if="market.preHeaders && market.preHeaders.length > 0">
                              <div class="preview-pair-item" v-for="(h, idx) in market.preHeaders" :key="idx">{{ h }}</div>
                            </div>
                            <div class="preview-pair-headers" v-else></div> 
                            
                            <div :class="['market-values', m > 0 ? 'market-values-border-left' : '']">
                              <div
                                  class="odds-btn"
                                  v-for="(opt, optIndex) in market.previewValues"
                                  :key="optIndex"
                                  :class="{
                                    'is-locked': item.is_locked || opt.suspended || !opt.odd || market.is_findLocked,
                                    'is-active': isSelected(item.id, market.id, opt),
                                    'odds-up': isOddsUp(getOddsKey(item.id, market.id, opt)),
                                    'odds-down': isOddsDown(getOddsKey(item.id, market.id, opt)),
                                    'is-centered-odds': opt.isCentered
                                  }"
                                  :style="{
                                    flexDirection: Boolean(!opt.odd || opt.suspended || item.is_locked || market.is_findLocked) ? 'column' : 'row',
                                  }"
                                  @click.stop="handleOddsClick(item, market, opt)"
                              >
                                <div class="odds-name-wrapper" v-if="!opt.isCentered || opt.handicap_text">
                                  <span class="selection-name" style="margin-right: 4px" v-if="!opt.isCentered" :title="locale === 'zh' ? opt.value_text : opt.value">
                                    {{ opt.displayName }}
                                  </span>
                                  <span class="handicap-val" v-if="opt.handicap_text">{{ opt.handicap_text }}</span>
                                </div>

                                <div class="odds-val-wrapper">
                                  <el-icon v-if="!opt.odd || opt.suspended || item.is_locked || market.is_findLocked" class="lock-icon"><Lock /></el-icon>
                                  <span v-else class="odds-val">
                                    <span>{{ opt.odd || opt.odd === 0 ? opt.odd : '-' }}</span>
                                    <span v-if="showChangeIcon(getOddsKey(item.id, market.id, opt))"
                                          class="change-icon"
                                          :class="isOddsUp(getOddsKey(item.id, market.id, opt)) ? 'up' : 'down'">
                                       <el-icon v-show="isOddsUp(getOddsKey(item.id, market.id, opt))"><CaretTop /></el-icon>
                                      <el-icon v-show="!isOddsUp(getOddsKey(item.id, market.id, opt))"><CaretBottom /></el-icon>
                                    </span>
                                  </span>
                                </div>
                              </div>
                            </div>
                          </div>
                        </template>

                        <div class="empty-odds-tip" v-else>
                          <span class="empty-text" v-if="item.state !== 2">{{ t('暂无盘口数据') }}</span>
                          <span class="empty-text" v-else>{{ t('已完场') }}</span>
                        </div>
                      </div>

                      <div class="match-more-toggle" @click.stop="toggleMatchExpand(item.id)" v-if="item.state !== 2">
                        <div class="more-content" v-if="item.odds_count > 0">
                          <span class="more-text">+{{ item.odds_count }} {{ t('玩法') }}</span>
                          <el-icon class="toggle-icon"><ArrowDown v-if="!isMatchExpanded(item.id)" /><ArrowUp v-else /></el-icon>
                        </div>
                        <span v-else class="empty-more">--</span>
                      </div>
                    </div>

                    <el-collapse-transition>
                      <div class="match-expanded-wrapper" v-show="isMatchExpanded(item.id)">
                        <div class="match-expanded-area">
                          <div class="expanded-market-item" v-for="market in item.odds" :key="market.id">
                            <div class="expanded-market-header">
                              <div class="header-left">
                                <div class="m-decorate"></div>
                                <span class="m-name">{{ locale === 'zh' ? market.name : market.name_en }}</span>
                              </div>
                              <el-button
                                  v-if="hasMore(market)"
                                  link
                                  type="primary"
                                  @click="toggleMarketExpand(item.id, market.id)"
                              >
                                {{ isMarketExpanded(item.id, market.id) ? t('收起') : t('展开全部') }}
                                <el-icon class="ml-1"><ArrowDown v-if="!isMarketExpanded(item.id, market.id)" /><ArrowUp v-else /></el-icon>
                              </el-button>
                            </div>

                            <div class="expanded-pair-headers" v-if="market.preHeaders && market.preHeaders.length > 0">
                              <div class="expanded-pair-item" v-for="(h, idx) in market.preHeaders" :key="idx">{{ h }}</div>
                            </div>
                            <div class="expanded-pair-headers" v-else></div> 
                            
                            <div class="m-values-grid" :class="getGridClass(market)">
                              <div
                                  class="odds-btn"
                                  v-for="(opt, optIndex) in getExpandedMarketValues(item.id, market)"
                                  :key="optIndex"
                                  :class="{
                                    'is-locked': item.is_locked || opt.suspended || !opt.odd || market.is_findLocked,
                                    'is-active': isSelected(item.id, market.id, opt),
                                    'odds-up': isOddsUp(getOddsKey(item.id, market.id, opt)),
                                    'odds-down': isOddsDown(getOddsKey(item.id, market.id, opt)),
                                    'is-centered-odds': opt.isCentered
                                  }"
                                  @click.stop="handleOddsClick(item, market, opt)"
                              >
                                <div class="odds-name-wrapper" v-if="!opt.isCentered || opt.handicap_text">
                                  <span class="selection-name" style="margin-right: 4px" v-if="!opt.isCentered" :title="locale === 'zh' ? opt.value_text : opt.value">
                                    {{ opt.displayName }}
                                  </span>
                                  <span class="handicap-val" v-if="opt.handicap_text">{{ opt.handicap_text || '-' }}</span>
                                </div>
                                <div class="odds-val-wrapper">
                                  <el-icon v-if="!opt.odd || opt.suspended || item.is_locked || market.is_findLocked" class="lock-icon"><Lock /></el-icon>
                                  <span v-else class="odds-val">
                                    {{ opt.odd || opt.odd === 0 ? opt.odd : '-' }}
                                    <span
                                        v-if="showChangeIcon(getOddsKey(item.id, market.id, opt))"
                                          class="change-icon"
                                          :class="isOddsUp(getOddsKey(item.id, market.id, opt)) ? 'up' : 'down'">
                                      <el-icon v-show="isOddsUp(getOddsKey(item.id, market.id, opt))"><CaretTop /></el-icon>
                                      <el-icon v-show="!isOddsUp(getOddsKey(item.id, market.id, opt))"><CaretBottom /></el-icon>
                                    </span>
                                  </span>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </el-collapse-transition>
                  </div>

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

            
          </el-scrollbar>

          
         
           
          
        </div>

        <pcFooter  />
        
      </div>

       
    </div>

   
  </div>
</template>

<script setup>
import SportDateFilter from "@/views/SportsBetting/SportDateFilter.vue";
import LeagueList from "./LeagueList/index.vue"; 
import pcFooter from '@/businessComponents/pcFooter/index.vue'

// defineOptions({
//   name: 'SportsBetting'
// })

import { ref, watch, computed, onMounted, onActivated, onUnmounted, nextTick } from "vue"
import { useRouter } from "vue-router"
import { useI18n } from "vue-i18n"
import { getSportSchedule, getBanner,getActivity, getUserInfo } from "@/request/api.js"
import { useOrderStore } from "@/store/bettingSheet.js"
import { RefreshRight, Lock, ArrowDown, ArrowUp, DataBoard, CaretBottom, CaretTop, Search } from '@element-plus/icons-vue'
import socket from '@/utils/websocket.js'
import { threeColMarkets, pairPriority } from './config.js';

const { t, locale } = useI18n()
const router = useRouter()
const route = useRoute()
const orderStore = useOrderStore()
const banners2 = ref([]);

const isFirstLoad = ref(true)

const skeletonLoading = ref(true)
const sportList = ref([])
const concurrency = ref(false)

const isNoMore = ref(false)
const isFetching = ref(false)
const currentPage = ref(1)
const currentLimit = ref(20)
const scrollbarRef = ref(null)

const keyword = ref('')
const currentSportIndex = ref(0)
const sportCategoryList = ref([
  { name: '足球', icon: '⚽️', value: 1 },
  { name: '篮球', icon: '🏀', value: 2 },
  { name: '网球', icon: '🎾', value: 3 },
  { name: '排球', icon: '🏐', value: 4 },
  { name: '羽毛球', icon: '🏸', value: 5 },
  { name: '乒乓球', icon: '🏓', value: 6 },
  { name: '电竞', icon: '🎮', value: 7 }
])

const leagueListRef = ref(null); 

const onSearch = () => {
  if (currentState.value === 'league') {
    if (leagueListRef.value) {
      leagueListRef.value.refresh();
    }
    return;
  }
  onQuery(1, currentLimit.value)
}

const onSportCategoryChange = (index) => {
  currentSportIndex.value = index
}

const tabList = computed(() => [
  { name: t('进行中'), value: 1 },
  { name: t('未开始'), value: 0 },
  { name: t('已完场'), value: 2 },
])

const currentState = ref(1)
const currentDate = ref('')
const selectedMap = ref({})

// ====================== 基础工具方法 ======================
const translateSelection = (valStr) => valStr === undefined || valStr === null ? '' : String(valStr);

const isDoubleChanceMarket = (market) => {
  if (!market || !market.values) return false;
  if (market.name_en && market.name_en.toLowerCase().includes('double chance')) return true;
  const vals = market.values.map(v => v.value);
  const hasCombo1 = vals.includes('Home/Draw') && vals.includes('Home/Away') && vals.includes('Draw/Away');
  const hasCombo2 = vals.includes('1/X') && vals.includes('1/2') && vals.includes('X/2');
  return hasCombo1 || hasCombo2;
};

const isThreeWayMarket = (market) => {
  if (!market || !market.values) return false;
  const hasHome = market.values.some(v => ['Home', '1'].includes(v.value));
  const hasDraw = market.values.some(v => ['Draw', 'X'].includes(v.value));
  const hasAway = market.values.some(v => ['Away', '2'].includes(v.value));
  if (hasHome && hasDraw && hasAway) return true;

  const hasOver = market.values.some(v => ['Over'].includes(v.value));
  const hasExactly = market.values.some(v => ['Exactly'].includes(v.value));
  const hasUnder = market.values.some(v => ['Under'].includes(v.value));
  return hasOver && hasExactly && hasUnder;
};

const getThreeWayHeaders = (market) => {
  if (!market || !market.values) return ['', '', ''];
  let col1 = '', col2 = '', col3 = '';
  const hasHome = market.values.some(v => ['Home', '1'].includes(v.value));
  const hasDraw = market.values.some(v => ['Draw', 'X'].includes(v.value));
  const hasAway = market.values.some(v => ['Away', '2'].includes(v.value));
  const isHAD = hasHome && hasDraw && hasAway;

  for (const v of market.values) {
    if (isHAD) {
      if (!col1 && ['Home', '1'].includes(v.value)) {
        col1 = translateSelection(locale.value === 'zh' ? v.value_text : v.value);
      } else if (!col2 && ['Draw', 'X'].includes(v.value)) {
        col2 = translateSelection(locale.value === 'zh' ? v.value_text : v.value);
      } else if (!col3 && ['Away', '2'].includes(v.value)) {
        col3 = translateSelection(locale.value === 'zh' ? v.value_text : v.value);
      }
    } else {
      if (!col1 && ['Over'].includes(v.value)) {
        col1 = translateSelection(locale.value === 'zh' ? v.value_text : v.value);
      } else if (!col2 && ['Exactly'].includes(v.value)) {
        col2 = translateSelection(locale.value === 'zh' ? v.value_text : v.value);
      } else if (!col3 && ['Under'].includes(v.value)) {
        col3 = translateSelection(locale.value === 'zh' ? v.value_text : v.value);
      }
    }
  }
  return [col1, col2, col3];
};

const isSlashGroupMarket = (market) => {
  if (!market || !market.values) return false;
  if (isDoubleChanceMarket(market)) return false;
  return market.values.some(v => typeof v.value === 'string' && v.value.includes('/'));
};

const getSlashHeadersInfo = (market) => {
  const headers = [];
  const keys = [];
  if (!market || !market.values) return { headers, keys };
  
  market.values.forEach(v => {
    if (typeof v.value === 'string' && v.value.includes('/')) {
      const key = v.value.split('/')[0];
      if (!keys.includes(key)) {
        keys.push(key);
        let name = key;
        if (locale.value === 'zh' && v.value_text && v.value_text.includes('/')) {
          name = v.value_text.split('/')[0];
        } else {
          name = translateSelection(key);
        }
        headers.push({ key, name });
      }
    }
  });
  
  const orderedHeaders = [];
  const order = ['Home', '1', 'Draw', 'X', 'Away', '2'];
  order.forEach(k => {
    const found = headers.find(h => h.key === k);
    if (found && !orderedHeaders.includes(found)) orderedHeaders.push(found);
  });
  headers.forEach(h => {
    if (!orderedHeaders.includes(h)) orderedHeaders.push(h);
  });
  
  return { headers: orderedHeaders, keys: orderedHeaders.map(h => h.key) };
};


const isOverUnderMixedMarket = (market) => {
  if (!market || !market.values) return false;
  if (isThreeWayMarket(market)) return false;
  if (isSlashGroupMarket(market)) return false;
  
  let hasOver = false;
  let hasUnder = false;

  market.values.forEach(v => {
    const val = String(v.value).toLowerCase();
    const zhVal = String(v.value_text || '');
    const hasNumber = /\d/.test(val) || /\d/.test(zhVal);
    
    if (hasNumber) {
      if (val.includes('over ') || val.includes(' or more') || zhVal.includes('大')) {
        hasOver = true;
      }
      if (val.includes('under ') || zhVal.includes('小')) {
        hasUnder = true;
      }
    }
  });

  // 必须同时具备大和小，才认为是混合大小盘
  return hasOver && hasUnder;
};

const getSelectionDisplayName = (market, selection) => {
  let rawText = translateSelection(locale.value === 'zh' ? selection.value_text : selection.value);
  
  if (market.isSlashGroup && typeof selection.value === 'string' && selection.value.includes('/')) {
     const textParts = rawText.split('/');
     return textParts.length > 1 ? textParts.slice(1).join('/') : rawText;
  }

  if (market.isOverUnderMixed) {
    if (locale.value === 'zh') {
       rawText = rawText.replace(/^[大小]/, '');
    } else {
       rawText = rawText.replace(/over/i, '').replace(/under/i, '').replace(/or more/i, '').trim();
    }
  }

  return rawText;
};

const isHeaderValue = (market, val) => {
  if (market.isSlashGroup || market.isOverUnderMixed) return false;
  if (market.isThreeWay) {
    return ['Home', '1', 'Draw', 'X', 'Away', '2', 'Over', 'Exactly', 'Under'].includes(val);
  }
  return market.hasPairHeader && pairPriority[val];
};

const getPairHeaders = (market) => {
  if (!market || !market.values) return ['', ''];
  let left = '';
  let right = '';
  for (const v of market.values) {
    if (pairPriority[v.value] === 1 && !left) {
      left = translateSelection(locale.value === 'zh' ? v.value_text : v.value);
    } else if (pairPriority[v.value] === 2 && !right) {
      right = translateSelection(locale.value === 'zh' ? v.value_text : v.value);
    }
  }
  return [left, right];
};

const hasPairHeaders = (market) => {
  if (threeColMarkets.includes(market.name_en)) return false;
  if (isThreeWayMarket(market)) return false; 
  if (isSlashGroupMarket(market)) return false;
  if (isOverUnderMixedMarket(market)) return false;
  const headers = getPairHeaders(market);
  return !!(headers[0] || headers[1]);
};

// ====================== 布局与排序 ======================
const zipperSort = (market, values) => {
  if (!values) return [];
  
  if (market.isSlashGroup) {
    const { keys } = getSlashHeadersInfo(market);
    const groups = {};
    keys.forEach(k => groups[k] = []);
    const others = [];
    
    values.forEach(v => {
      if (typeof v.value === 'string' && v.value.includes('/')) {
        const k = v.value.split('/')[0];
        if (groups[k]) groups[k].push(v);
        else others.push(v);
      } else {
        others.push(v);
      }
    });
    
    let sortedValues = [];
    const maxLen = Math.max(...keys.map(k => groups[k].length), 0);
    for (let i = 0; i < maxLen; i++) {
      keys.forEach(k => {
        if (groups[k][i]) sortedValues.push(groups[k][i]);
      });
    }
    return sortedValues.concat(others);
  }
  
  if (market.isOverUnderMixed) {
    const overs = [], unders = [], others = [];
    values.forEach(v => {
      const valStr = String(v.value).toLowerCase();
      const zhStr = String(v.value_text || '');
      let type = '';
      if (valStr.includes('under') || zhStr.startsWith('小')) type = 'under';
      else if (valStr.includes('over') || valStr.includes('or more') || zhStr.startsWith('大')) type = 'over';
      
      const numMatch = valStr.match(/\d+(\.\d+)?/);
      const key = numMatch ? numMatch[0] : valStr;
      
      if (type === 'over') overs.push({ ...v, _sortKey: key });
      else if (type === 'under') unders.push({ ...v, _sortKey: key });
      else others.push(v);
    });

    const keys = [...new Set([...overs.map(o => o._sortKey), ...unders.map(u => u._sortKey)])];
    keys.sort((a, b) => {
      const numA = parseFloat(a);
      const numB = parseFloat(b);
      if (!isNaN(numA) && !isNaN(numB)) return numA - numB;
      return a.localeCompare(b);
    });

    let sortedValues = [];
    keys.forEach(k => {
      const overItem = overs.find(o => o._sortKey === k);
      const underItem = unders.find(u => u._sortKey === k);
      if (overItem) sortedValues.push(overItem);
      if (underItem) sortedValues.push(underItem);
    });
    return sortedValues.concat(others);
  }
  
  if (threeColMarkets.includes(market.name_en)) return values;
  
  if (market.isThreeWay) {
    const col1 = [], col2 = [], col3 = [], others = [];
    const hasHome = market.values.some(v => ['Home', '1'].includes(v.value));
    const hasDraw = market.values.some(v => ['Draw', 'X'].includes(v.value));
    const hasAway = market.values.some(v => ['Away', '2'].includes(v.value));
    const isHAD = hasHome && hasDraw && hasAway;

    values.forEach(v => {
      if (isHAD) {
        if (['Home', '1'].includes(v.value)) col1.push(v);
        else if (['Draw', 'X'].includes(v.value)) col2.push(v);
        else if (['Away', '2'].includes(v.value)) col3.push(v);
        else others.push(v);
      } else {
        if (['Over'].includes(v.value)) col1.push(v);
        else if (['Exactly'].includes(v.value)) col2.push(v);
        else if (['Under'].includes(v.value)) col3.push(v);
        else others.push(v);
      }
    });

    let sortedValues = [];
    const maxLen = Math.max(col1.length, col2.length, col3.length);
    for (let i = 0; i < maxLen; i++) {
      if (col1[i]) sortedValues.push(col1[i]);
      if (col2[i]) sortedValues.push(col2[i]);
      if (col3[i]) sortedValues.push(col3[i]);
    }
    return sortedValues.concat(others);
  }
  
  const lefts = [];
  const rights = [];
  const others = [];
  
  values.forEach(v => {
    const p = pairPriority[v.value];
    if (p === 1) lefts.push(v);
    else if (p === 2) rights.push(v);
    else others.push(v);
  });

  let sortedValues = [];
  if (lefts.length > 0 || rights.length > 0) {
    const maxLen = Math.max(lefts.length, rights.length);
    for (let i = 0; i < maxLen; i++) {
      if (lefts[i]) sortedValues.push(lefts[i]);
      if (rights[i]) sortedValues.push(rights[i]);
    }
    sortedValues = sortedValues.concat(others);
  } else {
    sortedValues = [...values];
  }
  return sortedValues;
};

// ====================== 数据预处理核心 ======================
const processMarketData = (market) => {
  market.isDoubleChance = isDoubleChanceMarket(market);
  market.isSlashGroup = isSlashGroupMarket(market);
  market.isThreeWay = isThreeWayMarket(market);
  market.isOverUnderMixed = isOverUnderMixedMarket(market);
  market.hasPairHeader = hasPairHeaders(market);

  if (market.isSlashGroup) {
    market.preHeaders = getSlashHeadersInfo(market).headers.map(h => h.name);
  } else if (market.isThreeWay) {
    market.preHeaders = getThreeWayHeaders(market);
  } else if (market.isOverUnderMixed) {
    market.preHeaders = [locale.value === 'zh' ? '大' : 'Over', locale.value === 'zh' ? '小' : 'Under'];
  } else if (market.hasPairHeader) {
    market.preHeaders = getPairHeaders(market);
  } else {
    market.preHeaders = [];
  }

  const sortedValues = zipperSort(market, market.values);
  market.allSortedValues = sortedValues; 

  if (market.isSlashGroup) {
    const numKeys = getSlashHeadersInfo(market).headers.length;
    market.previewValues = sortedValues.slice(0, numKeys);
  } else if (market.isOverUnderMixed) {
    market.previewValues = sortedValues.slice(0, 2);
  } else if (threeColMarkets.includes(market.name_en) || market.isThreeWay) {
    market.previewValues = sortedValues.slice(0, 3);
  } else {
    market.previewValues = sortedValues.slice(0, 2);
  }

  market.previewValues.forEach(opt => {
    opt.displayName = getSelectionDisplayName(market, opt);
    opt.isCentered = isHeaderValue(market, opt.value) && !opt.handicap_text;
  });
  
  market.allSortedValues.forEach(opt => {
    opt.displayName = getSelectionDisplayName(market, opt);
    opt.isCentered = isHeaderValue(market, opt.value) && !opt.handicap_text;
  });

  return market;
};

const processMatchOdds = (match) => {
  if (typeof match.odds === 'string') {
    try { match.odds = JSON.parse(match.odds); } catch (e) { match.odds = []; }
  }
  if (match.odds && Array.isArray(match.odds)) {
    match.odds = match.odds.map(market => {
      if (match.odd_ids_locked && Array.isArray(match.odd_ids_locked) && match.odd_ids_locked.includes(market.id)) {
        market.is_findLocked = true;
      }
      return processMarketData(market);
    });
  }
  return match;
};

const MIN_NEW_ITEMS = 10;
const TIME_INCREMENT_MS = 60000;
let currentQueryId = 0;

const getGridClass = (market) => {
  if (!market || !market.values) return 'cols-2';
  if (market.isThreeWay) return 'cols-3';
  if (market.isSlashGroup) {
    return market.preHeaders.length === 3 ? 'cols-3' : 'cols-2';
  }
  if (market.isOverUnderMixed) return 'cols-2';
  if (threeColMarkets.includes(market.name_en)) return 'cols-3';
  return 'cols-2';
};

const getMaxItems = (market) => {
  const gridClass = getGridClass(market);
  if (gridClass === 'cols-3') return 6;
  if (gridClass === 'cols-1') return 2;
  return 4; // 默认为 cols-2
};

const getExpandedMarketValues = (matchId, market) => {
  const sorted = market.allSortedValues || [];
  if (isMarketExpanded(matchId, market.id)) return sorted;

  const maxItems = getMaxItems(market);
  return sorted.length <= maxItems ? sorted : sorted.slice(0, maxItems);
};

const hasMore = (market) => {
  return market.allSortedValues && market.allSortedValues.length > getMaxItems(market);
};

// ====================== 订单与基础工具 ======================
const getUniqueKey = (matchId, marketId, selection) => {
  // 优先取 submit_value，没有再去取 value 或 optionValue
  let val = selection.submit_value !== undefined ? selection.submit_value : (selection.value !== undefined ? selection.value : selection.optionValue);
  let hdp = '';
  
  if (selection.handicap !== null && selection.handicap !== undefined && selection.handicap !== '') {
    hdp = `_${selection.handicap}`;
  } else if (selection.handicap_text !== null && selection.handicap_text !== undefined && selection.handicap_text !== '') {
    hdp = `_${selection.handicap_text}`;
  }
  
  return `${matchId}_${marketId}_${val}${hdp}`;
};
// ====================== 解决弹跳：基于真实渲染高度的虚拟滚动 ======================
const scrollTop = ref(0);
const containerHeight = ref(800); 

const cachedHeights = {}; 
const heightsVersion = ref(0);
let heightUpdateTimer = null;

const handleItemRef = (el, id) => {
  if (el) {
    requestAnimationFrame(() => {
      const h = el.offsetHeight + 8;
      if (h > 0 && cachedHeights[id] !== h) {
        cachedHeights[id] = h;
        if (!heightUpdateTimer) {
          heightUpdateTimer = setTimeout(() => {
            heightsVersion.value++;
            heightUpdateTimer = null;
          }, 50);
        }
      }
    });
  }
};

const getItemEstimatedHeight = (item) => {
  let h = 120;
  if (isMatchExpanded(item.id)) {
    h += 200;
  }
  return h;
};

const listMeta = computed(() => {
  heightsVersion.value; 
  const tops = [];
  let currentTop = 0;
  sportList.value.forEach((item) => {
    tops.push(currentTop);
    const id = item.data_id || item.id;
    const h = cachedHeights[id] || getItemEstimatedHeight(item);
    currentTop += h;
  });
  tops.push(currentTop);
  return tops;
});

let scrollRafId = null;

const onScroll = ({ scrollTop: top }) => {
  if (scrollRafId) cancelAnimationFrame(scrollRafId);
  scrollRafId = requestAnimationFrame(() => {
    scrollTop.value = top;
  });
};

const startIndex = computed(() => {
  const tops = listMeta.value;
  const st = scrollTop.value;
  let l = 0, r = tops.length - 1;
  while (l < r) {
    const mid = Math.floor((l + r) / 2);
    if (tops[mid] <= st) l = mid + 1;
    else r = mid;
  }
  return Math.max(0, l - 1 - 8); 
});

const endIndex = computed(() => {
  const tops = listMeta.value;
  const st = scrollTop.value + containerHeight.value;
  let l = 0, r = tops.length - 1;
  while (l < r) {
    const mid = Math.floor((l + r) / 2);
    if (tops[mid] <= st) l = mid + 1;
    else r = mid;
  }
  return Math.min(sportList.value.length, l + 12); 
});

const visibleSportList = computed(() => {
  return sportList.value.slice(startIndex.value, endIndex.value);
});

const listPaddingTop = computed(() => {
  return startIndex.value > 0 ? listMeta.value[startIndex.value] : 0;
});

const listPaddingBottom = computed(() => {
  const tops = listMeta.value;
  const totalHeight = tops[tops.length - 1] || 0;
  return endIndex.value < sportList.value.length ? totalHeight - tops[endIndex.value] : 0;
});

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

const getOddsKey = (matchId, marketId, opt) => {
  // 优先取 submit_value
  let val = opt.submit_value !== undefined ? opt.submit_value : opt.value;

  if (opt.handicap !== null && opt.handicap !== undefined && opt.handicap !== '') {
    return `${matchId}_${marketId}_${val}_${opt.handicap}`;
  }
  if (opt.handicap_text !== null && opt.handicap_text !== undefined && opt.handicap_text !== '') {
    return `${matchId}_${marketId}_${val}_${opt.handicap_text}`;
  }
  return `${matchId}_${marketId}_${val}`;
}

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 showChangeIcon = (key) => {
  const change = oddsChangeMap.value.get(key)
  return !!change && (Date.now() - change.timestamp < 3000)
}

// ========== WebSocket 实时刷新 ============
const handleSocketMessage = (e) => {
  if (currentState.value === 'league') return; 
  const res = e.detail;
  if (!res || res.type !== 'sport_list' || !Array.isArray(res.message)) return;

  let newList = [...sportList.value];
  let hasChanges = false;
  let needSort = false;

  res.message.forEach((newMatch) => {
    const idx = newList.findIndex(item => item.data_id === newMatch.data_id);

    if (idx !== -1) {
      const oldMatch = newList[idx];

      if (newMatch.odds && Array.isArray(newMatch.odds) && oldMatch.odds && Array.isArray(oldMatch.odds)) {
        newMatch.odds.forEach(newMarket => {
          const oldMarket = oldMatch.odds.find(m => m.id === newMarket.id);
          if (oldMarket && oldMarket.values && newMarket.values) {
            newMarket.values.forEach(newOpt => {
              const oldOpt = oldMarket.values.find(o => {
                if (o.submit_value && newOpt.submit_value) {
                  return o.submit_value === newOpt.submit_value;
                }
                return o.value === newOpt.value && (o.handicap === newOpt.handicap || (!o.handicap && !newOpt.handicap));
              });

              if (oldOpt && oldOpt.odd && newOpt.odd) {
                const oldOddNum = parseFloat(oldOpt.odd);
                const newOddNum = parseFloat(newOpt.odd);

                if (!isNaN(oldOddNum) && !isNaN(newOddNum) && oldOddNum !== newOddNum) {
                  const key = getOddsKey(oldMatch.id, newMarket.id, newOpt);
                  const direction = newOddNum > oldOddNum ? 'up' : 'down';

                  oddsChangeMap.value.set(key, {
                    direction,
                    timestamp: Date.now()
                  });

                  let timer = setTimeout(() => {
                    oddsChangeMap.value.delete(key);
                    clearTimeout(timer);
                  }, 3100);
                }
              }
            });
          }
        });
      }

      const isStateChanged = newMatch.state !== undefined && Number(newMatch.state) !== Number(currentState.value);
      const isStatusOffline = newMatch.status !== undefined && Number(newMatch.status) === 0;

      if (isStateChanged || isStatusOffline) {
        newList.splice(idx, 1);
        hasChanges = true;
      } else {
        let updatedMatch = { ...oldMatch, ...newMatch };
        newList[idx] = processMatchOdds(updatedMatch);
        hasChanges = true;
        if (typeof orderStore.updateMatchStatus === 'function') {
          orderStore.updateMatchStatus(newMatch.data_id, newMatch);
        }
      }
    } else {
      const isStateMatching = newMatch.state !== undefined && Number(newMatch.state) === Number(currentState.value);
      const isStatusOnline = newMatch.status === undefined || Number(newMatch.status) === 1;

      if (isStateMatching && isStatusOnline) {
        let matchToInsert = { ...newMatch };
        newList.push(processMatchOdds(matchToInsert));
        hasChanges = true;
        needSort = true; 
      }
    }
  });

  if (needSort) {
    newList.sort((a, b) => {
      const timeA = a.game_time ? new Date(a.game_time.replace(/-/g, '/')).getTime() : 0;
      const timeB = b.game_time ? new Date(b.game_time.replace(/-/g, '/')).getTime() : 0;

      if (currentState.value === 2) {
        return timeB - timeA;
      } else {
        return timeA - timeB;
      }
    });
  }

  if (hasChanges) {
    sportList.value = newList;
  }

  nextTick(); 
};

onMounted(() => {
  syncFromStore();
  onQuery(1, currentLimit.value);
  
  socket.eventBus.addEventListener('onSocketMessage', handleSocketMessage);

  nextTick(() => {
    const scrollDom = document.querySelector('.scroll-view-container');
    if (scrollDom) {
      containerHeight.value = scrollDom.clientHeight || 800;
    }
  });
});

onActivated(() => {
  syncFromStore();
});

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

const onRefresh = () => {
  onQuery(1, currentLimit.value);
};

const onLoadMore = () => {
  if (isNoMore.value || isFetching.value || skeletonLoading.value) return;
  onQuery(currentPage.value + 1, currentLimit.value);
};

// ==========================================
// ========== 调度与请求核心架构 =============
// ==========================================
async function onQuery(pageNo, pageSize) {
  if (currentState.value === 'league') return;
  const queryId = ++currentQueryId;

  try {
    if (pageNo === 1) {
      isNoMore.value = false;
      scrollTop.value = 0;
      currentPage.value = 1;
      
      for (const key in cachedHeights) delete cachedHeights[key];
      heightsVersion.value++;

      if (scrollbarRef.value) {
        scrollbarRef.value.setScrollTop(0);
      }
      
      skeletonLoading.value = true;
      sportList.value = []; 
    } else {
      if (isFetching.value || isNoMore.value) return;
    }

    isFetching.value = true;

    let accumulatedNewItems = [];
    let currentApiGameTime = null;
    let attemptCount = 0;
    const maxAttempts = 5;

    if (pageNo > 1 && sportList.value.length > 0) {
      const lastItem = sportList.value[sportList.value.length - 1];
      if (lastItem && lastItem.game_time) {
        currentApiGameTime = lastItem.game_time;
      }
    }

    let targetCount = pageNo === 1 ? pageSize : MIN_NEW_ITEMS;

    while (accumulatedNewItems.length < targetCount && !isNoMore.value && attemptCount < maxAttempts) {
      if (queryId !== currentQueryId) return;

      attemptCount++;

      const params = {
        page: 1, 
        limit: pageSize,
        state: currentState.value,
        from: 'pc'
      };

      if (keyword.value) {
        params.keyword = keyword.value;
      }

      if (currentApiGameTime) {
        params.game_time = currentApiGameTime;
      }
      
      if (currentState.value !== 1) {
        params.start_time = currentDate.value;
        params.end_time = currentDate.value;
      }
      
      const res = await getSportSchedule(params);
      
      if (queryId !== currentQueryId) return;

      if (res && res.code === 1 && res.data && res.data.list && res.data.list.length > 0) {
        const rawList = res.data.list;
        const formatList = rawList.map(item => processMatchOdds(item));

        const existingIds = new Set([
          ...sportList.value.map(i => i.id),
          ...accumulatedNewItems.map(i => i.id)
        ]);

        const newItems = formatList.filter(item => !existingIds.has(item.id));
        accumulatedNewItems = accumulatedNewItems.concat(newItems);

        if (rawList.length < pageSize) {
          isNoMore.value = true; 
        } else {
          if (newItems.length === 0) {
            let baseTimeStr = currentApiGameTime || rawList[rawList.length - 1].game_time;
            if (baseTimeStr) {
              let dateVal = new Date(baseTimeStr.replace(/-/g, '/'));
              if (!isNaN(dateVal.getTime())) {
                dateVal = new Date(dateVal.getTime() + TIME_INCREMENT_MS);
                const y = dateVal.getFullYear();
                const m = String(dateVal.getMonth() + 1).padStart(2, '0');
                const d = String(dateVal.getDate()).padStart(2, '0');
                const h = String(dateVal.getHours()).padStart(2, '0');
                const min = String(dateVal.getMinutes()).padStart(2, '0');
                const s = String(dateVal.getSeconds()).padStart(2, '0');
                currentApiGameTime = `${y}-${m}-${d} ${h}:${min}:${s}`;
              } else {
                currentApiGameTime = rawList[rawList.length - 1].game_time;
              }
            }
          } else {
            currentApiGameTime = rawList[rawList.length - 1].game_time;
          }
        }
      } else {
        isNoMore.value = true;
      }
    }

    if (queryId === currentQueryId) {
      if (pageNo === 1) {
        sportList.value = accumulatedNewItems;
        if (currentState.value === 1 && sportList.value.length === 0 && isFirstLoad.value) {
          currentState.value = 0;
          isFirstLoad.value = false; 
          onQuery(1, currentLimit.value);
          return;
        }
        
        isFirstLoad.value = false; 
      } else {
        sportList.value = sportList.value.concat(accumulatedNewItems);
      }
      currentPage.value = pageNo; 
      skeletonLoading.value = false;
      isFetching.value = false;
    }
    
  } catch (error) {
    if (queryId === currentQueryId) {
      isNoMore.value = true;
      skeletonLoading.value = false;
      isFetching.value = false;
    }
  }
}

const onTabChange = (val) => {
  currentState.value = val;
  if (val !== 'league') {
    onQuery(1, currentLimit.value);
  }
};

const dateChange = (e) => {
  currentDate.value = e;
  if (currentState.value !== 1 && currentState.value !== 'league') {
    onQuery(1, currentLimit.value);
  }
};

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

const getScore = (scoreStr, index) => {
  if (!scoreStr || scoreStr === '-') return '0';
  const parts = scoreStr.split('-');
  return parts[index] || '0';
};

const expandedMatches = ref(new Set());
const expandedMarkets = ref(new Set());

const toggleMatchExpand = (matchId) => {
  const newSet = new Set(expandedMatches.value);
  if (newSet.has(matchId)) newSet.delete(matchId);
  else newSet.add(matchId);
  expandedMatches.value = newSet;
};

const isMatchExpanded = (matchId) => expandedMatches.value.has(matchId);

const toggleMarketExpand = (matchId, marketId) => {
  const key = `${matchId}_${marketId}`;
  const newSet = new Set(expandedMarkets.value);
  if (newSet.has(key)) newSet.delete(key);
  else newSet.add(key);
  expandedMarkets.value = newSet;
};

const isMarketExpanded = (matchId, marketId) => expandedMarkets.value.has(`${matchId}_${marketId}`);

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 isSelected = (matchId, marketId, selection) => {
  const uniqueKey = getUniqueKey(matchId, marketId, selection);
  return !!selectedMap.value[uniqueKey];
};

const handleOddsClick = (item, market, selection) => {
  if (item.state !== 0 && item.state !== 1) return;
  if (item.is_locked || market.is_findLocked) return;
  if (!selection || !selection.odd || selection.odd === '-') return;
  if (selection.suspended) return;

  const uniqueKey = getUniqueKey(item.id, market.id, selection);

  if (selectedMap.value[uniqueKey]) {
    orderStore.removeOrderItemByKey(uniqueKey);
  } else {
    const betItem = {
      matchId: item.id,
      data_id: item.data_id,
      league: item.league,
      league_en: item.league_en,
      homeTeam: item.home_team,
      home_team_en: item.home_team_en,
      guestTeam: item.guest_team,
      guest_team_en: item.guest_team_en,
      betType: market.name,
      betTypeEn: market.name_en,
      betTypeName: selection.value_text,
      betTypeNameEn: selection.value,
      handicap: selection.handicap,
      handicap_text: selection.handicap_text,
      odds: selection.odd,
      score: item.score,
      state: item.state,
      uniqueKey: uniqueKey,
      optionValue: selection.value,
      submit_value: selection.submit_value,
      marketId: market.id,
       mininum: market.mininum, // 新增：最低限额
      maxinum: market.maxinum, // 新增：最高限额
      selection: {
        ...selection
      }
    };

    orderStore.addOrderItem(betItem);

    if (market.values) {
      market.values.forEach(wsItem => {
        const otherKey = getUniqueKey(item.id, market.id, wsItem);
        if (selectedMap.value[otherKey] && otherKey !== uniqueKey) {
          orderStore.removeOrderItemByKey(otherKey);
        }
      });
    }
  }
};

function getBannerData() {
  // getBanner({type: 'pc'}).then(res => {
  //    banners2.value = res.data?.list || [];
  // })

  getActivity({type: 'pc'}).then(res => {
    banners2.value = res.data?.list || [];
    console.log(banners2.value, res, 1349)
  })
}

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

getBannerData()

if(route.query.token) {
  // 缓存 token到 localStorage
  localStorage.setItem('token', route.query.token);
}

if(route.query.token && (!route.query.is_bind || route.query.is_bind == 0)) {
  

  getUserInfo().then(res => {
    if(!res.data.account) {
      // 确认弹窗
      ElMessageBox.confirm(
        '您的账号信息尚未完善，为保证功能的正常使用，请前往补充填写。',
        '温馨提示',
        {
          confirmButtonText: '去填写',
          showCancelButton: false, // 如果不需要取消按钮可以设为 false，需要的话去掉这行
          type: 'warning',
          closeOnClickModal: false // 防止误触空白处关闭弹窗
        }
      ).then(() => {
        // 点击确定后跳转（假设使用 vue-router，请将路径替换为你实际的填写页路径）
        router.push({ path: '/setAccount' }); 
      }).catch(() => {
        // 点击取消的回调（如果显示了取消按钮）
      });
    }
  })
  
}
</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);

/* === 分类与搜索栏样式 === */
.search-segment-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: $card-bg;
  border-radius: 6px;
  padding: 8px 16px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  flex-shrink: 0;
  gap: 16px;

  .el-scrollbar {
    flex: 1;
    min-width: 0;
  }

  .sport-segment-container {
    display: inline-flex;
    gap: 12px;
    align-items: center;
    height: 100%;
  }

  .sport-segment-item {
    display: inline-flex;
    align-items: center;
    padding: 6px 14px;
    border-radius: 20px;
    background-color: var(--el-fill-color-light);
    cursor: pointer;
    transition: all 0.3s;
    white-space: nowrap; 
    flex-shrink: 0;      

    &:hover {
      background-color: var(--el-fill-color);
    }

    &.is-active {
      background-color: $main-color;
      .sport-name, .sport-icon {
        color: #fff;
        font-weight: bold;
      }
    }

    .sport-icon {
      font-size: 16px;
      margin-right: 6px;
    }

    .sport-name {
      font-size: 14px;
      color: var(--el-text-color-regular);
    }
  }

  .search-box {
    width: 260px;
    flex-shrink: 0;
    
    .search-input {
      width: 100%;
    }
  }
}

.pc-sports-list-container {
  container-type: inline-size;
  container-name: sports-list;
  height: 100%;
  padding: 6px 8px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  @container sports-list (max-width: 800px) { padding: 4px; }
}

.layout-column {
  display: flex;
  flex-direction: column;
  width: 100%;
  flex: 1;
  min-height: 0;
  gap: 8px;
  background-color: transparent;
  @container sports-list (max-width: 550px) { gap: 6px; }
}

.top-filter-bar {
  background-color: $card-bg;
  border-radius: 6px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  flex-shrink: 0;

  .top-tabs {
    display: flex;
    align-items: center;
    gap: 20px;
  }

  .top-tab-item {
    position: relative;
    padding: 8px 4px;
    cursor: pointer;
    font-size: 14px;
    color: var(--el-text-color-regular);
    transition: all 0.2s;
    font-weight: 500;

    &:hover {
      color: $main-color;
    }
    &.is-active {
      color: $main-color;
      font-weight: bold;
      &::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: 10%;
        height: 3px;
        width: 80%;
        background-color: $main-color;
        border-radius: 2px 2px 0 0;
      }
    }
  }

  .top-actions {
    display: flex;
    align-items: center;
    gap: 12px;

    .el-button {
      display: flex;
      align-items: center;
    }
  }
}

.right-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  height: calc(100% - 80px);
  overflow-y: auto;
  overflow-x: hidden;
  
}
.right-content::-webkit-scrollbar {
    display: none;
  }

.match-list-body {
  flex: 1; height: 100%; display: flex; flex-direction: column;
  @container sports-list (max-width: 550px) { gap: 6px; padding-right: 0; }
  
  :deep(.el-scrollbar) {
    height: 100%;
  }
}

.match-card {
  background-color: $card-bg; border-radius: 6px; border: 1px solid $border-color; box-shadow: 0 1px 3px rgba(0,0,0,0.05); overflow: hidden; flex-shrink: 0; transition: border-color 0.2s; margin-bottom: 8px;
  &:hover { border-color: var(--el-border-color); .team-info { text-decoration: underline; } }

  .match-card-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 6px 12px;
    background-color: var(--el-fill-color-lighter); border-bottom: 1px solid $border-color;
    @container sports-list (max-width: 550px) { padding: 6px 10px; flex-wrap: wrap; gap: 4px; }
    .league-info {
      display: flex; align-items: center;
      .decorate-bar { width: 3px; height: 12px; background-color: $main-color; border-radius: 2px; margin-right: 6px; }
      .league-name { font-size: 12px; font-weight: bold; color: var(--el-text-color-primary); }
    }
    .match-status-time {
      display: flex; align-items: center;
      .time-text { font-size: 11px; color: var(--el-text-color-regular); font-family: monospace; }
      .timer-text { font-size: 11px; color: var(--el-color-danger); font-weight: bold; display: flex; align-items: center; gap: 4px; .live-dot { width: 4px; height: 4px; background-color: var(--el-color-danger); border-radius: 50%; animation: pulse 1.5s infinite; } }
      .el-tag { height: 18px; line-height: 16px; padding: 0 4px; font-size: 11px; border-radius: 2px; }
    }
  }

  .match-card-main {
    display: flex; align-items: stretch; cursor: pointer; background-color: transparent; transition: background-color 0.2s;
    &:hover { background-color: $hover-bg; }
    @container sports-list (max-width: 550px) { flex-direction: column; }

    .match-teams {
      width: 180px;
      flex-shrink: 0; padding: 8px 12px; border-right: 1px dashed $border-color; display: flex; flex-direction: column; justify-content: center;
      @container sports-list (max-width: 550px) { width: 100%; border-right: none; border-bottom: 1px dashed $border-color; padding: 8px; flex-direction: row; align-items: center; gap: 16px; }
      .team-row {
        display: flex; justify-content: space-between; align-items: center;
        @container sports-list (max-width: 550px) { flex: 1; }
        &.mt-3 { margin-top: 6px !important; @container sports-list (max-width: 550px) { margin-top: 0 !important; } }
        .team-info {
          display: flex; align-items: center; gap: 6px; flex: 1; overflow: hidden;
          .team-logo { background-color: transparent; }
          .team-name { font-size: 12px; font-weight: 500; color: var(--el-text-color-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%; text-align: left; @container sports-list (max-width: 800px) { font-size: 11px; } }
        }
        .team-score { font-size: 14px; font-weight: 800; color: var(--el-text-color-primary); padding-left: 6px; &.text-live { color: $main-color; } }
      }
    }

    .match-odds-grids {
      flex: 1;
      padding: 8px 12px;
      display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 20px;
      @container sports-list (max-width: 1200px) { gap: 20px; }
      @container sports-list (max-width: 800px) { padding: 6px 8px; gap: 20px; }
      @container sports-list (max-width: 1350px) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        .market-col:nth-child(n+3) { display: none; }
      }
      @container sports-list (max-width: 992px) {
        grid-template-columns: repeat(1, minmax(0, 1fr));
        .market-col:nth-child(n+2) { display: none; }
      }

      .market-col {
        display: flex; flex-direction: column;
        .market-name { font-size: 11px; color: var(--el-text-color-secondary); margin-bottom: 4px; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        
        .preview-pair-headers {
          display: flex; gap: 4px; width: 100%; margin-bottom: 4px;
          min-height: 16px;
          .preview-pair-item {
            flex: 1; text-align: center; font-size: 11px; color: var(--el-text-color-secondary); line-height: 16px;
          }
        }

        .market-values { 
          display: flex; gap: 4px; width: 100%; 
          position: relative;
        }
        .market-values-border-left::before{
          content: '';
          position: absolute;
          left: -10px;
          width: 1px;
          height: 80%;
          top: 10%;
          background-color: $main-color;
          opacity: 0.5;
        }
      }
      .empty-odds-tip { grid-column: 1 / -1; display: flex; align-items: center; justify-content: flex-start; padding-left: 10px; .empty-text { color: var(--el-text-color-placeholder); font-size: 12px; } }
    }

    .match-more-toggle {
      width: 100px;
      flex-shrink: 0; border-left: 1px dashed $border-color; display: flex; flex-direction: column; align-items: center; justify-content: center; transition: background-color 0.2s;
      @container sports-list (max-width: 800px) { width: 44px; }
      @container sports-list (max-width: 550px) { width: 100%; height: 28px; border-left: none; border-top: 1px dashed $border-color; flex-direction: row; }

      &:hover { background-color: var(--el-border-color-extra-light); }
      .more-content {
        display: flex; flex-direction: column; align-items: center; gap: 2px; color: var(--el-color-primary); font-size: 11px; font-weight: bold;
        @container sports-list (max-width: 550px) { flex-direction: row; }
        .toggle-icon { font-size: 12px; }
      }
      .empty-more { color: var(--el-text-color-placeholder); font-size: 11px;}
    }
  }

  .match-expanded-wrapper {
    background-color: var(--el-fill-color-lighter); border-top: 1px solid $border-color;
  }

  .match-expanded-area {
    padding: 8px 12px 12px 208px;
    display: flex; flex-direction: column; gap: 8px;
    @container sports-list (max-width: 1200px) { padding: 8px 10px 10px 208px; }
    @container sports-list (max-width: 550px) { padding: 6px 8px; gap: 6px; }

    .expanded-market-item {
      background-color: var(--el-bg-color-overlay); border: 1px solid var(--el-border-color-light); border-radius: 4px; padding: 8px; box-shadow: 0 1px 2px rgba(0,0,0,0.02);

      .expanded-market-header {
        display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; padding-bottom: 6px; 
        .header-left { display: flex; align-items: center; .m-decorate { width: 3px; height: 10px; background-color: $main-color; margin-right: 4px; } .m-name { font-size: 12px; font-weight: bold; color: var(--el-text-color-primary); } }
        .el-button { height: 18px; font-size: 11px; padding: 2px; }
      }

      .expanded-pair-headers {
        display: flex; gap: 8px; width: 100%; margin-bottom: 12px; padding: 0 4px; box-sizing: border-box;
        min-height: 18px; 
        .expanded-pair-item {
          flex: 1; text-align: center; font-size: 12px; color: var(--el-text-color-regular); font-weight: 500; line-height: 18px;
        }
      }

      .m-values-grid {
        display: grid; gap: 8px;
        &.cols-2 { grid-template-columns: repeat(2, 1fr); }
        &.cols-3 { grid-template-columns: repeat(3, 1fr); }
      }
    }
  }
}

.odds-btn {
  flex: 1;
   min-width: 0; 
   background-color: var(--el-fill-color); 
   border: 1px solid var(--el-border-color);
    border-radius: 4px;
  display: flex;
   justify-content: space-between; 
   align-items: center;
    padding: 6px 8px; 
    box-sizing: border-box;
  transition: all 0.2s; cursor: pointer; 
  position: relative; 
  overflow: hidden; 
  min-height: 40px;

  &.is-centered-odds {
    justify-content: center;
  }

  .odds-name-wrapper {
    display: flex;  align-items: center; min-width: 0; flex: 1; margin-right: 6px; z-index: 1;
    .selection-name {
      font-size: 12px; color: var(--el-text-color-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: left;
    }
    .handicap-val {
      font-size: 12px; color: var(--el-text-color-primary); font-weight: bold; margin-top: 2px;
    }
  }

  .odds-val-wrapper {
    display: flex; align-items: center; justify-content: flex-end; flex-shrink: 0; z-index: 1; gap: 4px;
    .odds-val {
      display: flex;
      align-items: center;
      font-size: 13px; font-weight: bold; color: $main-color;
    }
  }

  &:hover { border-color: $main-color; background-color: var(--el-fill-color-light); }
  &.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; font-weight: bold } }
  &.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: 14px; z-index: 3; } }

  &.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-weight: bold; font-size: 14px;
    display: flex; align-items: center;
    &.up { color: #4caf50; }
    &.down { color: #f56c6c; }
  }
}

.market-values {
  container-type: inline-size;
  container-name: odds-wrapper;
  display: flex; gap: 4px; width: 100%;
}

@container odds-wrapper (max-width: 400px) {
  .odds-name-wrapper { align-items: center!important; margin-right: 0!important; }
}

.loading-more {
  text-align: center;
  padding: 15px 0;
  font-size: 13px;
  color: #999;
}

.mr-1 { margin-right: 4px; }
.mr-2 { margin-right: 6px; }
.ml-1 { margin-left: 2px; }

@keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.4; } 100% { opacity: 1; } }

:deep(.el-avatar) {
  width: 18px !important; height: 18px !important;
  @container sports-list (max-width: 800px) { width: 16px !important; height: 16px !important; }
}
  .main-carousel-wrapper {
    cursor: pointer;
    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; }
  }
</style>