<template>
  <div class="tournament-bracket-root">
    <h1>单败淘汰赛赛程树状图</h1>
    <div class="tournament-info">
      <p><strong>总轮数:</strong> {{ totalRounds }} 轮 (基于 {{ participantCount }} 位参赛者)</p>
    </div>
    <div class="container">
      <div class="bracket-container" id="bracketContainer">
        <div class="zoom-controls">
          <button class="zoom-btn" @click="zoomIn" title="放大 (+)">+</button>
          <button class="zoom-btn" @click="zoomOut" title="缩小 (-)">-</button>
          <button class="zoom-btn" @click="resetZoom" title="重置视图 (0)">⌂</button>
        </div>
        <div class="interaction-hint" v-if="tournament.matches.length > 0">
          <span>💡 点击比赛查看详情/录入比分 | 拖拽移动 | 滚轮缩放</span>
        </div>
        <svg id="d3-bracket" class="d3-bracket"></svg>
      </div>
    </div>

    <!-- 比赛详情弹窗 -->
    <MatchDetailsModal
      :visible="showMatchModal"
      :match="selectedMatch"
      :is-organizer="isOrganizer"
      @close="closeMatchModal"
      @submit="handleMatchSubmit"
    />

    <!-- 对话框组件 -->
    <SuccessDialog
      :visible="successDialog.visible"
      :message="successDialog.message"
      @close="successDialog.visible = false"
    />
    <ErrorDialog
      :visible="errorDialog.visible"
      :message="errorDialog.message"
      @close="errorDialog.visible = false"
    />
  </div>
</template>

<script setup>
import { ref, computed, onMounted, nextTick, onUnmounted } from 'vue';
import { getSignUpResultList, updateSignUpResult, getTournamentList, addSignUpResult } from '@/api/tournament';
import { getStoredUser } from '@/utils/jwt.js';
import * as d3 from 'd3';
import SuccessDialog from '@/components/SuccessDialog.vue';
import ErrorDialog from '@/components/ErrorDialog.vue';
import MatchDetailsModal from '@/components/MatchDetailsModal.vue';

const props = defineProps({
  tournamentId: {
    type: Number,
    required: true
  }
});

const emit = defineEmits(['refreshPlayers']);

// Dialog state
const successDialog = ref({ visible: false, message: '' });
const errorDialog = ref({ visible: false, message: '' });

// Match Modal state
const showMatchModal = ref(false);
const selectedMatch = ref({});
const isOrganizer = ref(false);

// Store zoom behavior for external control
let zoomBehavior = null;
let svgSelection = null;

const tournament = ref({
  id: props.tournamentId,
  name: '',
  participants: [],
  rounds: 0,
  matches: [],
  apiData: [],
  organizer_qq: ''
});

// 计算总轮数和参赛人数
const totalRounds = computed(() => {
  return tournament.value.rounds;
});

const participantCount = computed(() => {
  return tournament.value.participants.length;
});

onMounted(() => {
  checkPermission();
  loadTournamentData();
  
  // Add keyboard shortcuts for zoom control
  const handleKeydown = (event) => {
    if (event.target.tagName === 'INPUT') return;
    
    switch(event.key) {
      case '+':
      case '=':
        event.preventDefault();
        zoomIn();
        break;
      case '-':
        event.preventDefault();
        zoomOut();
        break;
      case '0':
        event.preventDefault();
        resetZoom();
        break;
    }
  };
  
  document.addEventListener('keydown', handleKeydown);
  
  // Store cleanup function
  onUnmounted(() => {
    document.removeEventListener('keydown', handleKeydown);
    const svg = d3.select('#d3-bracket');
    if (svg.node()) svg.selectAll('*').remove();
  });
});

const checkPermission = async () => {
  try {
    const tournaments = await getTournamentList();
    const selectedTournament = tournaments.find(t => t.id === props.tournamentId);
    if (selectedTournament) {
      tournament.value.organizer_qq = selectedTournament.qq_code;
      const user = getStoredUser();
      isOrganizer.value = user && String(user.qq_code) === String(selectedTournament.qq_code);
    }
  } catch (error) {
    console.error('权限检查失败:', error);
  }
};

const loadTournamentData = async () => {
  if (!props.tournamentId) return;
  
  tournament.value.id = props.tournamentId;
  
  try {
    // 获取锦标赛信息
    const tournaments = await getTournamentList();
    const selectedTournament = tournaments.find(t => t.id === props.tournamentId);
    if (selectedTournament) {
      tournament.value.name = selectedTournament.name;
    }
    
    // 获取参赛者数据（第0轮）
    const data = await getSignUpResultList();
    const filtered = data.filter(item => 
      item.tournament_id == props.tournamentId && 
      parseInt(item.round || 0) === 0
    );
    const participants = filtered.map(item => ({ id: item.id, name: item.sign_name }));
    tournament.value.participants = participants;
    
    // 保存API数据
    tournament.value.apiData = data.filter(item => item.tournament_id == tournament.value.id);
    
    // 计算总轮数
    tournament.value.rounds = Math.ceil(Math.log2(participants.length));
    
    // 生成单败淘汰赛树状图
    if (participants.length >= 2) {
      await generateSingleEliminationBracket();
      nextTick(() => drawD3Bracket());
    }
  } catch (err) {
    errorDialog.value = { visible: true, message: '获取比赛数据失败: ' + err.message };
  }
};

const generateSingleEliminationBracket = async () => {
  tournament.value.matches = [];
  
  // 获取所有API数据
  const allData = await getSignUpResultList();
  const tournamentData = allData.filter(item => item.tournament_id == tournament.value.id);
  tournament.value.apiData = tournamentData;
  
  // 按轮数分组数据
  const roundsData = {};
  tournamentData.forEach(item => {
    const round = parseInt(item.round || 0);
    if (!roundsData[round]) {
      roundsData[round] = [];
    }
    roundsData[round].push(item);
  });
  
  // 获取所有存在的轮次
  const existingRounds = Object.keys(roundsData).map(Number).sort((a, b) => a - b);

  // 生成所有轮次的比赛
  for (const round of existingRounds) {
      if (round === 0) {
      await generateRound0Matches(roundsData[round] || []);
      } else {
      await generateRoundMatches(round, roundsData[round] || []);
      }
    }
    
  // 更新总轮数为实际存在的最大轮次
  if (existingRounds.length > 0) {
    tournament.value.rounds = Math.max(...existingRounds);
  }
};

const generateRound0Matches = async (round0Data) => {
      const matches = [];
      const usedPlayers = new Set();
      
  // 处理正常配对
  for (const player of round0Data) {
        if (usedPlayers.has(player.id)) continue;
        
        const rivalName = player.rival_name;
        const isBye = rivalName === '轮空' || rivalName === 'bye' || rivalName === 'BYE' || rivalName === 'Bye';
        const isPending = rivalName === '待定' || rivalName === 'pending' || rivalName === 'PENDING' || rivalName === 'Pending';
        
    if (isBye || isPending) continue;
    
          // 寻找对手
    const rival = round0Data.find(p => 
            p.sign_name === rivalName && p.id !== player.id && !usedPlayers.has(p.id)
          );
          
          if (rival) {
            const matchNumber = matches.length + 1;
            matches.push({
        id: `0-${matchNumber}`,
        round: 0,
              matchNumber: matchNumber,
        participant1: { id: player.id, name: player.sign_name },
        participant2: { id: rival.id, name: rival.sign_name },
              winner: null,
              score1: parseInt(player.win || 0),
              score2: parseInt(rival.win || 0),
              decided: false
            });
            usedPlayers.add(player.id);
            usedPlayers.add(rival.id);
        }
      }
      
  // 处理轮空
  for (const player of round0Data) {
        if (usedPlayers.has(player.id)) continue;
        
        const rivalName = player.rival_name;
        const isBye = rivalName === '轮空' || rivalName === 'bye' || rivalName === 'BYE' || rivalName === 'Bye';
        
        if (isBye) {
          const matchNumber = matches.length + 1;
          matches.push({
        id: `0-${matchNumber}`,
        round: 0,
            matchNumber: matchNumber,
        participant1: { id: player.id, name: player.sign_name },
            participant2: null,
        winner: { id: player.id, name: player.sign_name },
            score1: 1,
            score2: 0,
            decided: true
          });
          usedPlayers.add(player.id);
        }
      }
      
      tournament.value.matches.push(...matches);
};

const generateRoundMatches = async (round, roundData) => {
      const matches = [];
      const usedPlayers = new Set();
      
  // 处理已有数据的比赛
  for (const player of roundData) {
          if (usedPlayers.has(player.id)) continue;
          
          const rivalName = player.rival_name;
          const isBye = rivalName === '轮空' || rivalName === 'bye' || rivalName === 'BYE' || rivalName === 'Bye';
          const isPending = rivalName === '待定' || rivalName === 'pending' || rivalName === 'PENDING' || rivalName === 'Pending';
          
          if (isBye || isPending) continue;
    
            // 寻找对手
    const rival = roundData.find(p => 
              p.sign_name === rivalName && p.id !== player.id && !usedPlayers.has(p.id)
            );
            
            if (rival) {
              const matchNumber = matches.length + 1;
              
              // 判断比赛是否已完成
              const playerStatus = player.status;
              const rivalStatus = rival.status;
              const playerWin = parseInt(player.win || 0);
              const rivalWin = parseInt(rival.win || 0);
              
              // 如果任一玩家有胜场，说明比赛已完成
              const isDecided = playerWin > 0 || rivalWin > 0 || 
                               playerStatus === 'win' || playerStatus === 'lose' || 
                               rivalStatus === 'win' || rivalStatus === 'lose';
              
              // 确定获胜者
              let winner = null;
              if (playerStatus === 'win' || playerWin > rivalWin) {
                winner = { id: player.id, name: player.sign_name };
              } else if (rivalStatus === 'win' || rivalWin > playerWin) {
                winner = { id: rival.id, name: rival.sign_name };
              }
              
              matches.push({
                id: `${round}-${matchNumber}`,
                round: round,
                matchNumber: matchNumber,
                participant1: { id: player.id, name: player.sign_name },
                participant2: { id: rival.id, name: rival.sign_name },
                winner: winner,
                score1: parseInt(player.win || 0),
                score2: parseInt(rival.win || 0),
                decided: isDecided
              });
              usedPlayers.add(player.id);
              usedPlayers.add(rival.id);
            }
        }
        
  // 处理轮空
  for (const player of roundData) {
    if (usedPlayers.has(player.id)) continue;
          
          const rivalName = player.rival_name;
          const isBye = rivalName === '轮空' || rivalName === 'bye' || rivalName === 'BYE' || rivalName === 'Bye';
          
          if (isBye) {
            const matchNumber = matches.length + 1;
            matches.push({
              id: `${round}-${matchNumber}`,
              round: round,
              matchNumber: matchNumber,
              participant1: { id: player.id, name: player.sign_name },
              participant2: null,
              winner: { id: player.id, name: player.sign_name },
              score1: 1,
              score2: 0,
              decided: true
            });
            usedPlayers.add(player.id);
          }
        }
  
  // 处理待定的玩家（单独显示）
  for (const player of roundData) {
    if (usedPlayers.has(player.id)) continue;
    
    const rivalName = player.rival_name;
    const isPending = rivalName === '待定' || rivalName === 'pending' || rivalName === 'PENDING' || rivalName === 'Pending';
    
    if (isPending) {
      const matchNumber = matches.length + 1;
      
      // 判断比赛是否已完成（如果玩家状态是win或lose，或者有胜场，说明比赛已完成）
      const playerWin = parseInt(player.win || 0);
      const isDecided = player.status === 'win' || player.status === 'lose' || playerWin > 0;
      let winner = null;
      if (player.status === 'win' || playerWin > 0) {
        winner = { id: player.id, name: player.sign_name };
      }
      
      matches.push({
        id: `${round}-${matchNumber}`,
        round: round,
        matchNumber: matchNumber,
        participant1: { id: player.id, name: player.sign_name },
        participant2: null,
        winner: winner,
        score1: parseInt(player.win || 0),
        score2: 0,
        decided: isDecided
      });
      usedPlayers.add(player.id);
    }
  }
  
      tournament.value.matches.push(...matches);
};

const openMatchModal = (match) => {
  selectedMatch.value = { ...match };
  showMatchModal.value = true;
};

const closeMatchModal = () => {
  showMatchModal.value = false;
  selectedMatch.value = {};
};

const handleMatchSubmit = async (updatedMatch) => {
  await confirmScore(updatedMatch);
};

const confirmScore = async (match) => {
  console.log('确认比分:', match);
  
  // 处理轮空比赛
  if (!match.participant2) {
    if (!match.decided) {
      match.winner = match.participant1;
      match.decided = true;
      match.score1 = 1;
      match.score2 = 0;
    }
    
    // 更新轮空玩家的状态并创建新记录
    try {
      const p1Data = tournament.value.apiData.find(item => item.id === match.participant1.id);
      
      if (p1Data) {
        // 更新轮空玩家的状态
        const winnerUpdate = {
          ...p1Data,
          win: '1',
          lose: '0',
          status: 'win'
        };
        
        await updateSignUpResult(p1Data.id, winnerUpdate);
        
        // 为轮空玩家创建新的API记录（轮数+1）
        const nextRound = parseInt(p1Data.round || 0) + 1;
        const newRecord = {
          tournament_id: parseInt(p1Data.tournament_id),
          tournament_name: p1Data.tournament_name,
          team_name: p1Data.team_name || null,
          sign_name: p1Data.sign_name,
          win: '0',
          lose: '0',
          status: 'tie',
          round: String(nextRound),
          rival_name: '待定'
        };
        
        // 检查是否已存在该玩家的晋级记录
        const existingRecord = tournament.value.apiData.find(item => 
          item.sign_name === p1Data.sign_name && 
          parseInt(item.round) === nextRound
        );
        
        if (!existingRecord) {
          await addSignUpResult(newRecord);
          // 尝试匹配对手
          await matchOpponentsInRound(nextRound);
        }
      }
      } catch (error) {
      console.error('处理轮空晋级失败:', error);
      }
    
    nextTick(() => drawD3Bracket());
    await loadTournamentData();
    emit('refreshPlayers');
    return;
    }
    
  // 验证比分
  const s1 = Number(match.score1);
  const s2 = Number(match.score2);
  
  // 设置比赛结果
  match.score1 = s1;
  match.score2 = s2;
  match.winner = s1 > s2 ? match.participant1 : match.participant2;
  match.decided = true;
  
  // 更新API数据
  try {
    const p1Data = tournament.value.apiData.find(item => item.id === match.participant1.id);
    const p2Data = tournament.value.apiData.find(item => item.id === match.participant2.id);
    
    if (p1Data && p2Data) {
      // 更新玩家1
      const update1 = {
        ...p1Data,
        win: String(s1),
        lose: String(s2),
        status: s1 > s2 ? 'win' : 'lose'
      };
      await updateSignUpResult(p1Data.id, update1);
      
      // 更新玩家2
      const update2 = {
        ...p2Data,
        win: String(s2),
        lose: String(s1),
        status: s2 > s1 ? 'win' : 'lose'
      };
      await updateSignUpResult(p2Data.id, update2);
      
      // 处理晋级
      await handlePlayerAdvancement(match);
      
      successDialog.value = { visible: true, message: '比分已确认' };
      await loadTournamentData();
      emit('refreshPlayers');
    }
  } catch (error) {
    console.error('更新比分失败:', error);
    errorDialog.value = { visible: true, message: '更新比分失败' };
  }
};

const handlePlayerAdvancement = async (match) => {
  if (!match.winner) return;
  
  const nextRound = match.round + 1;
  
  // 检查是否到达最后一轮
  if (nextRound > tournament.value.rounds) return;
  
  // 获胜者晋级
  try {
    const winnerData = tournament.value.apiData.find(item => item.id === match.winner.id);
    if (winnerData) {
      // 检查是否已经存在该玩家在下一轮的记录
      const existingNextRoundRecord = tournament.value.apiData.find(item => 
        item.tournament_id == tournament.value.id && 
        item.sign_name === winnerData.sign_name && 
        parseInt(item.round || 0) === nextRound
      );
      
      if (existingNextRoundRecord) {
        // 如果已存在下一轮记录，更新状态
        const updateData = {
          ...existingNextRoundRecord,
          win: '0',
          lose: '0',
          status: 'tie',
          rival_name: '待定'
        };
        await updateSignUpResult(existingNextRoundRecord.id, updateData);
      } else {
        // 如果不存在下一轮记录，创建新记录
        const advancementData = {
          tournament_id: parseInt(winnerData.tournament_id),
          tournament_name: winnerData.tournament_name,
          team_name: winnerData.team_name || null,
          sign_name: winnerData.sign_name,
          win: '0',
          lose: '0',
          status: 'tie',
          round: String(nextRound),
          rival_name: '待定'
        };
        await addSignUpResult(advancementData);
      }
      
      // 尝试匹配对手
      await matchOpponentsInRound(nextRound);
    }
  } catch (error) {
    console.error('处理晋级记录失败:', error);
  }
};

// 匹配指定轮次的对手
const matchOpponentsInRound = async (round) => {
  try {
    // 重新获取最新数据
    const allData = await getSignUpResultList();
    const roundData = allData.filter(item => 
      item.tournament_id == tournament.value.id &&
      parseInt(item.round) === round && 
      item.rival_name === '待定'
    );
    
    // 如果待定玩家数量为偶数，可以两两匹配
    if (roundData.length >= 2 && roundData.length % 2 === 0) {
        // 按ID排序，确保从上到下的顺序
        const sortedPlayers = roundData.sort((a, b) => a.id - b.id);
        
        // 按照从上到下的顺序两两匹配
        for (let i = 0; i < sortedPlayers.length; i += 2) {
          const player1 = sortedPlayers[i];
          const player2 = sortedPlayers[i + 1];
          
          if (player1 && player2) {
            // 更新player1的对手
            await updateSignUpResult(player1.id, {
              ...player1,
              rival_name: player2.sign_name
            });
            
            // 更新player2的对手
            await updateSignUpResult(player2.id, {
              ...player2,
              rival_name: player1.sign_name
            });
          }
        }
    }
  } catch (error) {
    console.error(`匹配第${round}轮对手失败:`, error);
  }
};

// D3.js drawing function
const drawD3Bracket = () => {
  const margin = { top: 40, right: 40, bottom: 40, left: 40 };
  const matchWidth = 200;
  const matchHeight = 100;
  const roundGap = 80;
  const matchGap = 40;

  const rounds = tournament.value.rounds + 1;
  // 计算每一轮的比赛数量
  const matchesPerRound = [];
  for (let i = 0; i < rounds; i++) {
    const matchesInRound = tournament.value.matches.filter(m => m.round === i);
    matchesPerRound.push(matchesInRound.length || Math.pow(2, tournament.value.rounds - i - 1));
  }
  const maxMatchesInRound = Math.max(...matchesPerRound);

  const totalWidth = rounds * (matchWidth + roundGap) + margin.left + margin.right;
  const totalHeight = maxMatchesInRound * (matchHeight + matchGap) + margin.top + margin.bottom;

  const container = document.getElementById('bracketContainer');
  const containerWidth = container.clientWidth - 30;
  const containerHeight = container.clientHeight - 30;

  const svg = d3.select('#d3-bracket')
    .attr('width', containerWidth)
    .attr('height', containerHeight)
    .attr('viewBox', `0 0 ${totalWidth} ${totalHeight}`)
    .attr('preserveAspectRatio', 'xMidYMid meet');

  // Clear previous content
  svg.selectAll('*').remove();

  // Create zoom behavior
  const zoom = d3.zoom()
    .scaleExtent([0.1, 3])
    .on('zoom', (event) => {
      g.attr('transform', `translate(${margin.left},${margin.top}) ${event.transform}`);
    });
  
  zoomBehavior = zoom;
  svgSelection = svg;

  svg.call(zoom);

  svg.style('cursor', 'grab')
    .on('mousedown', () => svg.style('cursor', 'grabbing'))
    .on('mouseup', () => svg.style('cursor', 'grab'));

  const g = svg.append('g')
    .attr('transform', `translate(${margin.left},${margin.top})`);

  // Draw matches for each round
  for (let roundIndex = 0; roundIndex < rounds; roundIndex++) {
    const roundMatches = tournament.value.matches.filter(m => m.round === roundIndex)
      .sort((a, b) => a.matchNumber - b.matchNumber);
    
    if (roundMatches.length === 0) continue;

    const roundX = roundIndex * (matchWidth + roundGap);
    
    // Calculate Y positions to center matches relative to previous round
    const roundStartY = (totalHeight - margin.top - margin.bottom - (roundMatches.length * (matchHeight + matchGap))) / 2;

    // Round title
    g.append('text')
      .attr('x', roundX + matchWidth / 2)
      .attr('y', -10)
      .attr('text-anchor', 'middle')
      .attr('class', 'round-title')
      .style('font-weight', 'bold')
      .style('font-size', '16px')
      .style('fill', '#606266')
      .text(`第 ${roundIndex + 1} 轮`);

    roundMatches.forEach((match, index) => {
      // Calculate Y position based on bracket logic (centering parents)
      let matchY;
      if (roundIndex === 0) {
        matchY = roundStartY + index * (matchHeight + matchGap);
      } else {
        // Find child matches in previous round
        const prevRoundMatches = tournament.value.matches.filter(m => m.round === roundIndex - 1)
          .sort((a, b) => a.matchNumber - b.matchNumber);
        
        const childMatch1 = prevRoundMatches[index * 2];
        const childMatch2 = prevRoundMatches[index * 2 + 1];
        
        if (childMatch1 && childMatch2 && childMatch1._y !== undefined && childMatch2._y !== undefined) {
          matchY = (childMatch1._y + childMatch2._y) / 2 - matchHeight / 2;
        } else if (childMatch1 && childMatch1._y !== undefined) {
           matchY = childMatch1._y; // Should not happen in standard bracket but handle safely
        } else {
           matchY = roundStartY + index * (matchHeight + matchGap);
        }
      }

      // Match container group
      const matchGroup = g.append('g')
        .attr('class', 'match-group')
        .attr('transform', `translate(${roundX}, ${matchY})`)
        .style('cursor', 'pointer')
        .on('click', () => openMatchModal(match));

      // Match background
      matchGroup.append('rect')
        .attr('width', matchWidth)
        .attr('height', matchHeight)
        .attr('rx', 8)
        .style('fill', 'white')
        .style('stroke', match.decided ? '#67c23a' : '#dcdfe6')
        .style('stroke-width', match.decided ? 2 : 1)
        .style('filter', 'drop-shadow(0 2px 4px rgba(0,0,0,0.05))');

      // Match ID
      matchGroup.append('text')
        .attr('x', 10)
        .attr('y', 20)
        .style('font-size', '12px')
        .style('fill', '#909399')
        .text(`#${match.matchNumber}`);

      // Participant 1
      const p1Group = matchGroup.append('g').attr('transform', `translate(10, 35)`);
      p1Group.append('rect')
        .attr('width', matchWidth - 20)
        .attr('height', 24)
        .attr('rx', 4)
        .style('fill', match.winner && match.participant1 && match.winner.id === match.participant1.id ? '#f0f9eb' : '#f5f7fa');
      
      p1Group.append('text')
        .attr('x', 8)
        .attr('y', 17)
        .style('font-size', '13px')
        .style('font-weight', match.winner && match.participant1 && match.winner.id === match.participant1.id ? 'bold' : 'normal')
        .style('fill', '#303133')
        .text(match.participant1 ? match.participant1.name : '待定');
        
      if (match.decided) {
        p1Group.append('text')
          .attr('x', matchWidth - 30)
          .attr('y', 17)
          .style('font-weight', 'bold')
          .style('text-anchor', 'end')
          .text(match.score1);
      }

      // Participant 2
      const p2Group = matchGroup.append('g').attr('transform', `translate(10, 65)`);
      p2Group.append('rect')
        .attr('width', matchWidth - 20)
        .attr('height', 24)
        .attr('rx', 4)
        .style('fill', match.winner && match.participant2 && match.winner.id === match.participant2.id ? '#f0f9eb' : '#f5f7fa');
      
      p2Group.append('text')
        .attr('x', 8)
        .attr('y', 17)
        .style('font-size', '13px')
        .style('font-weight', match.winner && match.participant2 && match.winner.id === match.participant2.id ? 'bold' : 'normal')
        .style('fill', '#303133')
        .text(match.participant2 ? match.participant2.name : '待定');

      if (match.decided) {
        p2Group.append('text')
          .attr('x', matchWidth - 30)
          .attr('y', 17)
          .style('font-weight', 'bold')
          .style('text-anchor', 'end')
          .text(match.score2);
      }

      // Store coordinates for connections
      match._x = roundX + matchWidth;
      match._y = matchY + matchHeight / 2;
      match._leftX = roundX;
    });
  }

  // Draw connections
  tournament.value.matches.forEach(match => {
    if (match.round > 0) {
      // Find parents
      const prevRoundMatches = tournament.value.matches.filter(m => m.round === match.round - 1)
        .sort((a, b) => a.matchNumber - b.matchNumber);
      
      // The match index in current round determines which parents it has
      const currentRoundMatches = tournament.value.matches.filter(m => m.round === match.round)
        .sort((a, b) => a.matchNumber - b.matchNumber);
      const matchIndex = currentRoundMatches.findIndex(m => m.id === match.id);
      
      const parent1 = prevRoundMatches[matchIndex * 2];
      const parent2 = prevRoundMatches[matchIndex * 2 + 1];
      
      if (parent1 && parent1._x !== undefined) {
        drawConnection(g, parent1._x, parent1._y, match._leftX, match._y);
      }
      if (parent2 && parent2._x !== undefined) {
        drawConnection(g, parent2._x, parent2._y, match._leftX, match._y);
      }
    }
  });
};

const drawConnection = (g, x1, y1, x2, y2) => {
  const midX = (x1 + x2) / 2;
  g.append('path')
    .attr('d', `M${x1},${y1} L${midX},${y1} L${midX},${y2} L${x2},${y2}`)
    .style('stroke', '#c0c4cc')
    .style('stroke-width', 2)
    .style('fill', 'none');
};

// Zoom controls
const zoomIn = () => {
  if (zoomBehavior && svgSelection) {
    zoomBehavior.scaleBy(svgSelection.transition().duration(300), 1.2);
  }
};

const zoomOut = () => {
  if (zoomBehavior && svgSelection) {
    zoomBehavior.scaleBy(svgSelection.transition().duration(300), 0.8);
  }
};

const resetZoom = () => {
  if (zoomBehavior && svgSelection) {
    svgSelection.transition().duration(300).call(zoomBehavior.transform, d3.zoomIdentity);
  }
};
</script>

<style scoped>
.tournament-bracket-root {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #f5f7fa;
}

.tournament-info {
  padding: 10px 20px;
  background: white;
  border-bottom: 1px solid #ebeef5;
}

.container {
  flex: 1;
  position: relative;
  overflow: hidden;
  padding: 20px;
}

.bracket-container {
  width: 100%;
  height: 600px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.05);
  position: relative;
  overflow: hidden;
}

.zoom-controls {
  position: absolute;
  bottom: 20px;
  right: 20px;
  display: flex;
  gap: 8px;
  z-index: 10;
}

.zoom-btn {
  width: 32px;
  height: 32px;
  border: 1px solid #dcdfe6;
  background: white;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  color: #606266;
  transition: all 0.3s;
}

.zoom-btn:hover {
  background: #ecf5ff;
  color: #409EFF;
  border-color: #c6e2ff;
}

.interaction-hint {
  position: absolute;
  top: 20px;
  left: 20px;
  background: rgba(255, 255, 255, 0.9);
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 12px;
  color: #909399;
  pointer-events: none;
  z-index: 10;
  border: 1px solid #ebeef5;
}

.d3-bracket {
  width: 100%;
  height: 100%;
}
</style>