<template>
  <div class="pc-sport-detail-container">
    <div class="scoreboard-banner" v-if="matchInfo">
      <div class="bg-glow left-glow"></div>
      <div class="bg-glow right-glow"></div>
      <div class="bg-pattern"></div>

      <div class="banner-top">
        <el-button class="back-btn" link @click="goBack">
          <el-icon class="mr-1"><ArrowLeft /></el-icon> {{ t('返回列表') }}
        </el-button>
        <div class="league-name">
          <el-image v-if="matchInfo.league_logo" :src="matchInfo.league_logo" style="width: 18px; height: 18px; margin-right: 8px;" />
          <el-icon v-else color="#f8b932" class="mr-2"><Trophy /></el-icon>
          <span>{{ locale === 'zh' ? matchInfo.league : matchInfo.league_en }}</span>
          <el-tag v-if="matchInfo.is_roll === 1" style="margin-left: 10px">{{ t('滚球') }}</el-tag>
        </div>
        <div class="placeholder-right"></div>
      </div>

      <div class="banner-main">
        <div class="team-panel home">
          <el-tag size="large" type="success" style="margin-top: 4px">{{ t('主') }}</el-tag>
          <span class="team-name" :title="locale === 'zh' ? matchInfo.home_team : matchInfo.home_team_en">{{ locale === 'zh' ? matchInfo.home_team : matchInfo.home_team_en }}</span>
          <div class="logo-wrapper">
            <el-avatar :src="matchInfo.home_team_logo" :size="80" shape="circle">
            </el-avatar>
          </div>
        </div>

        <div class="score-panel">
          <div class="score-board">
            <div class="score-numbers" v-if="matchInfo.state !==  0">
              <span class="num">{{ getScore(matchInfo.score, 0) }}</span>
              <span class="divider">:</span>
              <span class="num">{{ getScore(matchInfo.score, 1) }}</span>
            </div>

            <div
                class="live-timer mt-2"
                :class="`is-${stateTagType(matchInfo.state)}`"
                :style="{minWidth: matchInfo.fixture_status && matchInfo.fixture_status.seconds ? '200px' : ''}"
            >
              <span class="timer-text">{{ matchInfo.game_time }}</span>
              <span class="live-dot" v-if="matchInfo.state === 1"></span>
              <span class="timer-text" v-if="matchInfo.fixture_status">{{ matchInfo.fixture_status.seconds}}</span>
            </div>

            <div style="display: flex;align-items: center;justify-content: center;margin-top: 10px">
              <el-tag style="margin-right: 10px" v-if="matchInfo.state === 1 && matchInfo.fixture_status">
              {{ t(matchInfo.fixture_status?.long) }}
            </el-tag>
            <el-tag :type="stateTagType(matchInfo.state)"
            >{{ getStatusText(matchInfo.state) }}</el-tag>
            </div>

            <div class="half-score" v-if="matchInfo.half_score && matchInfo.state !== 0 && matchInfo.half_score !== '-'">
              {{ t('半场') }} {{ matchInfo.half_score }}
            </div>
          </div>
        </div>

        <div class="team-panel away">
          <div class="logo-wrapper">
            <el-avatar :src="matchInfo.guest_team_logo" :size="80" shape="circle">
            </el-avatar>
          </div>
          <span class="team-name" :title="locale === 'zh' ? matchInfo.guest_team : matchInfo.guest_team_en">{{ locale === 'zh' ? matchInfo.guest_team : matchInfo.guest_team_en }}</span>
          <el-tag size="large" type="danger" style="margin-top: 4px">{{ t('客') }}</el-tag>
        </div>
      </div>
    </div>

    <div class="markets-container" v-if="matchInfo">

      <div class="match-events-wrap" v-if="parsedEvents.length > 0">
        <el-card class="market-row-card" shadow="hover" style="margin-bottom: 16px;">
          <div class="market-header" @click="eventsExpanded = !eventsExpanded" style="cursor: pointer;">
            <div class="header-left">
              <div class="decorate-bar"></div>
              <span class="title">{{ t('比赛事件') }}</span>
            </div>
            <div class="header-right">
              <el-button link type="primary" @click.stop="eventsExpanded = !eventsExpanded">
                {{ eventsExpanded ? t('收起') : t('展开') }}
                <el-icon class="ml-1"><ArrowUp v-if="eventsExpanded" /><ArrowDown v-else /></el-icon>
              </el-button>
            </div>
          </div>

          <el-collapse-transition>
            <div class="events-timeline" v-show="eventsExpanded">
              <div class="timeline-line"></div>

              <div
                  class="timeline-item"
                  v-for="(ev, idx) in parsedEvents"
                  :key="idx"
                  :class="ev.isHome ? 'is-home' : 'is-away'"
              >
                <div class="time-box">{{ ev.time_elapsed }}'</div>

                <div class="event-box">
                  <template v-if="ev.isHome">
                    <div class="event-details text-right">
                      <div class="player-name">{{ ev.playerName }}</div>
                      <div class="event-desc">
                        {{ locale === 'zh' ? ev.detail_text : ev.detail }}
                        <span v-if="ev.assistName">({{ ev.assistName }})</span>
                      </div>
                    </div>
                    <div class="event-icon ml-2">
                      <span v-if="ev.type === 'Goal' && ev.detail !== 'Missed Penalty'">⚽</span>
                      <span v-else-if="ev.detail === 'Yellow Card'" class="card-icon yellow"></span>
                      <span v-else-if="ev.detail === 'Red Card'" class="card-icon red"></span>
                      <span v-else-if="ev.type === 'subst'">🔃</span>
                      <span v-else-if="ev.detail === 'Missed Penalty'">❌</span>
                      <span v-else>📌</span>
                    </div>
                  </template>

                  <template v-else>
                    <div class="event-icon mr-2">
                      <span v-if="ev.type === 'Goal' && ev.detail !== 'Missed Penalty'">⚽</span>
                      <span v-else-if="ev.detail === 'Yellow Card'" class="card-icon yellow"></span>
                      <span v-else-if="ev.detail === 'Red Card'" class="card-icon red"></span>
                      <span v-else-if="ev.type === 'subst'">🔃</span>
                      <span v-else-if="ev.detail === 'Missed Penalty'">❌</span>
                      <span v-else>📌</span>
                    </div>
                    <div class="event-details text-left">
                      <div class="player-name">{{ ev.playerName }}</div>
                      <div class="event-desc">
                        {{ locale === 'zh' ? ev.detail_text : ev.detail }}
                        <span v-if="ev.assistName">({{ ev.assistName }})</span>
                      </div>
                    </div>
                  </template>
                </div>
              </div>
            </div>
          </el-collapse-transition>
        </el-card>
      </div>

      <div class="markets-list" v-if="matchInfo.odds && matchInfo.odds.length > 0">

        <el-card
            class="market-row-card"
            shadow="hover"
            v-for="(market, mIndex) in matchInfo.odds"
            :key="mIndex"
        >
          <div class="market-header">
            <div class="header-left">
              <div class="decorate-bar"></div>
              <span class="title">{{ locale === 'zh' ? market.name : market.name_en }}</span>
            </div>
            
            <div class="header-right" v-if="hasMore(market)">
              <el-button link type="primary" @click="toggleExpand(market.id)">
                {{ isExpanded(market.id) ? t('收起') : t('展开全部') }}
                <el-icon class="ml-1"><ArrowUp v-if="isExpanded(market.id)" /><ArrowDown v-else /></el-icon>
              </el-button>
            </div>
          </div>

          <div class="pair-headers" v-if="hasPairHeaders(market) || isThreeWayMarket(market) || isSlashGroupMarket(market) || isOverUnderMixedMarket(market)">
            <template v-if="isSlashGroupMarket(market)">
              <div class="pair-header-item" v-for="(h, idx) in getSlashHeadersInfo(market).headers" :key="idx">{{ h.name }}</div>
            </template>
            <template v-else-if="isThreeWayMarket(market)">
              <div class="pair-header-item">{{ getThreeWayHeaders(market)[0] }}</div>
              <div class="pair-header-item">{{ getThreeWayHeaders(market)[1] }}</div>
              <div class="pair-header-item">{{ getThreeWayHeaders(market)[2] }}</div>
            </template>
            <template v-else-if="isOverUnderMixedMarket(market)">
              <div class="pair-header-item">{{ locale === 'zh' ? '大' : 'Over' }}</div>
              <div class="pair-header-item">{{ locale === 'zh' ? '小' : 'Under' }}</div>
            </template>
            <template v-else>
              <div class="pair-header-item">{{ getPairHeaders(market)[0] }}</div>
              <div class="pair-header-item">{{ getPairHeaders(market)[1] }}</div>
            </template>
          </div>

          <div class="odds-wrapper" :class="getGridClass(market)">
            <div
                class="odds-btn"
                v-for="(selection, sIndex) in getVisibleValues(market, market.values)"
                :key="sIndex"
                :class="{
                  'is-active': isSelected(market.id, selection),
                  'is-locked': !selection.odd || selection.suspended || checkIsLocked(matchInfo) || market.is_findLocked,
                  'odds-up': isOddsUp(getOddsKey(matchInfo.id || matchInfo.data_id, market.id, selection)) && !(!selection.odd || selection.suspended || checkIsLocked(matchInfo)),
                  'odds-down': isOddsDown(getOddsKey(matchInfo.id || matchInfo.data_id, market.id, selection)) && !(!selection.odd || selection.suspended || checkIsLocked(matchInfo))
                }"
                @click="handleBet(market, selection)"
            >
              <div class="selection-info">
                <span class="selection-name" :title="getSelectionDisplayName(market, selection)">
                  {{ getSelectionDisplayName(market, selection) }}
                </span>
                <span v-if="selection.handicap_text" class="handicap-wrap">
                  <span class="handicap-val">{{ selection.handicap_text || '-' }}</span>
                </span>
              </div>

              <div class="odds-val-info">
                <span class="odds-val">
                  {{ selection.odd || '-' }}
                  <span
                      v-if="showChangeIcon(getOddsKey(matchInfo.id || matchInfo.data_id, market.id, selection))"
                      class="change-icon"
                      :class="{
                      up: isOddsUp(getOddsKey(matchInfo.id || matchInfo.data_id, market.id, selection)),
                      down: isOddsDown(getOddsKey(matchInfo.id || matchInfo.data_id, market.id, selection))
                    }"
                  >
                    <el-icon v-show="isOddsUp(getOddsKey(matchInfo.id || matchInfo.data_id, market.id, selection)) && !(!selection.odd || selection.suspended || checkIsLocked(matchInfo))"><CaretTop /></el-icon>
                    <el-icon v-show="!isOddsUp(getOddsKey(matchInfo.id || matchInfo.data_id, market.id, selection)) && !(!selection.odd || selection.suspended || checkIsLocked(matchInfo))"><CaretBottom /></el-icon>
                  </span>
                </span>
                <el-icon v-if="!selection.odd || selection.suspended || checkIsLocked(matchInfo)" class="lock-icon"><Lock /></el-icon>
              </div>
            </div>
          </div>
        </el-card>

      </div>

      <el-empty v-else v-show="matchInfo.state !== 2" :description="t('暂无盘口数据')" />
    </div>

  </div>
</template>

<script setup>
import { ref, watch, onMounted, onUnmounted, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useI18n } from "vue-i18n";
import { getSportInfo } from '@/request/api.js';
import { useOrderStore } from "@/store/bettingSheet.js";
import {ArrowLeft, Trophy, Lock, ArrowDown, ArrowUp, CaretBottom, CaretTop} from '@element-plus/icons-vue';
import socket from '@/utils/websocket.js'
import {formatRange} from "@/utils/index.js";
import { threeColMarkets, pairPriority } from '../SportsBetting/config.js';

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

const loading = ref(false);
const matchInfo = ref(null);
const dataId = ref(route.query.data_id || '');

const selectedMap = ref({});

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

// === 新增：判断是否是双重机会（Double Chance）玩法 ===
const isDoubleChanceMarket = (market) => {
  if (!market || !market.values) return false;
  if (market.name_en && market.name_en.toLowerCase().includes('double chance')) return true;
  
  // 兼容性检查，防止部分情况下 name_en 丢失
  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;
};

// === 判断是否包含Home、Draw、Away 或 Over、Exactly、Under的3向玩法 ===
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) };
};

// === 判断是否是大小球并且数字附带在选项值里的玩法（含 or more） ===
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);
  return rawText;
};

// ==============================================

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 oddsChangeMap = ref(new Map()) 

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

  if (selection.handicap !== null && selection.handicap !== undefined && selection.handicap !== '') {
    return `${matchId}_${marketId}_${val}_${selection.handicap}`;
  }
  if (selection.handicap_text !== null && selection.handicap_text !== undefined && selection.handicap_text !== '') {
    return `${matchId}_${marketId}_${val}_${selection.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)
}

// ==============================================
// 比赛事件的解析逻辑
// ==============================================
const eventsExpanded = ref(true);

const parsedEvents = computed(() => {
  if (!matchInfo.value || !matchInfo.value.event || matchInfo.value.event.length === 0) {
    return [];
  }

  return matchInfo.value.event.map(item => {
    let playerObj = {};
    let assistObj = {};

    try {
      if(typeof item.player === 'string') playerObj = JSON.parse(item.player);
    } catch(e) {}
    try {
      if(typeof item.assist === 'string') assistObj = JSON.parse(item.assist);
    } catch(e) {}

    const isHome = item.team_id === matchInfo.value.home_team_id;

    return {
      ...item,
      playerName: playerObj.name || '',
      assistName: assistObj.name || '',
      isHome
    };
  });
});

const stateTagType = computed(() => {
  return (state) => {
    if(state === 0) return 'warning';
    else if(state === 1) return 'success';
    else return 'danger';
  }
})

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 expandedGroups = ref({});
const isExpanded = (id) => !!expandedGroups.value[id];
const toggleExpand = (id) => { expandedGroups.value[id] = !expandedGroups.value[id]; };

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

// === 拉链式交替排序逻辑与列表展示控制 ===
const getVisibleValues = (market, values) => {
  if (!values) return [];
  
  const maxItems = getMaxItems(market);
  
  if (isSlashGroupMarket(market)) {
    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]);
      });
    }
    sortedValues = sortedValues.concat(others);
    
    if (isExpanded(market.id)) return sortedValues;
    return sortedValues.length <= maxItems ? sortedValues : sortedValues.slice(0, maxItems);
  }

  if (isOverUnderMixedMarket(market)) {
    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);
    });
    sortedValues = sortedValues.concat(others);
    
    if (isExpanded(market.id)) return sortedValues;
    return sortedValues.length <= maxItems ? sortedValues : sortedValues.slice(0, maxItems);
  }

  if (threeColMarkets.includes(market.name_en)) {
    if (isExpanded(market.id)) return values;
    return values.length <= maxItems ? values : values.slice(0, maxItems);
  }

  if (isThreeWayMarket(market)) {
    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]);
    }
    sortedValues = sortedValues.concat(others);
    if (isExpanded(market.id)) return sortedValues;
    return sortedValues.length <= maxItems ? sortedValues : sortedValues.slice(0, maxItems);
  }
  
  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];
  }

  if (isExpanded(market.id)) return sortedValues;
  return sortedValues.length <= maxItems ? sortedValues : sortedValues.slice(0, maxItems);
};

const hasMore = (market) => market && market.values && market.values.length > getMaxItems(market);

const fetchData = async () => {
  if (!dataId.value) return;
  loading.value = true;
  try {
    const res = await getSportInfo({ data_id: dataId.value });
    if (res && res.code === 1 && res.data) {
      if (typeof res.data.odds === 'string') {
        try { res.data.odds = JSON.parse(res.data.odds); } catch(e) { res.data.odds = []; }
      }
      matchInfo.value = res.data;
      matchInfo.value.odds.forEach(jtem => {
        if(matchInfo.value.odd_ids_locked?.find(trim => jtem.id === trim)) {
          jtem.is_findLocked = true
        }
      })
    } else {
      router.back();
    }
  } catch (e) {
    console.error(e);
  } finally {
    loading.value = false;
  }
};

const goBack = () => {
  router.back();
};

const handleSocketMessage = (e) => {
  try {
    const res = e.detail;
    if (!res || res.type !== 'sport_list' || !Array.isArray(res.message)) return;

    const newMatchData = res.message.find(m => m.data_id === matchInfo.value?.data_id);
    if (!newMatchData || !matchInfo.value) return;

    const oldMatch = matchInfo.value;

    let parsedNewOdds = newMatchData.odds;
    if (typeof parsedNewOdds === 'string') {
      try { parsedNewOdds = JSON.parse(parsedNewOdds); } catch(e) { parsedNewOdds = []; }
    } else if (!parsedNewOdds) {
      parsedNewOdds = oldMatch.odds;
    }

    if (oldMatch.odds && Array.isArray(oldMatch.odds) && parsedNewOdds && Array.isArray(parsedNewOdds)) {
      parsedNewOdds.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?.odd && newOpt?.odd) {
              const oldOddNum = parseFloat(oldOpt.odd);
              const newOddNum = parseFloat(newOpt.odd);
              if (!isNaN(oldOddNum) && !isNaN(newOddNum) && oldOddNum !== newOddNum) {
                const matchId = oldMatch.id || oldMatch.data_id;
                const key = getOddsKey(matchId, 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);
              }
            }
          });
        }
      });
    }

    if (checkIsLocked(newMatchData)) {
      if (newMatchData.odds && newMatchData.odds.length > 0) {
        newMatchData.odds.forEach(market => {
          if (market.values) {
            market.values.forEach(wsItem => {
              const uniqueKey = getUniqueKey(matchInfo.value.id, market.id, wsItem);
              if (selectedMap.value[uniqueKey]) {
                orderStore.removeOrderItemByKey(uniqueKey);
              }
            });
          }
        });
      }
    }

    matchInfo.value = {
      ...oldMatch,
      ...newMatchData,
      odds: parsedNewOdds
    };

  } catch (error) {
    console.error('详情页 WebSocket 数据解析失败', error);
  }
};

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

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

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

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

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

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

const formatGameTime = (timestamp, formatStr) => {
  if (!timestamp) return '';
  const date = new Date(timestamp * 1000);
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  const h = String(date.getHours()).padStart(2, '0');
  const min = String(date.getMinutes()).padStart(2, '0');
  if (formatStr === 'MM-DD') return `${m}-${d}`;
  if (formatStr === 'HH:mm') return `${h}:${min}`;
  return `${m}-${d} ${h}:${min}`;
};

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

const getGridClass = (market) => {
  if (!market || !market.values) return 'cols-2';
  if (isThreeWayMarket(market)) return 'cols-3';
  if (isSlashGroupMarket(market)) {
    return getSlashHeadersInfo(market).headers.length === 3 ? 'cols-3' : 'cols-2';
  }
  if (isOverUnderMixedMarket(market)) return 'cols-2';
  if (threeColMarkets.includes(market.name_en)) return 'cols-3';

  const len = market.values.length;
  if (len === 1) return 'cols-1';
  return 'cols-2';
};

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

const handleBet = (market, selection) => {
  if (checkIsLocked(matchInfo.value)) return;
  if (!selection.odd) return;
  if (selection.suspended) return;

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

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

    const betItem = {
      matchId: matchInfo.value.id,
      data_id: matchInfo.value.data_id,
      league: locale.value === 'zh' ? matchInfo.value.league : matchInfo.value.league_en,
      homeTeam: locale.value === 'zh' ? matchInfo.value.home_team : matchInfo.value.home_team_en,
      guestTeam: locale.value === 'zh' ? matchInfo.value.guest_team : matchInfo.value.guest_team_en,
      betType: locale.value === 'zh' ? market.name : market.name_en,
      betTypeName: translateSelection(locale.value === 'zh' ? selection.value_text : selection.value),
      handicap: selection.handicap,
      handicap_text: selection.handicap_text,
      odds: selection.odd,
      score: matchInfo.value.score,
      state: matchInfo.value.state,
      status: matchInfo.value.status,
      is_roll: matchInfo.value.is_roll,
      is_locked: matchInfo.value.is_locked,
      uniqueKey: uniqueKey,
      optionValue: selection.value,
      submit_value: selection.submit_value,
      marketId: market.id,
       mininum: market.mininum, // 新增：最低限额
      maxinum: market.maxinum, // 新增：最高限额
      selection: {
        ...selection
      }
    };

    orderStore.addOrderItem(betItem);
  }
};
</script>

<style scoped lang="scss">
$main-color: #f8b932;

.pc-sport-detail-container {
  min-height: 100%;
  background-color: var(--el-bg-color-page);
  padding-bottom: 40px;
}

/* =====================================
   1. 顶部赛事看板 (沉浸式暗黑)
   ===================================== */
.scoreboard-banner {
  position: relative;
  background: linear-gradient(135deg, #101423 0%, #1e253c 100%);
  color: #ffffff;
  padding: 30px 40px 60px;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);

  .bg-glow {
    position: absolute;
    width: 300px; height: 300px;
    border-radius: 50%;
    filter: blur(80px);
    opacity: 0.15;
    pointer-events: none;
    &.left-glow { top: -100px; left: -100px; background: #3b82f6; }
    &.right-glow { bottom: -100px; right: -100px; background: $main-color; }
  }

  .bg-pattern {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background-image: radial-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px);
    background-size: 20px 20px;
    pointer-events: none; opacity: 0.5;
  }

  .banner-top {
    position: relative; z-index: 2;
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 40px;

    .back-btn { color: rgba(255, 255, 255, 0.8); font-size: 15px; &:hover { color: #fff; } }
    .league-name { display: flex; align-items: center; font-size: 18px; font-weight: bold; color: #fff; letter-spacing: 1px; }
    .placeholder-right { width: 80px; }
  }

  .banner-main {
    position: relative; z-index: 2;
    display: flex; justify-content: center; align-items: center; gap: 60px;

    .team-panel {
      display: flex; align-items: center; gap: 24px; flex: 1;
      .team-name { font-size: 28px; font-weight: 800; color: #fff; max-width: 300px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
      .logo-wrapper { background: rgba(255, 255, 255, 0.05); border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); width: 100px;height: 100px; display: flex;align-items: center;justify-content: center; }
      &.home { justify-content: flex-end; }
      &.away { justify-content: flex-start; }
    }

    .score-panel {
      display: flex; flex-direction: column; align-items: center; min-width: 180px;
      .time-board { text-align: center; .date { font-size: 16px; color: rgba(255, 255, 255, 0.7); margin-bottom: 4px; } .time { font-size: 40px; font-weight: bold; } }
      .score-board {
        text-align: center;
        .score-numbers { display: flex;
          width: 100%;
          justify-content: center;
          align-items: center; gap: 16px; .num { font-size: 56px; font-weight: 900; color: $main-color; line-height: 1; text-shadow: 0 0 20px rgba(248, 185, 50, 0.4); } .divider { font-size: 32px; color: rgba(255, 255, 255, 0.5); padding-bottom: 8px; } }
        .half-score { margin-top: 12px; font-size: 14px; color: rgba(255, 255, 255, 0.6); }
      }
      .status-badge { background: rgba(255, 255, 255, 0.1); padding: 4px 16px; border-radius: 20px; font-size: 13px; color: rgba(255, 255, 255, 0.9); }
      .live-timer {
        display: flex; align-items: center; gap: 8px; padding: 4px 16px; border-radius: 20px;
        .timer-text { font-weight: bold; font-size: 14px; }
        .live-dot { width: 8px; height: 8px; border-radius: 50%; }

        /* 未开始 (state: 0) - 橙色/警告色 */
        &.is-warning {
          background: rgba(230, 162, 60, 0.15); border: 1px solid rgba(230, 162, 60, 0.3);
          .timer-text { color: var(--el-color-warning); }
        }
        /* 进行中 (state: 1) - 绿色/成功色 */
        &.is-success {
          background: rgba(103, 194, 58, 0.15); border: 1px solid rgba(103, 194, 58, 0.3);
          .timer-text { color: var(--el-color-success); }
          .live-dot { background-color: var(--el-color-success); animation: blink 1.2s infinite; }
        }
        /* 已完场/取消/延期 (state: 2,3,4) - 红色/危险色 */
        &.is-danger {
          background: rgba(245, 108, 108, 0.15); border: 1px solid rgba(245, 108, 108, 0.3);
          .timer-text { color: var(--el-color-danger); }
        }
      }
    }
  }
}

/* =====================================
   2. 盘口卡片区 (每个玩法独占一行)
   ===================================== */
.markets-container {
  padding: 24px 40px;
  margin-top: -30px;
  position: relative;
  z-index: 10;

  .markets-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
  }

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

    :deep(.el-card__body) {
      padding: 0;
    }

    .market-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 10px 16px;
      background-color: var(--el-fill-color-light);
      border-bottom: 1px solid var(--el-border-color-lighter);

      .header-left {
        display: flex;
        align-items: center;
        .decorate-bar { width: 4px; height: 16px; background-color: $main-color; border-radius: 2px; margin-right: 10px; }
        .title { font-size: 14px; font-weight: bold; color: var(--el-text-color-primary); }
      }
    }
  }
}

/* === 新增的双列头部样式 === */
.pair-headers {
  display: flex;
  gap: 8px;
  padding: 12px 12px 0 12px;
  .pair-header-item {
    flex: 1;
    text-align: center;
    font-size: 13px;
    color: var(--el-text-color-regular);
    font-weight: 500;
  }
}

/* === 网格列布局与按钮内部布局 === */
.odds-wrapper {
  padding: 12px;
  display: grid;
  gap: 8px;

  &.cols-1 { grid-template-columns: 1fr; }
  &.cols-2 { grid-template-columns: repeat(2, 1fr); }
  &.cols-3 { grid-template-columns: repeat(3, 1fr); }
  &.cols-4 { grid-template-columns: repeat(4, 1fr); }
  &.cols-5 { grid-template-columns: repeat(5, 1fr); }
  &.cols-6 { grid-template-columns: repeat(6, 1fr); }
  &.cols-7 { grid-template-columns: repeat(7, 1fr); }
  &.cols-8 {
    grid-template-columns: repeat(8, 1fr);
    @media screen and (max-width: 1600px) { grid-template-columns: repeat(6, 1fr); }
    @media screen and (max-width: 1300px) { grid-template-columns: repeat(4, 1fr); }
    @media screen and (max-width: 900px)  { grid-template-columns: repeat(2, 1fr); }
  }

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

    .selection-info {
      display: flex;
      flex-direction: column;
      align-items: flex-start;
      justify-content: center;
      min-width: 0;
      flex: 1;
      margin-right: 8px;
      z-index: 1;

      .selection-name {
        font-size: 12px;
        color: var(--el-text-color-primary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        width: 100%;
      }
      .handicap-wrap {
        margin-top: 2px;
      }
      .handicap-val {
        font-size: 12px;
        color: var(--el-text-color-primary);
        font-weight: bold;
        flex-shrink: 0;
      }
    }

    .odds-val-info {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      gap: 4px;
      flex-shrink: 0;
      z-index: 1;

      .odds-val {
        font-size: 14px;
        font-weight: bold;
        color: $main-color;
      }
    }

    &:hover {
      border-color: $main-color;
      background-color: var(--el-color-primary-light-9);
    }

    &.is-active {
      background-color: $main-color;
      border-color: $main-color;
      .selection-info .selection-name,
      .selection-info .handicap-val,
      .odds-val-info .odds-val { color: #fff; }
    }

    &.is-locked {
      cursor: not-allowed;
      border-color: transparent;
      background-color: var(--el-fill-color-darker);

      .selection-info, .odds-val-info .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;
      }
    }

    &.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;
      &.up { color: #4caf50; }
      &.down { color: #f56c6c; }
    }
  }
}

.mr-1 { margin-right: 4px; }
.mr-2 { margin-right: 8px; }
.mt-2 { margin-top: 8px; }
.ml-1 { margin-left: 4px; }

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* =====================================
   新增比赛事件 (时间线) 的专属样式
   ===================================== */
.events-timeline {
  position: relative;
  padding: 30px 0;

  .timeline-line {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 2px;
    background: var(--el-border-color-darker);
    transform: translateX(-50%);
  }

  .timeline-item {
    position: relative;
    display: flex;
    align-items: center;
    margin-bottom: 20px;

    &:last-child {
      margin-bottom: 0;
    }

    .time-box {
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      width: 32px;
      height: 32px;
      background-color: var(--el-bg-color-overlay);
      border: 2px solid $main-color;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 12px;
      font-weight: bold;
      color: $main-color;
      z-index: 2;
    }

    .event-box {
      width: 50%;
      display: flex;
      align-items: center;
      padding: 0 30px;
      box-sizing: border-box;
    }
  }

  .is-home .event-box {
    margin-right: auto;
    justify-content: flex-end;
  }

  .is-away .event-box {
    margin-left: auto;
    justify-content: flex-start;
  }

  .event-details {
    display: flex;
    flex-direction: column;
    gap: 2px;

    &.text-right { text-align: right; }
    &.text-left { text-align: left; }

    .player-name {
      font-size: 13px;
      font-weight: bold;
      color: var(--el-text-color-primary);
    }
    .event-desc {
      font-size: 12px;
      color: var(--el-text-color-regular);
    }
  }

  .event-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;

    .card-icon {
      width: 14px;
      height: 18px;
      border-radius: 2px;
      &.yellow { background-color: #e6a23c; border: 1px solid #b57d2a; }
      &.red { background-color: #f56c6c; border: 1px solid #c25050; }
    }
  }

  .ml-2 { margin-left: 8px; }
  .mr-2 { margin-right: 8px; }
}
</style>