<template>
  <div class="martial-schedule-container">
    <div class="page-header">
      <div class="header-left">
        <el-button icon="el-icon-back" size="small" @click="goBack">返回</el-button>
        <h2 class="page-title">编排</h2>
      </div>
      <div class="header-right">
        <el-button
          size="small"
          type="primary"
          :loading="autoArrangeLoading"
          @click="handleAutoArrange"
        >
          {{ isScheduleCompleted ? '重新编排' : '自动编排' }}
        </el-button>
        <el-button size="small" type="danger" @click="showExceptionDialog">
          异常组 <el-badge :value="exceptionList.length" :hidden="exceptionList.length === 0" />
        </el-button>
      </div>
    </div>

    <div class="tabs-section">
        <div class="tab-buttons">
          <el-button
            size="small"
            :type="activeTab === 'competition' ? 'primary' : ''"
            @click="activeTab = 'competition'"
          >
            竞赛分组
          </el-button>
          <el-button
            size="small"
            :type="activeTab === 'venue' ? 'primary' : ''"
            @click="activeTab = 'venue'"
          >
            场地
          </el-button>
        </div>

        <!-- 竞赛分组 Tab -->
        <div v-show="activeTab === 'competition'" class="tab-content">
          
          <!-- 场地列表 -->
          <div class="venue-list">
            <div class="venue-buttons">
              <el-button
                v-for="venue in venues"
                :key="venue.id"
                size="small"
                :type="selectedVenueId === venue.id ? 'primary' : ''"
                @click="selectedVenueId = venue.id"
              >
                {{ venue.venueName }}
              </el-button>
              <div v-if="venues.length === 0" class="no-venue-hint">
                暂无场地信息，请先在赛事管理中配置场地
              </div>
            </div>
          </div>

          <div class="time-selector">
            <el-button
              v-for="(time, index) in timeSlots"
              :key="index"
              size="small"
              :type="selectedTime === index ? 'primary' : ''"
              @click="selectedTime = index"
            >
              {{ time }}
            </el-button>
          </div>

          <!-- 项目卡片列表 -->
          <div v-for="(group, groupIndex) in filteredCompetitionGroups" :key="group.id" class="project-card">
            <!-- 项目头部 - 可点击展开 -->
            <div class="project-header" :class="{ 'project-header-collapsed': !isProjectExpanded(group.id) }" @click="toggleProjectExpand(group.id)">
              <div class="project-info">
                <!-- 展开图标 -->
                <span class="project-expand-icon">
                  <el-icon v-if="isProjectExpanded(group.id)"><ArrowDown /></el-icon>
                  <el-icon v-else><ArrowRight /></el-icon>
                </span>
                <span class="project-index">{{ groupIndex + 1 }}、</span>
                <span class="project-title">{{ group.title }}</span>
                <span class="project-meta">{{ group.type }}</span>
                <span class="project-meta">{{ getTeamCount(group) }}队</span>
                <span class="project-meta">{{ group.items?.length || 0 }}组</span>
                <span class="project-meta">{{ group.code }}</span>
              </div>
              <div class="project-actions" @click.stop>
                <el-popover
                  placement="bottom"
                  :width="200"
                  trigger="click"
                  :disabled="isScheduleCompleted"
                >
                  <template #reference>
                    <el-button size="small" type="warning" :disabled="isScheduleCompleted">
                      移动
                    </el-button>
                  </template>
                  <div class="move-popover">
                    <div class="move-label">移动到</div>
                    <el-select v-model="moveTargetVenueId" placeholder="选择场地" size="small" style="width: 100%; margin-bottom: 10px;">
                      <el-option
                        v-for="venue in venues"
                        :key="venue.id"
                        :label="venue.venueName"
                        :value="venue.id"
                      ></el-option>
                    </el-select>
                    <el-button size="small" type="primary" @click="quickMoveGroup(group)">移动</el-button>
                  </div>
                </el-popover>
              </div>
            </div>

            <!-- 队伍列表 - 可折叠 -->
            <div v-if="isProjectExpanded(group.id)" class="team-list">
              <div
                v-for="(team, teamIndex) in groupItemsByTeam(group.items)"
                :key="team.id"
                class="team-row"
                :class="{ 'team-row-expanded': isTeamExpanded(group.id, team.id) }"
              >
                <!-- 队伍主行 - 可点击展开 -->
                <div class="team-main" @click="toggleTeamExpand(group.id, team.id)">
                  <!-- 展开图标 -->
                  <span class="expand-icon">
                    <el-icon v-if="isTeamExpanded(group.id, team.id)"><ArrowDown /></el-icon>
                    <el-icon v-else><ArrowRight /></el-icon>
                  </span>

                  <!-- 队伍信息 -->
                  <div class="team-info">
                    <span class="team-index">{{ teamIndex + 1 }}、</span>
                    <span class="team-name">{{ team.schoolUnit }}</span>
                  </div>

                  <!-- 选手列表 -->
                  <div class="player-list">
                    <span
                      v-for="(player, playerIndex) in team.players"
                      :key="player.id"
                      class="player-tag"
                      :class="{ 'player-exception': player.status === '异常' }"
                    >
                      {{ player.playerName }}
                    </span>
                  </div>

                  <!-- 操作按钮 -->
                  <div class="team-actions" @click.stop>
                    <el-button
                      link
                      size="small"
                      @click="handleTeamMoveUp(group, teamIndex)"
                      :disabled="teamIndex === 0 || isScheduleCompleted"
                      title="上移"
                      class="move-btn"
                    >
                      <img src="/img/图标 3@3x.png" class="move-icon" alt="上移" />
                    </el-button>
                    <el-button
                      link
                      size="small"
                      @click="handleTeamMoveDown(group, teamIndex)"
                      :disabled="teamIndex === groupItemsByTeam(group.items).length - 1 || isScheduleCompleted"
                      title="下移"
                      class="move-btn"
                    >
                      <img src="/img/图标 4@3x.png" class="move-icon" alt="下移" />
                    </el-button>
                  </div>
                </div>

                <!-- 展开内容 - 选手详情 -->
                <div v-if="isTeamExpanded(group.id, team.id)" class="team-expand-content">
                  <div
                    v-for="(player, playerIndex) in team.players"
                    :key="player.id"
                    class="player-detail-row"
                  >
                    <span class="player-detail-index">{{ playerIndex + 1 }}</span>
                    <span class="player-detail-name">{{ player.playerName }}</span>
                    <span class="player-detail-status">
                      <el-tag
                        :type="player.status === '已签到' ? 'success' : player.status === '异常' ? 'danger' : 'info'"
                        size="small"
                      >
                        {{ player.status || '未签到' }}
                      </el-tag>
                    </span>
                    <span class="player-detail-actions">
                      <el-button
                        v-if="(player.status || '未签到') === '未签到'"
                        link
                        size="small"
                        @click="markPlayerAsException(group, team, playerIndex)"
                        :disabled="isScheduleCompleted"
                        style="color: #f56c6c;"
                      >
                        标记异常
                      </el-button>
                      <el-button
                        v-if="player.status === '异常'"
                        link
                        size="small"
                        @click="removePlayerException(group, team, playerIndex)"
                        :disabled="isScheduleCompleted"
                        style="color: #67c23a;"
                      >
                        取消异常
                      </el-button>
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 场地 Tab -->
        <div v-show="activeTab === 'venue'" class="tab-content">
          <!-- 场地列表 -->
          <div class="venue-list">
            <div class="venue-buttons">
              <el-button
                v-for="venue in venues"
                :key="'venue-tab-' + venue.id"
                size="small"
                :type="selectedVenueIdForVenueTab === venue.id ? 'primary' : ''"
                @click="selectedVenueIdForVenueTab = venue.id"
              >
                {{ venue.venueName }}
              </el-button>
              <div v-if="venues.length === 0" class="no-venue-hint">
                暂无场地信息，请先在赛事管理中配置场地
              </div>
            </div>
          </div>

          <div class="time-selector">
            <el-button
              v-for="(time, index) in timeSlots"
              :key="index"
              size="small"
              :type="selectedTime === index ? 'primary' : ''"
              @click="selectedTime = index"
            >
              {{ time }}
            </el-button>
          </div>

          <el-table :data="venueData" border stripe size="small">
            <el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
            <el-table-column prop="project" label="项目" min-width="180">
              <template #default="scope">
                <span>{{ scope.row.project }}</span>
                <div v-if="scope.row.hint" class="row-hint">{{ scope.row.hint }}</div>
              </template>
            </el-table-column>
            <el-table-column prop="participant" label="参人/单位" width="120"></el-table-column>
            <el-table-column prop="team" label="队伍" width="80" align="center"></el-table-column>
            <el-table-column prop="number" label="编号" width="80" align="center"></el-table-column>
            <el-table-column prop="duration" label="合计时间" width="100" align="center"></el-table-column>
            <el-table-column prop="status" label="状态" width="100" align="center">
              <template #default="scope">
                <span v-if="scope.row.status" class="status-active">{{ scope.row.status }}</span>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>

      <div class="footer-actions">
        <el-button size="small" @click="handleSaveDraft" v-if="!isScheduleCompleted">保存草稿</el-button>
        <el-button size="small" @click="handleExport" v-if="isScheduleCompleted">导出</el-button>
        <el-button size="small" type="primary" @click="handleConfirm" v-if="!isScheduleCompleted">完成编排</el-button>
      </div>

    <!-- 确认对话框 -->
    <el-dialog
      title="确定完成编排"
      v-model="confirmDialogVisible"
      width="450px"
      center
    >
      <p style="text-align: center; padding: 20px; color: #606266;">
        完成编排后，不可再次调整。确定完成编排吗？
      </p>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="confirmDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmComplete">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 移动分组对话框 -->
    <el-dialog
      title="移动竞赛分组"
      v-model="moveDialogVisible"
      width="500px"
      center
    >
      <el-form label-width="100px">
        <el-form-item label="目标场地">
          <el-select v-model="moveTargetVenueId" placeholder="请选择场地" style="width: 100%;">
            <el-option
              v-for="venue in venues"
              :key="venue.id"
              :label="venue.venueName"
              :value="venue.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="目标时间段">
          <el-select v-model="moveTargetTimeSlot" placeholder="请选择时间段" style="width: 100%;">
            <el-option
              v-for="(time, index) in timeSlots"
              :key="index"
              :label="time"
              :value="index"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="moveDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmMoveGroup">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 异常组对话框 -->
    <el-dialog
      title="异常组参赛人员"
      v-model="exceptionDialogVisible"
      width="700px"
      center
    >
      <el-table :data="exceptionList" border stripe size="small" max-height="400">
        <el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
        <el-table-column prop="groupTitle" label="分组" min-width="180"></el-table-column>
        <el-table-column prop="schoolUnit" label="学校/单位" min-width="150"></el-table-column>
        <el-table-column prop="status" label="状态" width="100" align="center">
          <template #default="scope">
            <el-tag type="danger" size="small">{{ scope.row.status }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="100" align="center">
          <template #default="scope">
            <el-button
              link
              size="small"
              @click="removeFromException(scope.$index)"
              style="color: #409eff;"
            >
              移除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <div v-if="exceptionList.length === 0" style="text-align: center; padding: 40px; color: #909399;">
        暂无异常参赛人员
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="exceptionDialogVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import { ArrowDown, ArrowRight } from '@element-plus/icons-vue'
import { getVenuesByCompetition } from '@/api/martial/venue'
import { getCompetitionDetail } from '@/api/martial/competition'
import { getScheduleResult, saveAndLockSchedule, saveDraftSchedule, triggerAutoArrange, moveScheduleGroup, exportSchedule } from '@/api/martial/activitySchedule'
import { updateCheckInStatus, getScheduleConfig } from '@/api/martial/schedulePlan'

export default {
  name: 'MartialScheduleList',
  components: {
    ArrowDown,
    ArrowRight
  },
  data() {
    return {
      competitionId: null,
      orderId: null,
      activeTab: 'competition',
      selectedTime: 0,
      selectedVenueId: null, // 选中的场地ID（竞赛分组Tab）
      selectedVenueIdForVenueTab: null, // 选中的场地ID（场地Tab）
      confirmDialogVisible: false,
      isScheduleCompleted: false, // 是否已完成编排
      loading: false,
      autoArrangeLoading: false, // 自动编排加载状态
      venues: [], // 场地列表(从后端加载)
      competitionInfo: {
        competitionName: '',
        competitionStartTime: '',
        competitionEndTime: ''
      },
      timeSlots: [], // 时间段列表(根据比赛时间动态生成)
      competitionGroups: [], // 竞赛分组(从后端加载)

      // 移动分组相关
      moveDialogVisible: false,
      moveTargetVenueId: null,
      moveTargetTimeSlot: null,
      moveGroupIndex: null,

      // 异常组相关
      exceptionDialogVisible: false,
      exceptionList: [], // 异常参赛人员列表
      expandedTeams: {}, // 展开的队伍 { 'groupId-teamId': true }
      expandedProjects: {}, // 展开的项目 { 'groupId': true }，默认收起
      scheduleConfig: { morningStartTime: '08:00', afternoonStartTime: '14:00' } // 赛程配置
    }
  },
  computed: {
    // 根据选中的场地和时间段过滤竞赛分组
    filteredCompetitionGroups() {
      console.log('=== 过滤调试信息 ===')
      console.log('selectedVenueId:', this.selectedVenueId, 'type:', typeof this.selectedVenueId)
      console.log('selectedTime:', this.selectedTime, 'type:', typeof this.selectedTime)
      console.log('competitionGroups总数:', this.competitionGroups.length)

      if (!this.selectedVenueId || this.selectedTime === null) {
        console.log('场地或时间未选中，返回空数组')
        return []
      }

      const filtered = this.competitionGroups.filter(group => {
        console.log(`分组"${group.title}": venueId=${group.venueId}(${typeof group.venueId}), timeSlotIndex=${group.timeSlotIndex}(${typeof group.timeSlotIndex})`)
        const venueMatch = group.venueId === this.selectedVenueId || Number(group.venueId) === Number(this.selectedVenueId)
        const timeMatch = group.timeSlotIndex === this.selectedTime
        console.log(`  场地匹配:${venueMatch}, 时间匹配:${timeMatch}`)
        return venueMatch && timeMatch
      })

      console.log('过滤后的分组数量:', filtered.length)
      return filtered
    },

    // 场地标签页的数据 - 根据选中的场地和时间段动态生成
    venueData() {
      if (this.selectedTime === null) {
        return []
      }

      // 获取选中时间段的所有分组
      let groupsInTimeSlot = this.competitionGroups.filter(
        group => group.timeSlotIndex === this.selectedTime
      )

      // 如果选中了场地，进一步过滤
      if (this.selectedVenueIdForVenueTab) {
        groupsInTimeSlot = groupsInTimeSlot.filter(group => {
          return group.venueId === this.selectedVenueIdForVenueTab ||
                 Number(group.venueId) === Number(this.selectedVenueIdForVenueTab)
        })
      }

      // 将分组转换为场地视图的数据格式
      return groupsInTimeSlot.map(group => ({
        project: group.title,
        participant: group.type,
        team: 1, // 队伍数量,可以从分组中计算
        number: group.items?.length || 0, // 参赛人数
        duration: 0, // 合计时间,如果后端有数据可以显示
        status: group.venueName, // 显示场地名称
        venueName: group.venueName,
        hint: '' // 可以根据需要添加提示信息
      }))
    }
  },
  mounted() {
    // 从路由获取赛事ID和订单ID
    this.competitionId = this.$route.query.competitionId
    this.orderId = this.$route.query.orderId

    if (this.competitionId) {
      this.loadScheduleConfig()
      this.loadCompetitionInfo()
      this.loadVenues()
      this.loadScheduleData()
    } else {
      this.$message.warning('未获取到赛事ID')
    }
  },
  methods: {
    // 检查项目是否展开
    isProjectExpanded(groupId) {
      return this.expandedProjects[groupId] === true
    },

    // 切换项目展开状态
    toggleProjectExpand(groupId) {
      if (this.expandedProjects[groupId]) {
        delete this.expandedProjects[groupId]
      } else {
        this.expandedProjects[groupId] = true
      }
      // 触发响应式更新
      this.expandedProjects = { ...this.expandedProjects }
    },

    // 检查队伍是否展开
    isTeamExpanded(groupId, teamId) {
      const key = groupId + '-' + teamId
      return this.expandedTeams[key] === true
    },

    // 切换队伍展开状态
    toggleTeamExpand(groupId, teamId) {
      const key = groupId + '-' + teamId
      if (this.expandedTeams[key]) {
        delete this.expandedTeams[key]
      } else {
        this.expandedTeams[key] = true
      }
      // 触发响应式更新
      this.expandedTeams = { ...this.expandedTeams }
    },

    // 标记选手为异常
    markPlayerAsException(group, team, playerIndex) {
      if (this.isScheduleCompleted) {
        this.$message.warning('编排已完成，无法标记异常')
        return
      }

      const player = team.players[playerIndex]
      if (player) {
        player.status = '异常'
        // 添加到异常列表
        this.exceptionList.push({
          groupId: group.id,
          groupTitle: group.title,
          teamId: team.id,
          schoolUnit: team.schoolUnit,
          playerId: player.id,
          playerName: player.playerName,
          status: '异常'
        })

        // 调用后端API保存状态
        updateCheckInStatus(player.id, '异常').then(() => {
          this.$message.success(`已将 ${player.playerName} 标记为异常`)
        }).catch(err => {
          console.error('保存异常状态失败:', err)
        })
      }
    },

    // 取消选手异常状态
    removePlayerException(group, team, playerIndex) {
      if (this.isScheduleCompleted) {
        this.$message.warning('编排已完成，无法取消异常')
        return
      }

      const player = team.players[playerIndex]
      if (player) {
        player.status = '未签到'
        // 从异常列表中移除
        const idx = this.exceptionList.findIndex(
          e => e.playerId === player.id && e.groupId === group.id
        )
        if (idx !== -1) {
          this.exceptionList.splice(idx, 1)
        }

        // 调用后端API恢复状态
        updateCheckInStatus(player.id, '未签到').then(() => {
          this.$message.success(`已将 ${player.playerName} 取消异常标记`)
        }).catch(err => {
          console.error('恢复状态失败:', err)
        })
      }
    },

    // 将选手按学校/单位分组为队伍
    groupItemsByTeam(items) {
      if (!items || items.length === 0) return []
      const teamMap = new Map()
      items.forEach(item => {
        const key = item.schoolUnit
        if (!teamMap.has(key)) {
          teamMap.set(key, {
            id: `team_${item.id}`,
            schoolUnit: key,
            players: [],
            playerIds: []
          })
        }
        teamMap.get(key).players.push(item)
        teamMap.get(key).playerIds.push(item.id)
      })
      return Array.from(teamMap.values())
    },

    // 获取队伍数量
    getTeamCount(group) {
      if (!group.items || group.items.length === 0) return 0
      const teams = this.groupItemsByTeam(group.items)
      return teams.length
    },

    // 快速移动分组（从popover中调用）
    async quickMoveGroup(group) {
      if (!this.moveTargetVenueId) {
        this.$message.warning('请选择目标场地')
        return
      }

      const targetVenue = this.venues.find(v => v.id === this.moveTargetVenueId)

      try {
        // 调用后端API移动分组
        const res = await moveScheduleGroup({
          groupId: group.id,
          targetVenueId: this.moveTargetVenueId,
          targetTimeSlotIndex: this.selectedTime // 保持当前时间段
        })

        if (res.data.success) {
          // 更新前端数据
          group.venueId = this.moveTargetVenueId
          group.venueName = targetVenue ? targetVenue.venueName : ''

          this.$message.success(`已移动到 ${group.venueName}`)
        } else {
          this.$message.error(res.data.msg || '移动分组失败')
        }
      } catch (error) {
        console.error('移动分组失败:', error)
        this.$message.error('移动分组失败，请稍后重试')
      }
    },

    // 获取队伍状态
    getTeamStatus(team) {
      if (!team || !team.players) return '未签到'
      const statuses = team.players.map(p => p.status || '未签到')
      if (statuses.every(s => s === '已签到')) return '已签到'
      if (statuses.every(s => s === '未签到')) return '未签到'
      if (statuses.some(s => s === '异常')) return '部分异常'
      return '部分签到'
    },

    // 获取队伍状态类型
    getTeamStatusType(team) {
      const status = this.getTeamStatus(team)
      switch(status) {
        case '已签到': return 'success'
        case '部分异常': return 'danger'
        case '部分签到': return 'warning'
        default: return 'info'
      }
    },

    // 队伍上移
    handleTeamMoveUp(group, teamIndex) {
      const teams = this.groupItemsByTeam(group.items)
      if (teamIndex === 0 || this.isScheduleCompleted) return

      const currentTeam = teams[teamIndex]
      const prevTeam = teams[teamIndex - 1]

      // 找到两个队伍在原数组中的位置范围
      const currentPlayerIds = currentTeam.playerIds
      const prevPlayerIds = prevTeam.playerIds

      // 重新排序：将当前队伍的所有选手移到前一个队伍之前
      const newItems = []
      let addedCurrent = false

      for (const item of group.items) {
        if (prevPlayerIds.includes(item.id) && !addedCurrent) {
          // 先添加当前队伍的所有选手
          for (const cItem of group.items) {
            if (currentPlayerIds.includes(cItem.id)) {
              newItems.push(cItem)
            }
          }
          addedCurrent = true
        }
        if (!currentPlayerIds.includes(item.id)) {
          newItems.push(item)
        }
      }

      group.items = newItems
      this.$message.success('上移成功')
    },

    // 队伍下移
    handleTeamMoveDown(group, teamIndex) {
      const teams = this.groupItemsByTeam(group.items)
      if (teamIndex === teams.length - 1 || this.isScheduleCompleted) return

      const currentTeam = teams[teamIndex]
      const nextTeam = teams[teamIndex + 1]

      const currentPlayerIds = currentTeam.playerIds
      const nextPlayerIds = nextTeam.playerIds

      // 重新排序：将当前队伍的所有选手移到下一个队伍之后
      const newItems = []
      let addedCurrent = false

      for (const item of group.items) {
        if (!currentPlayerIds.includes(item.id)) {
          newItems.push(item)
        }
        if (nextPlayerIds.includes(item.id)) {
          // 检查是否是下一个队伍的最后一个选手
          const isLastOfNext = item.id === nextPlayerIds[nextPlayerIds.length - 1]
          if (isLastOfNext && !addedCurrent) {
            // 在下一个队伍最后一个选手之后添加当前队伍
            for (const cItem of group.items) {
              if (currentPlayerIds.includes(cItem.id)) {
                newItems.push(cItem)
              }
            }
            addedCurrent = true
          }
        }
      }

      group.items = newItems
      this.$message.success('下移成功')
    },

    goBack() {
      this.$router.go(-1)
    },

    // 加载赛事信息
    async loadCompetitionInfo() {
      try {
        this.loading = true
        const res = await getCompetitionDetail(this.competitionId)
        const data = res.data?.data

        if (data) {
          this.competitionInfo.competitionName = data.competitionName || data.competition_name || ''
          this.competitionInfo.competitionStartTime = data.competitionStartTime || data.competition_start_time
          this.competitionInfo.competitionEndTime = data.competitionEndTime || data.competition_end_time

          // 生成时间段
          this.generateTimeSlots()
        }
      } catch (err) {
        console.error('加载赛事信息失败', err)
        this.$message.error('加载赛事信息失败')
      } finally {
        this.loading = false
      }
    },

    // 根据开始和结束时间生成时间段列表
    // 加载赛程配置
    async loadScheduleConfig() {
      try {
        const res = await getScheduleConfig()
        if (res.data?.data) {
          this.scheduleConfig = res.data.data
          console.log('赛程配置:', this.scheduleConfig)
        }
      } catch (err) {
        console.error('加载赛程配置失败', err)
      }
    },

    // 格式化时间为显示格式 (08:00 -> 8:00)
    formatTimeForDisplay(time) {
      if (!time) return '8:00'
      const parts = time.split(':')
      const hour = parseInt(parts[0], 10)
      const minute = parts[1] || '00'
      return `${hour}:${minute}`
    },

    generateTimeSlots() {
      const startTime = this.competitionInfo.competitionStartTime
      const endTime = this.competitionInfo.competitionEndTime

      // 从配置获取时间，格式化为显示格式
      const morningTime = this.formatTimeForDisplay(this.scheduleConfig.morningStartTime || '08:00')
      const afternoonTime = this.formatTimeForDisplay(this.scheduleConfig.afternoonStartTime || '14:00')

      if (!startTime || !endTime) {
        this.$message.warning('赛事时间信息不完整，使用默认时间段')
        const today = new Date()
        const dateStr = `${today.getFullYear()}年${today.getMonth() + 1}月${today.getDate()}日`
        this.timeSlots = [
          `${dateStr} 上午${morningTime}`,
          `${dateStr} 下午${afternoonTime}`
        ]
        return
      }

      const slots = []
      const start = new Date(startTime)
      const end = new Date(endTime)

      // 遍历每一天
      let currentDate = new Date(start)

      while (currentDate <= end) {
        const year = currentDate.getFullYear()
        const month = currentDate.getMonth() + 1
        const day = currentDate.getDate()
        const dateStr = `${year}年${month}月${day}日`

        // 添加上午时段
        slots.push(`${dateStr} 上午${morningTime}`)

        // 添加下午时段
        slots.push(`${dateStr} 下午${afternoonTime}`)

        // 下一天
        currentDate.setDate(currentDate.getDate() + 1)
      }

      this.timeSlots = slots
      console.log('生成的时间段:', this.timeSlots)
    },

    // 加载场地列表
    async loadVenues() {
      try {
        this.loading = true
        const res = await getVenuesByCompetition(this.competitionId)
        const venuesData = res.data?.data?.records || res.data?.data || []

        if (venuesData.length === 0) {
          this.$message.warning('该赛事暂无场地信息')
          this.venues = []
        } else {
          this.venues = venuesData.map(v => ({
            id: v.id,
            venueName: v.venueName || v.venue_name,
            capacity: v.capacity || 0,
            location: v.location,
            description: v.description
          }))
          // 默认选中第一个场地
          if (this.venues.length > 0) {
            this.selectedVenueId = this.venues[0].id
            this.selectedVenueIdForVenueTab = this.venues[0].id
          }
          console.log('加载的场地数据:', this.venues)
        }
      } catch (err) {
        console.error('加载场地失败', err)
        this.$message.error('加载场地失败')
        this.venues = []
      } finally {
        this.loading = false
      }
    },

    // 加载编排数据
    async loadScheduleData() {
      try {
        this.loading = true
        const res = await getScheduleResult(this.competitionId)
        const data = res.data?.data

        console.log('=== API返回的编排数据 ===')
        console.log('完整响应:', res.data)
        console.log('data:', data)

        if (data) {
          // 判断是否有草稿或已完成的编排
          this.isScheduleCompleted = data.isCompleted || false

          // 加载竞赛分组数据
          if (data.competitionGroups && data.competitionGroups.length > 0) {
            this.competitionGroups = data.competitionGroups.map(group => ({
              id: group.id,
              title: group.title,
              type: group.type,
              count: group.count,
              code: group.code,
              venueId: group.venueId,
              venueName: group.venueName,
              timeSlot: group.timeSlot,
              timeSlotIndex: group.timeSlotIndex,
              items: (group.participants || []).map(p => ({
                id: p.id,
                schoolUnit: p.schoolUnit,
                playerName: p.playerName,
                status: p.status || '未签到',
                sortOrder: p.sortOrder
              }))
            }))

            // 加载异常组数据
            this.exceptionList = []
            this.competitionGroups.forEach(group => {
              group.items.forEach(item => {
                if (item.status === '异常') {
                  this.exceptionList.push({
                    groupId: group.id,
                    groupTitle: group.title,
                    participantId: item.id,
                    schoolUnit: item.schoolUnit,
                    status: item.status
                  })
                }
              })
            })

            console.log('解析后的competitionGroups:', this.competitionGroups)
            console.log('当前selectedVenueId:', this.selectedVenueId)
            console.log('当前selectedTime:', this.selectedTime)
            this.$message.success(data.isDraft ? '已加载草稿数据' : '已加载编排数据')
          } else {
            // 后端还没有数据，使用默认数据进行展示
            this.competitionGroups = []
            console.log('后端暂无编排数据，等待后端生成')
          }
        }
      } catch (err) {
        console.error('加载编排数据失败', err)
        if (err.response?.status === 404) {
          console.log('编排数据不存在，等待后端生成')
        } else {
          this.$message.error('加载编排数据失败: ' + (err.message || ''))
        }
        this.competitionGroups = []
      } finally {
        this.loading = false
      }
    },

    // 移动分组
    handleMoveGroup(group) {
      if (this.isScheduleCompleted) {
        this.$message.warning('编排已完成，无法移动')
        return
      }
      this.moveGroupIndex = this.competitionGroups.findIndex(g => g.id === group.id)
      this.moveTargetVenueId = group.venueId || null
      this.moveTargetTimeSlot = group.timeSlotIndex || 0
      this.moveDialogVisible = true
    },

    // 确认移动分组
    async confirmMoveGroup() {
      if (!this.moveTargetVenueId) {
        this.$message.warning('请选择目标场地')
        return
      }
      if (this.moveTargetTimeSlot === null) {
        this.$message.warning('请选择目标时间段')
        return
      }

      const group = this.competitionGroups[this.moveGroupIndex]
      const targetVenue = this.venues.find(v => v.id === this.moveTargetVenueId)

      try {
        // 调用后端API移动分组
        const res = await moveScheduleGroup({
          groupId: group.id,
          targetVenueId: this.moveTargetVenueId,
          targetTimeSlotIndex: this.moveTargetTimeSlot
        })

        if (res.data.success) {
          // 更新前端数据
          group.venueId = this.moveTargetVenueId
          group.venueName = targetVenue ? targetVenue.venueName : ''
          group.timeSlotIndex = this.moveTargetTimeSlot
          group.timeSlot = this.timeSlots[this.moveTargetTimeSlot]

          this.$message.success(`已移动到 ${group.venueName} - ${group.timeSlot}`)
          this.moveDialogVisible = false
        } else {
          this.$message.error(res.data.msg || '移动分组失败')
        }
      } catch (error) {
        console.error('移动分组失败:', error)
        this.$message.error('移动分组失败，请稍后重试')
      }
    },

    // 标记为异常
    markAsException(group, itemIndex) {
      if (this.isScheduleCompleted) {
        this.$message.warning('编排已完成，无法标记异常')
        return
      }

      const item = group.items[itemIndex]

      // 修改状态为异常
      item.status = '异常'

      // 添加到异常组列表
      this.exceptionList.push({
        groupId: group.id,
        groupTitle: group.title,
        participantId: item.id,
        schoolUnit: item.schoolUnit,
        status: '异常'
      })

      // 调用后端API保存状态
      updateCheckInStatus(item.id, '异常').then(() => {
        this.$message.success(`已将 ${item.schoolUnit} 标记为异常`)
      }).catch(err => {
        console.error('保存异常状态失败:', err)
      })
    },

    // 显示异常组对话框
    showExceptionDialog() {
      this.exceptionDialogVisible = true
    },

    // 从异常组移除
    removeFromException(index) {
      const exceptionItem = this.exceptionList[index]

      // 在竞赛分组中找到对应的参赛人员并恢复状态
      for (let group of this.competitionGroups) {
        if (group.id === exceptionItem.groupId) {
          for (let item of group.items) {
            if (item.id === exceptionItem.participantId) {
              item.status = '未签到'
              break
            }
          }
          break
        }
      }

      // 从异常列表中移除
      this.exceptionList.splice(index, 1)
      // 调用后端API恢复状态
      updateCheckInStatus(exceptionItem.participantId, '未签到').then(() => {
        this.$message.success(`已将 ${exceptionItem.schoolUnit} 从异常组移除`)
      }).catch(err => {
        console.error('恢复状态失败:', err)
      })
    },

    // 触发自动编排
    async handleAutoArrange() {
      try {
        // 确认操作
        await this.$confirm('自动编排将重新生成赛程安排，当前编排数据将被覆盖。确定继续吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })

        this.autoArrangeLoading = true

        // 调用自动编排接口
        const res = await triggerAutoArrange(this.competitionId)

        if (res.data?.success) {
          this.$message.success('自动编排完成')

          // 重新加载编排数据
          await this.loadScheduleData()
        } else {
          this.$message.error(res.data?.msg || '自动编排失败')
        }
      } catch (err) {
        if (err !== 'cancel') {
          console.error('自动编排失败', err)
          this.$message.error('自动编排失败: ' + (err.message || ''))
        }
      } finally {
        this.autoArrangeLoading = false
      }
    },

    // 保存草稿
    async handleSaveDraft() {
      try {
        this.loading = true

        // 构建保存数据
        const saveData = {
          competitionId: this.competitionId,
          isDraft: true,
          competitionGroups: this.competitionGroups.map(group => ({
            id: group.id,
            title: group.title,
            type: group.type,
            count: group.count,
            code: group.code,
            venueId: group.venueId,
            venueName: group.venueName,
            timeSlot: group.timeSlot,
            timeSlotIndex: group.timeSlotIndex,
            participants: group.items.map((item, index) => ({
              id: item.id,
              schoolUnit: item.schoolUnit,
              status: item.status,
              sortOrder: index + 1
            }))
          }))
        }

        // 调用保存草稿接口
        await saveDraftSchedule(saveData)
        console.log('保存草稿数据:', saveData)
        this.$message.success('草稿保存成功')
      } catch (err) {
        console.error('保存草稿失败', err)
        this.$message.error('保存草稿失败: ' + (err.message || ''))
      } finally {
        this.loading = false
      }
    },

    handleVenueCommand(command, groupIndex) {
      // 这个方法已废弃，保留以防万一
    },
    handleMoveUp(group, itemIndex) {
      if (itemIndex === 0 || this.isScheduleCompleted) return
      const temp = group.items[itemIndex]
      group.items.splice(itemIndex, 1)
      group.items.splice(itemIndex - 1, 0, temp)
      this.$message.success('上移成功')
    },
    handleMoveDown(group, itemIndex) {
      if (itemIndex === group.items.length - 1 || this.isScheduleCompleted) return
      const temp = group.items[itemIndex]
      group.items.splice(itemIndex, 1)
      group.items.splice(itemIndex + 1, 0, temp)
      this.$message.success('下移成功')
    },
    async handleExport() {
      try {
        this.loading = true
        const res = await exportSchedule(this.competitionId)
        // axios 返回的是 response 对象，需要取 res.data
        const blob = new Blob([res.data], { type: 'application/vnd.ms-excel' })
        const link = document.createElement('a')
        link.href = window.URL.createObjectURL(blob)
        link.download = `赛程表_${this.competitionInfo.competitionName || this.competitionId}.xlsx`
        link.click()
        window.URL.revokeObjectURL(link.href)
        this.$message.success('导出成功')
      } catch (error) {
        console.error('导出失败:', error)
        this.$message.error('导出失败，请稍后重试')
      } finally {
        this.loading = false
      }
    },
    handleConfirm() {
      this.confirmDialogVisible = true
    },
    async confirmComplete() {
      try {
        this.loading = true

        // 检查是否有编排数据
        if (!this.competitionGroups || this.competitionGroups.length === 0) {
          this.$message.warning('请先进行自动编排，生成编排数据后再完成编排')
          this.confirmDialogVisible = false
          return
        }

        console.log('开始完成编排，竞赛ID:', this.competitionId)
        console.log('编排分组数量:', this.competitionGroups.length)

        // 1. 先保存当前的草稿数据
        const saveData = {
          competitionId: this.competitionId,
          isDraft: true,
          competitionGroups: this.competitionGroups.map(group => ({
            id: group.id,
            title: group.title,
            type: group.type,
            count: group.count,
            code: group.code,
            venueId: group.venueId,
            venueName: group.venueName,
            timeSlot: group.timeSlot,
            timeSlotIndex: group.timeSlotIndex,
            participants: group.items.map((item, index) => ({
              id: item.id,
              schoolUnit: item.schoolUnit,
              status: item.status,
              sortOrder: index + 1
            }))
          }))
        }

        console.log('准备保存草稿数据:', saveData)

        const draftRes = await saveDraftSchedule(saveData)
        console.log('保存草稿成功，返回:', draftRes)

        // 2. 然后调用锁定接口
        console.log('准备锁定编排，竞赛ID:', this.competitionId)
        const lockRes = await saveAndLockSchedule(this.competitionId)
        console.log('锁定接口返回:', lockRes)

        // 3. 更新UI状态
        this.isScheduleCompleted = true
        this.confirmDialogVisible = false
        this.$message.success('编排已完成并锁定')

        // 4. 重新加载编排数据以获取最新状态
        await this.loadScheduleData()
      } catch (err) {
        console.error('完成编排失败', err)
        console.error('错误详情:', err.response?.data || err.message)
        this.$message.error('完成编排失败: ' + (err.response?.data?.msg || err.message || '未知错误'))
      } finally {
        this.loading = false
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.martial-schedule-container {
  padding: 15px;
  background: #fff;

  .page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 15px;
    gap: 10px;

    .header-left {
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .header-right {
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .page-title {
      margin: 0;
      font-size: 18px;
      font-weight: 600;
    }
  }

  .tabs-section {
    margin-bottom: 15px;

    .tab-buttons {
      margin-bottom: 15px;
      padding: 12px;
      background: #fff;
      border: 1px solid #dcdfe6;
    }

    .tab-content {
      padding: 15px;
      background: #fff;
      border: 1px solid #dcdfe6;

      .time-selector {
        margin-bottom: 15px;
        // padding: 8px;
        // background: #f5f7fa;
      }

      // 场地列表样式
      .venue-list {
        margin-bottom: 10px;
        background: #ffffff;
        border: 1px solid #ffffff;
        border-radius: 4px;

        .venue-list-title {
          font-size: 14px;
          font-weight: 600;
          color: #ffffff;
          margin-bottom: 10px;
        }

        .venue-buttons {
          display: flex;
          gap: 10px;
          flex-wrap: wrap;

          .no-venue-hint {
            padding: 8px 12px;
            color: #f59e0b;
            font-size: 13px;
            background: #fef3c7;
            border-radius: 4px;
          }
        }
      }

      .competition-group {
        margin-bottom: 15px;

        .group-header {
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding: 12px;
          background: #f5f7fa;
          border: 1px solid #dcdfe6;
          border-bottom: none;

          .group-info {
            display: flex;
            align-items: center;
            gap: 12px;

            .group-title {
              font-weight: 600;
              color: #303133;
              font-size: 13px;
            }

            .group-meta {
              color: #909399;
              font-size: 12px;
            }
          }

          .group-hints {
            flex: 1;
            text-align: center;

            .hint-text {
              color: #f50057;
              font-size: 11px;

              &.secondary {
                color: #ff4081;
              }
            }
          }

          .group-actions {
            display: flex;
            gap: 8px;
          }
        }
      }

      // 新的项目卡片样式
      .project-card {
        margin-bottom: 20px;
        border: 1px solid #e4e7ed;
        border-radius: 4px;
        overflow: hidden;

        .project-header {
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding: 12px 16px;
          background: #fafafa;
          border-bottom: 1px solid #e4e7ed;
          cursor: pointer;
          transition: background-color 0.2s;

          &:hover {
            background: #f0f0f0;
          }

          &.project-header-collapsed {
            border-bottom: none;
          }

          .project-info {
            display: flex;
            align-items: center;
            gap: 12px;

            .project-expand-icon {
              width: 20px;
              color: #909399;
              display: flex;
              align-items: center;
              justify-content: center;
            }

            .project-index {
              font-weight: 600;
              color: #e6a23c;
              font-size: 14px;
            }

            .project-title {
              font-weight: 600;
              color: #e6a23c;
              font-size: 14px;
            }

            .project-meta {
              color: #606266;
              font-size: 13px;
            }
          }

          .project-actions {
            display: flex;
            gap: 8px;
          }
        }

        .team-list {
          .team-row {
            border-bottom: 1px solid #ebeef5;
            background: #fff;

            &:last-child {
              border-bottom: none;
            }

            &.team-row-expanded {
              background: #fafafa;
            }

            .team-main {
              display: flex;
              align-items: center;
              padding: 12px 16px;
              cursor: pointer;

              &:hover {
                background: #f5f7fa;
              }

              .expand-icon {
                width: 20px;
                color: #909399;
                display: flex;
                align-items: center;
                justify-content: center;
              }

              .team-info {
                display: flex;
                align-items: center;
                min-width: 180px;

                .team-index {
                  color: #909399;
                  font-size: 13px;
                  margin-right: 4px;
                }

                .team-name {
                  color: #303133;
                  font-size: 13px;
                  font-weight: 500;
                }
              }

              .player-list {
                flex: 1;
                display: flex;
                flex-wrap: wrap;
                gap: 8px;
                padding: 0 20px;

                .player-tag {
                  color: #606266;
                  font-size: 13px;
                  padding: 2px 8px;
                  background: #f4f4f5;
                  border-radius: 4px;

                  &.player-exception {
                    color: #f56c6c;
                    background: #fef0f0;
                  }
                }
              }

              .team-actions {
                display: flex;
                gap: 4px;
                min-width: 80px;
                justify-content: flex-end;
              }
            }

            .team-expand-content {
              background: #fafafa;
              border-top: 1px dashed #e4e7ed;
              padding: 8px 16px 8px 56px;

              .player-detail-row {
                display: flex;
                align-items: center;
                padding: 8px 12px;
                border-bottom: 1px solid #ebeef5;

                &:last-child {
                  border-bottom: none;
                }

                .player-detail-index {
                  width: 30px;
                  color: #909399;
                  font-size: 12px;
                }

                .player-detail-name {
                  flex: 1;
                  color: #303133;
                  font-size: 13px;
                }

                .player-detail-status {
                  width: 80px;
                  text-align: center;
                }

                .player-detail-actions {
                  width: 100px;
                  text-align: right;
                }
              }
            }
          }
        }
      }

      .move-popover {
        .move-label {
          font-size: 13px;
          color: #606266;
          margin-bottom: 8px;
        }
      }

      .group-footer-hints {
        margin-top: 15px;
        padding: 8px 12px;
        background: #fff3e0;
        border-left: 3px solid #ff9800;

        .footer-hint-text {
          margin: 4px 0;
          color: #f50057;
          font-size: 11px;

          &.secondary {
            color: #ff4081;
          }
        }
      }

      .row-hint {
        margin-top: 4px;
        padding: 2px 5px;
        color: #f50057;
        font-size: 11px;
        background: rgba(245, 0, 87, 0.05);
        display: inline-block;
      }

      .venue-footer-hints {
        margin-top: 15px;
        padding: 8px 12px;
        background: #fff3e0;
        border-left: 3px solid #ff9800;

        .footer-hint-text {
          margin: 4px 0;
          color: #f50057;
          font-size: 11px;
        }
      }

      .status-active {
        color: #409eff;
        font-weight: 600;
      }
    }
  }

  .footer-actions {
    text-align: center;
    padding: 15px;
    background: #fff;
    border: 1px solid #dcdfe6;
  }

  .move-btn {
    padding: 4px;

    &:disabled {
      opacity: 0.4;
      cursor: not-allowed;
    }
  }

  .move-icon {
    width: 20px;
    height: 20px;
    display: inline-block;
    vertical-align: middle;
  }
}

  // 展开行样式
  .player-expand-list {
    padding: 10px 20px 10px 60px;
    background: #fafafa;

    .player-row {
      display: flex;
      align-items: center;
      gap: 15px;
      padding: 8px 0;
      border-bottom: 1px dashed #eee;

      &:last-child {
        border-bottom: none;
      }

      .player-name {
        min-width: 80px;
        color: #606266;
        font-weight: 500;
      }
    }
  }
</style>
