<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { Icon } from '@iconify/vue'
import { useStorage } from '@vueuse/core'
import { NButton, NCard, NImage, NInputNumber, NTag, useMessage } from 'naive-ui'
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { QuestionCategoryEnum } from '@/enum/business'
import { fetchGetQuestionList } from '@/service/api/competition'
import { fetchGetCurrentQuestionByRoomID, fetchGetGameStatistics, fetchGetGroupListByActivityID, fetchGetQuestionDetailByID } from '@/service/api/game'
import { updateCurrentQuestionUse, updateScore } from '@/service/api/result'
import GroupTabs, { type GroupItem } from './modules/GroupTabs.vue'
import Typewriter from './modules/Typewriter.vue'

// 本地存储手动修改的状态 (key: roomId-questionId-teamId-guid, value: status)
const manualStatusStorage = useStorage<Record<string, number>>('read-star-manual-status', {})
// 本地存储手动修改的分数 (key: roomId-questionId-teamId-guid, value: score)
const manualScoreStorage = useStorage<Record<string, number>>('read-star-manual-score', {})

const route = useRoute()
const message = useMessage()
const activityId = computed(() => route.query?.activityId as string)
const roomId = computed(() => route.query?.roomId as string)

const currentGroupId = ref<number | string>('') // 当前选中的组别 ID
const currentQuestionId = ref<number | string>('') // 当前选中的题目大纲 ID
const currentQuestionType = ref<string>('') // 当前选中的题目类型

const groups = ref<GroupItem[]>([])
const questionList = ref<(GroupItem & { type: string })[]>([])
const currentQuestion = ref<Api.Competition.GetCurrentQuestionInfo>() // 当前正在参赛的题目
const questionInfo = ref<Api.Competition.QuestionListDetailRound>() // 题目详情
const currentQuestionDetailID = ref<number | string>('') // 当前选中的题目详情 ID

// 判断当前activityId是正在比赛的活动
const isActiveActivityId = computed(() => {
  if (!currentQuestion.value)
    return false
  const qActivityId = (currentQuestion.value as any).MainID || (currentQuestion.value as any).ActivityID
  return Number(activityId.value) === Number(qActivityId)
})

// 计算当前题目类型对应的布局
const currentLayout = computed(() => {
  // 只有 汉字加一加 (CharacterRadicalAddition) 需要人工评分 (列表布局 - 分屏视图)
  // 其他所有题型 (汉字听写、诗词、词语听写、成语) 都使用长框展示 (网格布局 - 带切换的大图)
  // 修正需求：scoringTypes 包含 CharacterRadicalAddition, IdiomWriting1, ChineseCharacterDictation2
  // 这些题型使用 'list' 布局，其他使用 'grid'
  // 补充：当 scoringTypes 为 grid 时候，只有对错和正确，提交给接口分数规则是：如果评委觉得是正确的，就取 currentQuestion 里面的 Point 字段，反之错的就是 0
  const scoringTypes = [
    QuestionCategoryEnum.CharacterRadicalAddition,
    QuestionCategoryEnum.IdiomWriting1,
    QuestionCategoryEnum.ChineseCharacterDictation2,
  ]
  if (scoringTypes.includes(currentQuestionType.value as any)) {
    return 'list'
  }
  // 其他题型 (汉字听写、诗词、词语听写、成语看图等) 使用 'grid' 布局 (网格布局 - 带切换的大图)
  return 'grid'
})

interface TeamResult {
  TeamName: string
  UserAnswerPicture: string
  Answers: any[]
  Points: number
  TeamId: number
}

// 当前所有队伍的解析结果列表
const teamResults = ref<TeamResult[]>([])

// 手动设置状态（确认或修改）
async function setStatus(team: TeamResult, item: any, status: number) {
  item.Status = status
  item._isManual = true

  // 保存到本地存储
  if (item.Guid && team.TeamId) {
    const key = `${roomId.value}-${currentQuestionId.value}-${team.TeamId}-${item.Guid}`
    manualStatusStorage.value[key] = status
  }
}

/** 根据 QuestionDetailID 查询题目详情 */
async function fetchQuestionDetail(QuestionDetailID: number) {
  try {
    const { data } = await fetchGetQuestionDetailByID(QuestionDetailID)
    if (data?.data) {
      questionInfo.value = data.data
      console.log(questionInfo.value, 'questionInfo')
    }
  }
  catch (error: any) {
    message.error(error.message || '查询题目详情失败')
  }
}

async function handleManualScoreUpdate(item: any, newScore: number) {
  item.Score = newScore
  item._isManual = true

  // 保存分数到本地存储
  if (roomId.value && currentQuestionId.value && item.Guid && item.TeamId) {
    const key = `${roomId.value}-${currentQuestionId.value}-${item.TeamId}-${item.Guid}`
    manualScoreStorage.value[key] = newScore
  }

  try {
    await updateScore([{
      Id: item.TeamQuestionUseID,
      ResultPotins: newScore,
      QuestionDetailID: item.QuestionDetailID || 0,
      QuestionId: item.QuestionId || 0,
    }])
    message.success('分数已更新')
  }
  catch (e: any) {
    message.error(e.message || '保存分数失败')
  }
}

function handleNext() {
  // “下一步”按钮的逻辑
  // 简单示例：切换到下一题
  const currentIndex = questionList.value.findIndex(q => q.id === currentQuestionId.value)
  if (currentIndex !== -1 && currentIndex < questionList.value.length - 1) {
    currentQuestionId.value = questionList.value[currentIndex + 1].id
  }
  else {
    message.info('已经是最后一题了')
  }
}

/**
 * 根据房间当前题目，自动同步选中题目和当前正在比赛的组
 */
function syncCurrentQuestionSelection() {
  // 1. 如果不是当前正在进行的活动，默认选中第一组第一题
  if (!isActiveActivityId.value) {
    console.log('当前活动不是正在进行的活动，默认选中第一组第一题')
    if (groups.value.length > 0) {
      currentGroupId.value = groups.value[0].id
    }
    if (questionList.value.length > 0) {
      currentQuestionId.value = questionList.value[0].id
      currentQuestionType.value = questionList.value[0].type
    }
    return
  }

  // 2. 如果是当前正在进行的活动，同步选中当前正在进行的题目和组
  const currentQ = currentQuestion.value
  const qid = currentQ?.QuestionID
  const gid = currentQ?.TeamGroupID

  // 尝试匹配题目
  if (qid) {
    const hit = questionList.value.find(q => Number(q.id) === Number(qid))
    if (hit) {
      currentQuestionId.value = hit.id
      currentQuestionType.value = (hit as any).type || ''
    }
  }
  // 尝试匹配组
  if (gid) {
    currentGroupId.value = gid
  }

  // 兜底：如果同步失败（例如当前题目不在列表中），默认选中第一个
  if (!currentQuestionId.value && questionList.value.length > 0) {
    currentQuestionId.value = questionList.value[0].id
    currentQuestionType.value = questionList.value[0].type
  }
  if (!currentGroupId.value && groups.value.length > 0) {
    currentGroupId.value = groups.value[0].id
  }
}

/**
 * 获取分组列表
 */
async function fetchGroups() {
  if (!activityId.value) {
    window.$message?.error('请先选择比赛')
    return
  }
  try {
    const { data, error } = await fetchGetGroupListByActivityID(activityId.value, 3)
    if (error) {
      window.$message?.error('获取题目失败')
      return
    }
    const list = data?.data || []
    groups.value = list.map((item: any) => ({
      id: item.Id,
      name: item.Id,
    }))
    // 默认选中第一个分组
    if (groups.value.length > 0 && !currentGroupId.value) {
      currentGroupId.value = groups.value[0].id
    }
  }
  catch (error: any) {
    window.$message?.error(error.message || '获取分组失败')
  }
}

/**
 * 获取题目列表
 */
async function fetchQuestions() {
  if (!activityId.value)
    return
  try {
    const { data, error } = await fetchGetQuestionList(Number(activityId.value), 3)
    if (error) {
      message.error(error.message)
      return
    }
    const list = data?.data || []
    console.warn('question list', list)

    questionList.value = list.map((item, idx) => ({
      id: item.ID,
      name: item.ID || `题目 ${idx + 1}`,
      type: item.UIType || '',
    }))
    // 默认选中第一个题目
    if (questionList.value.length > 0 && !currentQuestionId.value) {
      currentQuestionId.value = questionList.value[0].id
      currentQuestionType.value = questionList.value[0].type
      console.warn(questionList.value, 'questionList')
    }
    // 题目加载完成后尝试同步到“当前进行中的题目”
    syncCurrentQuestionSelection()
  }
  catch (error: any) {
    message.error(error.message || '获取题目失败')
  }
}

/**
 * 获取当前正在比赛的题目（不触发同步选中逻辑）
 */
async function fetchCurrentQuestion(shouldSync = true) {
  if (!roomId.value)
    return
  try {
    const { data, error } = await fetchGetCurrentQuestionByRoomID(Number(roomId.value))
    if (error) {
      message.error(error.message)
      return
    }
    currentQuestion.value = data?.data || {}
    console.warn('current question', currentQuestion.value)
    // 只在初始化时同步选中题，轮询时不同步
    if (shouldSync) {
      syncCurrentQuestionSelection()
    }
  }
  catch (error: any) {
    message.error(error.message || '获取当前题目失败')
  }
}

/**
 * 获取答题卡数据
 */
async function fetchAnswerData() {
  if (!currentGroupId.value || !currentQuestionId.value)
    return
  try {
    const params = {
      TeamGroupID: Number(currentGroupId.value),
      QuestionID: Number(currentQuestionId.value),
    }

    const { data, error } = await fetchGetGameStatistics(params)
    if (error) {
      message.error(error.message)
      return
    }

    // 假设返回的数据结构是数组，取第一条或者根据逻辑取特定的一条
    const result = data?.data || []
    // console.log('接口返回的游戏统计数据：', result)

    // 获取题目详情 ID
    let detailId = 0
    // 1. 尝试从答题卡数据中获取当前比赛的题目详情 ID (优先)
    if (result.length > 0) {
      const item = result[0]
      if (item) {
        detailId = item?.QuestionDetaiID || 0
      }
    }
    // 如果获取到了新的 detailId，更新 currentQuestionDetailID (会触发 watch 调用 fetchQuestionDetail)
    if (detailId && detailId !== Number(currentQuestionDetailID.value)) {
      currentQuestionDetailID.value = detailId
    }

    result.forEach((item) => {
      const UserAnswerFont = JSON.parse(item.UserAnswerFont)
      console.log('解析后的 UserAnswerFont:', UserAnswerFont)
    })

    if (result && result.length > 0) {
      // 创建现有项目的映射以保留手动编辑
      const oldMap = new Map<string, any>()
      if (teamResults.value && teamResults.value.length > 0) {
        teamResults.value.forEach((t) => {
          if (t.Answers) {
            t.Answers.forEach((a: any) => {
              if (a.Guid) {
                // 使用 TeamId + Guid 作为 key，确保唯一性
                oldMap.set(`${t.TeamId}-${a.Guid}`, a)
              }
            })
          }
        })
      }

      teamResults.value = result.map((answerData) => {
        let parsedAnswers: any[] = []
        try {
          if (answerData.UserAnswerFont) {
            const parsedFonts = JSON.parse(answerData.UserAnswerFont)
            parsedAnswers = Array.isArray(parsedFonts) ? parsedFonts : []
            // console.warn('parsed fonts', parsedFonts)
          }
        }
        catch (e) {
          console.error('解析 UserAnswerFont 失败', e)
        }
        // 如果 UserAnswerFont 为空，尝试使用根对象的数据构建答案（适用于选择题等没有切图的题型）
        if (parsedAnswers.length === 0 && (answerData.UserAnswerPicture || answerData.AnswerValuePicture)) {
          parsedAnswers = [{
            Guid: answerData.Guid || `${answerData.QuestionId}-${answerData.TeamId}`,
            TeamQuestionUseID: answerData.Id, // 确保有 TeamQuestionUseID 用于后续更新分数
            AnswerText: '查看原图', // 默认提示文案
            AnswerValuePicture: answerData.AnswerValuePicture || answerData.UserAnswerPicture,
            Status: answerData.Status,
            Score: answerData.Points, // 使用根节点的 Points
          }]
        }

        // 将新答案与旧的手动编辑合并
        const mergedAnswers = parsedAnswers.map((ans: any) => {
          // 使用 TeamId + Guid 获取旧状态，确保不同队伍之间不冲突
          const oldAns = oldMap.get(`${answerData.TeamId}-${ans.Guid}`)

          // 检查本地存储是否有手动修改记录
          const storageKey = `${roomId.value}-${currentQuestionId.value}-${answerData.TeamId}-${ans.Guid}`
          const storedStatus = manualStatusStorage.value[storageKey]
          const storedScore = manualScoreStorage.value[storageKey]
          const hasStoredStatus = storedStatus !== undefined
          const hasStoredScore = storedScore !== undefined

          // 记录 AI 的原始推荐值（如果后端返回了）
          const aiStatus = ans.Status
          // _aiScore 专门用于存储 AI 的推荐分数（优先取外层 Points，如果没有则尝试内层）
          const aiScore = answerData.Points ?? ans.Score ?? ans.Point

          // 强制更新图片 URL，防止缓存
          // 优先使用 ans 中的图片，如果没有则回退到 answerData 中的图片
          const imageUrl = ans.AnswerValuePicture || (parsedAnswers.length === 1 && parsedAnswers[0] === ans ? answerData.UserAnswerPicture : '')
          let finalImageUrl = imageUrl
          const cleanBaseUrl = ''
          const timestamp = new Date().getTime()

          finalImageUrl = `${finalImageUrl}?_t=${timestamp}`
          console.log(finalImageUrl, 'finalImageUrl')

          // 判断是否手动干预：
          // 1. 本地存储有状态 (hasStoredStatus) 或有分数 (hasStoredScore)
          // 2. 内存中有手动标记 (oldAns._isManual)
          const isManual = hasStoredStatus || hasStoredScore || (oldAns && oldAns._isManual)

          if (isManual) {
            // 优先使用本地存储的状态，其次是内存中的手动编辑状态
            const finalStatus = hasStoredStatus ? storedStatus : (oldAns ? oldAns.Status : ans.Status)

            // 分数逻辑：
            // 1. 优先使用本地存储的分数 (hasStoredScore)
            // 2. 其次使用内存中的手动分数 (oldAns.Score)
            // 3. 如果都没有 (可能是只改了状态没改分数)，则默认 null
            let finalScore: number | null = null
            if (hasStoredScore) {
              finalScore = storedScore
            }
            else if (oldAns && oldAns.Score !== undefined && oldAns.Score !== null) {
              finalScore = oldAns.Score
            }

            // 修正：在返回的对象中注入 TeamId，以便 handleManualScoreUpdate 使用
            const resultItem = {
              ...ans,
              TeamId: answerData.TeamId, // [新增] 注入 TeamId
              QuestionId: answerData.QuestionId, // [新增]
              QuestionDetailID: answerData.QuestionDetaiID, // [新增] 注意后端字段拼写
              AnswerText: ans.AnswerText,
              AnswerValuePicture: finalImageUrl,
              _baseImgUrl: cleanBaseUrl,
              _t: timestamp, // 保存时间戳
              Score: finalScore,
              Status: finalStatus,
              _isManual: true,
              _aiStatus: aiStatus,
              _aiScore: aiScore,
            }
            return resultItem
          }

          // 如果没有手动编辑
          return {
            ...ans,
            TeamId: answerData.TeamId, // [新增] 注入 TeamId
            QuestionId: answerData.QuestionId, // [新增]
            QuestionDetailID: answerData.QuestionDetaiID, // [新增] 注意后端字段拼写
            AnswerText: ans.AnswerText,
            AnswerValuePicture: finalImageUrl,
            _baseImgUrl: cleanBaseUrl,
            _t: timestamp, // 保存时间戳
            Status: ans.Status,
            _aiStatus: aiStatus,
            _aiScore: aiScore,
            Score: null, // 默认 null
            _isManual: false,
          }
        })

        return {
          TeamId: answerData.TeamId,
          TeamName: answerData.TeamName,
          UserAnswerPicture: answerData.UserAnswerPicture,
          Points: answerData.Points,
          Answers: mergedAnswers,
        }
      })
    }
    else {
      teamResults.value = []
      message.info('暂无答题数据')
    }
  }
  catch (error: any) {
    message.error(error.message || '获取答题数据失败')
  }
}

/**
 * 调转到当前题目
 */
async function handleNexCurrentQuestion() {
  await fetchCurrentQuestion()

  // 校验 ActivityID 是否一致
  if (!isActiveActivityId.value) {
    window.$message?.warning('当前房间正在进行的不是本场活动，无法跳转到当前题目')
    return
  }

  if (currentQuestionId.value && currentGroupId.value) {
    currentQuestionId.value = currentQuestion.value?.QuestionID || currentQuestionId.value
    currentGroupId.value = currentQuestion.value?.TeamGroupID || currentGroupId.value
  }
}

function handlePublish() {
  const endTimeStr = (currentQuestion.value as any)?.EndTime
  if (endTimeStr && Date.now() < new Date(endTimeStr).getTime() + 5000) {
    window.$message?.warning('倒计时未结束（需等待5秒延迟），暂不能发布')
    return
  }
  if (currentQuestion.value?.TeamGroupQuestionID) {
    // 检查是否有未评分的题目
    let hasUnrated = false
    teamResults.value.forEach((team) => {
      if (team.Answers) {
        team.Answers.forEach((item: any) => {
          if (!item._isManual) {
            hasUnrated = true
          }
        })
      }
    })

    if (hasUnrated) {
      window.$message?.error('还有未人工校准的题目，请完成后再发布！')
      return
    }

    window.$dialog?.warning({
      title: '二次确认',
      content: '请仔细检查所有人工打分和AI推荐结果是否已核对无误。提交后结果将不可更改，确定要发布吗？',
      positiveText: '确认发布',
      negativeText: '再次检查',
      onPositiveClick: async () => {
        // 在发布前，将所有手动修改的分数/状态提交一次
        // 注意：现在 updateScore 接口支持批量提交，我们需要收集所有需要提交的数据
        const scoreList: { Id: number, ResultPotins: number, QuestionDetailID: number, QuestionId: number }[] = []
        let isValid = true

        teamResults.value.forEach((team) => {
          if (!isValid)
            return

          if (team.Answers) {
            team.Answers.forEach((item: any) => {
              // 无论是手动还是 AI 推荐，最终都需要提交分数
              // 如果是 grid 布局（客观题），Status=1 -> 1分，Status=0 -> 0分
              // 如果是 list 布局（主观题），直接用 Score 分数
              // 必须有 TeamQuestionUseID (Id) 才能提交
              if (item.TeamQuestionUseID) {
                let scoreToSubmit = item.Score

                // 校验：对于 list 布局（主观题），分数不能为 null
                if (currentLayout.value === 'list' && (scoreToSubmit === null || scoreToSubmit === undefined)) {
                  window.$message?.error(`队伍 "${team.TeamName}" 存在未打分的题目，请检查`)
                  isValid = false
                  return
                }

                if (currentLayout.value === 'grid') {
                  // Grid 布局（客观题）：只有对错
                  // 规则：如果评委认为是正确 (Status=1)，则使用当前题目的总分 (currentQuestion.Point)
                  // 否则（错误），分数为 0
                  // 注意：currentQuestion 可能没有 Point 字段，需要确认类型，如果没有则尝试从 item._aiScore 获取或者默认 1？
                  // 根据需求："就取currentQuestion里面的Point字段"
                  // 查看 typings，currentQuestion 是 GetCurrentQuestionInfo 类型，可能没有 Point。
                  // 假设 GetCurrentQuestionInfo 有 Point 字段 (或者 Points / Score)
                  // 如果 currentQuestion 没有，回退到 item._aiScore (AI 认为正确的那个分数) 还是默认 1？
                  // 通常客观题分数是固定的。这里假设 currentQuestion 有 Point。
                  // 修正：currentQuestion.value 可能是 undefined。
                  const maxPoint = (currentQuestion.value as any)?.Point || (currentQuestion.value as any)?.Score || 1
                  scoreToSubmit = item.Status === 1 ? maxPoint : 0
                }

                // 确保分数为数字
                scoreList.push({
                  Id: item.TeamQuestionUseID,
                  ResultPotins: Number(scoreToSubmit || 0),
                  QuestionDetailID: item.QuestionDetailID || 0,
                  QuestionId: item.QuestionId || 0,
                })
              }
            })
          }
        })

        if (!isValid)
          return

        try {
          if (scoreList.length > 0) {
            await updateScore(scoreList)
          }
          await fetchUpdateCurrentQuestionUse(currentQuestion.value?.TeamGroupQuestionID || 0)
          // 发布成功后，清理本地存储
          const prefix = `${roomId.value}-${currentQuestionId.value}-`
          Object.keys(manualStatusStorage.value).forEach((k) => {
            if (k.startsWith(prefix))
              delete manualStatusStorage.value[k]
          })
          Object.keys(manualScoreStorage.value).forEach((k) => {
            if (k.startsWith(prefix))
              delete manualScoreStorage.value[k]
          })
        }
        catch (error: any) {
          window.$message?.error(error.message || '提交分数或发布失败，请重试')
        }
      },
    })
  }
}

/**
 * 消费并发布当前题目
 */
const pollingTimer = ref<NodeJS.Timeout | null>(null)
const nowTs = ref(Date.now())
const canPublish = computed(() => {
  const endTime = (currentQuestion.value as any)?.EndTime
  if (!endTime)
    return true
  // 结束时间 + 5秒延迟才能发布
  const end = new Date(endTime).getTime() + 5000
  return nowTs.value >= end
})

function startPolling() {
  stopPolling()

  // 检查是否已经结束
  const endTime = (currentQuestion.value as any)?.EndTime
  if (endTime) {
    // 增加 12s 缓冲时间
    const end = new Date(endTime).getTime() + 12000
    const now = new Date().getTime()
    if (now > end) {
      console.log('当前题目已结束（含12s缓冲），仅获取一次最终结果，不启动轮询', endTime)
      fetchAnswerData()
      return
    }
  }

  // 如果不是当前正在进行的活动，仅获取一次数据，不启动轮询
  if (!isActiveActivityId.value) {
    console.log('当前活动 ID 不是正在比赛的活动，仅获取一次数据', activityId.value, currentQuestion.value?.ActivityID)
    fetchAnswerData()
    return
  }

  fetchAnswerData() // 立即获取
  nowTs.value = Date.now()
  pollingTimer.value = setInterval(() => {
    // 每次轮询前再次检查是否过期
    const currentEndTime = (currentQuestion.value as any)?.EndTime
    if (currentEndTime) {
      // 增加 12s 缓冲时间
      const endTs = new Date(currentEndTime).getTime() + 12000
      if (Date.now() > endTs) {
        console.log('题目时间已到（含12s缓冲），停止轮询', currentEndTime)
        stopPolling()
        return
      }
    }
    nowTs.value = Date.now()

    // 轮询时同时更新当前题目信息（获取最新的 EndTime），但不触发同步
    fetchCurrentQuestion(false)
    fetchAnswerData()
  }, 3000)
}

function stopPolling() {
  if (pollingTimer.value) {
    clearInterval(pollingTimer.value)
    pollingTimer.value = null
  }
}

/**
 * 消费并发布当前题目
 */
async function fetchUpdateCurrentQuestionUse(TeamGroupQuestionID: number) {
  try {
    const { data, error } = await updateCurrentQuestionUse(TeamGroupQuestionID)
    console.warn('updateCurrentQuestionUse result', data)
    if (!error) {
      window?.$message?.success('结果已发布')
      stopPolling() // 发布后停止轮询
    }
  }
  catch (error: any) {
    window?.$message?.error(error.message)
  }
}

// 监听分组和题目的变化，重新获取答题数据
watch([currentGroupId, currentQuestionId], () => {
  if (currentGroupId.value && currentQuestionId.value) {
    const question = questionList.value.find(q => q.id === currentQuestionId.value)
    if (question) {
      currentQuestionType.value = question.type
    }
    // 重新启动新问题的轮询（通过获取重新开始隐式清除旧的手动编辑？不，等等。）
    // 我们可能需要重置 teamResults 或根据需要处理手动编辑清除。
    // 目前，fetchAnswerData 将根据新问题数据重新初始化。
    // 但是，如果我们保持轮询，我们需要确保如果 ID 冲突（如果 Guid 是唯一的，则不太可能），我们不会保留上一个问题的手动编辑。
    // 让我们停止并重新启动以保持清洁。
    stopPolling()
    teamResults.value = [] // 清除旧结果以避免闪烁或陈旧数据
    startPolling()
  }
})

watch(() => currentQuestionDetailID.value, (newVal) => {
  console.log(newVal)

  if (newVal) {
    fetchQuestionDetail(Number(newVal))
  }
}, { immediate: true })

onMounted(async () => {
  // 并行拉取分组、题目与当前题目，完成后做一次同步
  await Promise.all([fetchGroups(), fetchQuestions(), fetchCurrentQuestion(true)])
  syncCurrentQuestionSelection()
  startPolling()
})

onUnmounted(() => {
  stopPolling()
})
</script>

<template>
  <div class="h-full flex flex-col gap-2 overflow-hidden bg-[#F9FAFB] p-6">
    <!-- 顶部栏 -->
    <div class="flex items-center justify-between rounded-2xl bg-white px-6 py-4 shadow-sm">
      <div class="flex items-center gap-8">
        <h1 class="m-0 flex items-center gap-2 text-xl text-gray-800 font-bold">
          <div class="i-carbon-chart-line-data text-2xl text-blue-600" />
          实时结果
        </h1>
        <GroupTabs
          v-model:group-id="currentGroupId" v-model:question-id="currentQuestionId" :groups="groups"
          :question-list="questionList"
        />
      </div>

      <div class="flex gap-4">
        <div class="flex items-center rounded-full bg-blue-50 px-4 py-1.5 text-sm text-blue-600 font-bold">
          当前进度 {{ questionList.findIndex(q => q.id === currentQuestionId) + 1 }}/{{ questionList.length }}
        </div>
        <NButton type="primary" strong class="px-6" @click="handleNexCurrentQuestion">
          当前题目
        </NButton>
        <NButton secondary strong @click="handleNext">
          下一题
        </NButton>
        <NButton type="tertiary" strong class="px-6" :disabled="!canPublish" @click="handlePublish">
          发布结果
        </NButton>
      </div>
    </div>

    <!-- 主要内容 -->
    <div class="flex-1 overflow-auto">
      <div v-if="teamResults.length === 0" class="h-full flex items-center justify-center text-gray-400">
        暂无队伍数据
      </div>

      <div v-else class="flex flex-col gap-6 pb-6">
        <NCard v-for="team in teamResults" :key="team.TeamId" hoverable>
          <template #header>
            <div class="flex flex-col gap-4">
              <!-- 队伍信息 -->
              <div class="flex items-center gap-2">
                <NTag type="info" round size="large" class="text-base font-bold">
                  {{ team.TeamName || '队伍信息' }}
                </NTag>
              </div>

              <!-- 参考答案展示（如果有） -->
              <div v-if="questionInfo?.Answer" class="border border-green-200 rounded-lg bg-green-50 p-4">
                <div class="mb-2 text-sm text-green-800 font-bold tracking-wider uppercase">
                  参考答案
                </div>
                <div class="text-base text-green-900 font-medium leading-relaxed">
                  {{ questionInfo.Answer }}
                </div>
              </div>
            </div>
          </template>

          <div class="flex flex-row items-start gap-6 px-4 py-2">
            <!-- 学生答题原图 -->
            <!-- <div class="UserAnswerPicture flex-shrink-0">
              <NImage
                v-if="team.UserAnswerPicture" :src="team.UserAnswerPicture" width="550" object-fit="contain"
                class="block border border-gray-200 rounded-lg"
              />
              <div
                v-else
                class="h-[150px] w-[150px] flex items-center justify-center rounded-lg bg-gray-100 p-2 text-center text-xs text-gray-400"
              >
                暂无原图
              </div>
            </div> -->

            <!-- 解析答题里面的题目 -->
            <div class="UserAnswerFont flex-1">
              <div class="flex flex-wrap gap-x-8 gap-y-4">
                <!-- 网格布局：汉字听写、汉字加一加、选择题 -> 带切换的大图 -->
                <div v-if="currentLayout === 'grid'" class="w-full flex flex-col gap-6">
                  <div
                    v-for="(item) in team.Answers" :key="item.Guid"
                    class="relative w-full overflow-hidden border-2 rounded-xl border-dashed p-4 transition-all duration-300"
                    :class="[
                      !item._isManual ? 'border-gray-300 bg-gray-50/30' : (item.Status === 1 ? 'border-green-500 bg-green-50/30' : 'border-red-500 bg-red-50/30'),
                    ]"
                  >
                    <div v-if="item.AnswerText" class="border-b border-gray-200 pb-2 text-lg text-gray-800 font-bold">
                      <span> 由 ai识别出的答题文本：</span>
                      <Typewriter :text="item.AnswerText" />
                    </div>

                    <!-- AI Suggestion Indicator -->
                    <div class="mb-2 flex items-center justify-center gap-2 text-xs font-bold">
                      <!-- AI 推荐 -->
                      <div class="flex items-center gap-1 text-orange-500">
                        <div class="i-carbon-ai-status" />
                        <span>AI: {{ item._aiScore }}分 ({{ item._aiStatus === 1 ? '对' : '错' }})</span>
                      </div>
                      <!-- 分隔符 -->
                      <div class="h-3 w-[1px] bg-gray-300" />
                      <!-- 当前状态 -->
                      <div v-if="!item._isManual" class="text-gray-400">
                        跟随 AI
                      </div>
                      <div v-else class="flex items-center gap-1 text-green-600">
                        <div class="i-carbon-user-avatar-filled-alt" />
                        <span>人工: {{ item.Status === 1 ? '对' : '错' }}</span>
                      </div>
                    </div>
                    <!-- 图片展示 -->
                    <div class="flex items-center justify-center">
                      <NImage
                        :src="item.AnswerValuePicture || item.imageUrl" object-fit="contain"
                        class="max-h-[300px] w-full"
                      />
                    </div>

                    <!-- Toggle Button Overlay (Center) -->
                    <div
                      class="absolute inset-0 flex flex-col items-center justify-center gap-2 opacity-0 transition-opacity duration-200 hover:opacity-100"
                    >
                      <!-- 如果未校准，显示两个按钮 -->
                      <template v-if="!item._isManual">
                        <NButton
                          strong secondary round size="medium" type="success" class="shadow-xl"
                          @click="setStatus(team, item, 1)"
                        >
                          确认正确 (绿)
                        </NButton>
                        <NButton
                          strong secondary round size="medium" type="error" class="shadow-xl"
                          @click="setStatus(team, item, 0)"
                        >
                          确认错误 (红)
                        </NButton>
                      </template>

                      <!-- 如果已校准，显示切换按钮 -->
                      <template v-else>
                        <NButton
                          strong secondary round size="large" :type="item.Status === 1 ? 'error' : 'success'"
                          class="shadow-xl" @click="setStatus(team, item, item.Status === 1 ? 0 : 1)"
                        >
                          切换为 {{ item.Status === 1 ? '错误 (红)' : '正确 (绿)' }}
                        </NButton>
                      </template>
                    </div>

                    <!-- Status Icon (Top Right) - Only show if manually calibrated -->
                    <div v-if="item._isManual" class="absolute right-4 top-4 z-10">
                      <div class="rounded-full bg-white shadow-md">
                        <Icon v-if="item.Status === 1" icon="mdi:check-circle" class="text-4xl text-green-500" />
                        <Icon v-else icon="mdi:close-circle" class="text-4xl text-red-500" />
                      </div>
                    </div>

                    <!-- Manual Calibration Badge (Bottom Right) -->
                    <div class="absolute bottom-4 right-4 z-10">
                      <div
                        class="flex items-center gap-1 border border-green-200 rounded bg-green-50 px-2 py-1 text-xs text-green-600"
                      >
                        <icon-ic:twotone-rule class="text-icon" />
                        <span> 已人工校准</span>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- List Layout: 主观题 -> Split View (Image Left, Scoring Right) -->
                <div v-else class="w-full flex flex-col gap-6">
                  <div
                    v-for="item in team.Answers" :key="item.Guid"
                    class="flex flex-col gap-6 border border-gray-100 rounded-xl bg-white p-6 shadow-sm"
                  >
                    <!-- Title -->
                    <div class="text-lg text-gray-800 font-bold">
                      <span> 由 ai识别出的答题文本：</span>
                      <Typewriter :text="item.AnswerText || '题目'" />
                    </div>

                    <div class="flex flex-col gap-6 lg:flex-row">
                      <!-- Left: Original Image Display Area -->
                      <div
                        class="relative min-h-[800px] flex-1 overflow-hidden border-2 border-gray-200 rounded-xl border-dashed bg-gray-50 p-4"
                      >
                        <div class="absolute left-4 top-4 flex items-center gap-1 text-sm text-gray-400">
                          <div class="i-carbon-image" />
                          主观题原图展示区
                        </div>

                        <div class="h-full flex items-center justify-center">
                          <NImage
                            v-if="item.AnswerValuePicture || item.imageUrl"
                            :src="item.AnswerValuePicture || item.imageUrl" object-fit="contain"
                            class="max-h-[800px] w-full"
                          />
                          <div v-else class="text-gray-300">
                            <div class="i-carbon-no-image text-6xl" />
                          </div>
                        </div>
                      </div>

                      <!-- Right: Scoring Panel -->
                      <div class="w-full flex flex-col gap-6 rounded-xl bg-blue-50/30 p-6 lg:w-[320px]">
                        <div>
                          <div class="text-lg text-gray-800 font-bold">
                            人工评分
                          </div>
                          <div class="mt-1 text-sm text-gray-500">
                            请根据对的字数进行打分
                          </div>
                          <!-- 评分状态展示区域：明确区分 AI 推荐和人工干预状态 -->
                          <div class="mt-2 flex flex-col gap-2">
                            <!-- AI 推荐信息 (始终显示，作为参考) -->
                            <div
                              class="flex items-center justify-between border border-gray-100 rounded bg-gray-50 px-3 py-2"
                            >
                              <div class="flex items-center gap-1.5">
                                <div class="i-carbon-ai-status text-orange-500" />
                                <span class="text-xs text-gray-600 font-medium">AI 推荐</span>
                              </div>
                              <div class="flex items-center gap-2">
                                <span class="text-sm text-gray-800 font-bold">{{ item._aiScore }} 分</span>
                                <span
                                  class="rounded px-1.5 py-0.5 text-[10px]"
                                  :class="item._aiStatus === 1 ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'"
                                >
                                  {{ item._aiStatus === 1 ? '判对' : '判错' }}
                                </span>
                              </div>
                            </div>

                            <!-- 当前生效状态提示 -->
                            <div
                              v-if="item._isManual"
                              class="flex items-center gap-1 border border-green-200 rounded bg-green-50 px-2 py-1 text-xs text-green-600"
                            >
                              <!-- <div class="i-carbon-user-avatar-filled-alt" /> -->
                              <icon-ic:twotone-rule class="text-icon" />
                              <span> 已人工校准</span>
                            </div>

                            <div v-else class="flex items-center gap-1.5 px-1 text-xs text-gray-400">
                              <div class="i-carbon-arrows-horizontal" />
                              <span>当前跟随 AI 推荐结果</span>
                            </div>
                          </div>
                        </div>

                        <!-- Score Input -->
                        <div class="flex flex-col gap-2">
                          <div class="text-sm text-gray-600 font-medium">
                            最终得分 (人工)
                          </div>
                          <div class="flex items-center border border-blue-100 rounded-xl bg-white px-4 py-3 shadow-sm">
                            <!-- <NInputNumber v-model:value="item.Score" :min="0" :max="100" :show-button="false"
                              class="flex-1 text-center text-3xl font-bold !border-none" placeholder="0" /> -->
                            <NInputNumber
                              v-model:value="item.Score" button-placement="both" :min="0" :max="100"
                              @update:value="(val) => handleManualScoreUpdate(item, val || 0)"
                            >
                              <template #suffix>
                                分
                              </template>
                            </NInputNumber>
                          </div>
                        </div>

                        <!-- Quick Score Buttons -->
                        <div class="flex flex-col gap-2">
                          <div class="text-sm text-gray-600 font-medium">
                            快捷打分
                          </div>
                          <div class="grid grid-cols-4 gap-2">
                            <NButton
                              v-for="score in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" :key="score" secondary strong
                              :type="item.Score === score ? 'primary' : 'default'" class="h-10 w-full"
                              @click="() => handleManualScoreUpdate(item, score)"
                            >
                              {{ score }}
                            </NButton>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </NCard>
      </div>
    </div>
  </div>
</template>

<style scoped>
:deep(.n-card__content) {
  padding: 0;
}
</style>
