/**
 * 大屏得分与结束画面
 * 左上角：分数卡片（紫色）
 * 右上角：房间号卡片（紫色）
 * 游戏结束：全屏遮罩 + 大卡片展示得分
 */
import { SCREEN_WIDTH, SCREEN_HEIGHT, SAFE_AREA_TOP } from '../constants.js'

const TEAM_NAME_MAP = {
  A: '深耕队',
  B: '致远队',
}

function getTeamDisplayName(team) {
  return TEAM_NAME_MAP[team] || team
}

// ─── 工具 ─────────────────────────────────────────────────────────────────────

function roundRectPath(ctx, x, y, w, h, r) {
  ctx.beginPath()
  ctx.moveTo(x + r, y)
  ctx.lineTo(x + w - r, y)
  ctx.arcTo(x + w, y, x + w, y + r, r)
  ctx.lineTo(x + w, y + h - r)
  ctx.arcTo(x + w, y + h, x + w - r, y + h, r)
  ctx.lineTo(x + r, y + h)
  ctx.arcTo(x, y + h, x, y + h - r, r)
  ctx.lineTo(x, y + r)
  ctx.arcTo(x, y, x + r, y, r)
  ctx.closePath()
}

function drawStar(ctx, cx, cy, outerR, innerR, color, alpha) {
  ctx.save()
  if (alpha !== undefined) ctx.globalAlpha = alpha
  ctx.fillStyle = color
  ctx.beginPath()
  for (let i = 0; i < 10; i++) {
    const angle = (i * Math.PI) / 5 - Math.PI / 2
    const r = i % 2 === 0 ? outerR : innerR
    ctx.lineTo(cx + r * Math.cos(angle), cy + r * Math.sin(angle))
  }
  ctx.closePath()
  ctx.fill()
  ctx.restore()
}

// ─── 得分卡片（左上）──────────────────────────────────────────────────────────

function drawScoreCard(ctx, score) {
  const boxX = 10
  const boxY = SAFE_AREA_TOP + 8
  const boxH = 44
  const scoreText = String(score)

  ctx.save()
  ctx.font = 'bold 24px Arial'
  const sw = ctx.measureText(scoreText).width
  ctx.font = 'bold 11px Arial'
  const lw = ctx.measureText('分数').width
  const boxW = Math.max(sw, lw) + 28
  const r = 10

  ctx.shadowColor = 'rgba(0,0,0,0.4)'
  ctx.shadowBlur = 8
  ctx.shadowOffsetY = 3
  const bg = ctx.createLinearGradient(boxX, boxY, boxX, boxY + boxH)
  bg.addColorStop(0, 'rgba(139,92,246,0.9)')
  bg.addColorStop(1, 'rgba(124,58,237,0.95)')
  ctx.fillStyle = bg
  roundRectPath(ctx, boxX, boxY, boxW, boxH, r)
  ctx.fill()
  ctx.shadowBlur = 0

  const hl = ctx.createLinearGradient(boxX, boxY, boxX + boxW, boxY)
  hl.addColorStop(0, 'rgba(167,139,250,0.6)')
  hl.addColorStop(0.5, 'rgba(196,181,253,0.8)')
  hl.addColorStop(1, 'rgba(167,139,250,0.6)')
  ctx.fillStyle = hl
  ctx.fillRect(boxX + 4, boxY + 4, boxW - 8, 3)

  ctx.strokeStyle = 'rgba(167,139,250,0.5)'
  ctx.lineWidth = 1.5
  roundRectPath(ctx, boxX, boxY, boxW, boxH, r)
  ctx.stroke()
  ctx.restore()

  const cx = boxX + boxW / 2
  ctx.textAlign = 'center'
  ctx.textBaseline = 'alphabetic'
  ctx.font = 'bold 11px Arial'
  ctx.fillStyle = 'rgba(221,214,254,0.9)'
  ctx.fillText('分数', cx, boxY + 18)

  ctx.font = 'bold 24px Arial'
  ctx.fillStyle = 'rgba(0,0,0,0.3)'
  ctx.fillText(scoreText, cx + 1, boxY + 39)
  const sg = ctx.createLinearGradient(cx - 20, 0, cx + 20, 0)
  sg.addColorStop(0, '#FDE68A')
  sg.addColorStop(0.5, '#FCD34D')
  sg.addColorStop(1, '#F59E0B')
  ctx.fillStyle = sg
  ctx.fillText(scoreText, cx, boxY + 38)
}

// ─── 房间号卡片（右上）────────────────────────────────────────────────────────

function drawRoomCard(ctx, roomId) {
  if (!roomId && roomId !== 0) return
  const label = String(roomId)
  const boxY = SAFE_AREA_TOP + 8
  const boxH = 44
  const r = 10

  ctx.save()
  ctx.font = 'bold 18px Arial'
  const rw = ctx.measureText(label).width
  ctx.font = 'bold 11px Arial'
  const lw = ctx.measureText('房间').width
  const boxW = Math.max(rw, lw) + 28
  const boxX = SCREEN_WIDTH - boxW - 10

  ctx.shadowColor = 'rgba(0,0,0,0.4)'
  ctx.shadowBlur = 8
  ctx.shadowOffsetY = 3
  const bg = ctx.createLinearGradient(boxX, boxY, boxX, boxY + boxH)
  bg.addColorStop(0, 'rgba(139,92,246,0.9)')
  bg.addColorStop(1, 'rgba(124,58,237,0.95)')
  ctx.fillStyle = bg
  roundRectPath(ctx, boxX, boxY, boxW, boxH, r)
  ctx.fill()
  ctx.shadowBlur = 0

  const hl = ctx.createLinearGradient(boxX, boxY, boxX + boxW, boxY)
  hl.addColorStop(0, 'rgba(167,139,250,0.6)')
  hl.addColorStop(0.5, 'rgba(196,181,253,0.8)')
  hl.addColorStop(1, 'rgba(167,139,250,0.6)')
  ctx.fillStyle = hl
  ctx.fillRect(boxX + 4, boxY + 4, boxW - 8, 3)

  ctx.strokeStyle = 'rgba(167,139,250,0.5)'
  ctx.lineWidth = 1.5
  roundRectPath(ctx, boxX, boxY, boxW, boxH, r)
  ctx.stroke()
  ctx.restore()

  const cx = boxX + boxW / 2
  ctx.textAlign = 'center'
  ctx.textBaseline = 'alphabetic'
  ctx.font = 'bold 11px Arial'
  ctx.fillStyle = 'rgba(221,214,254,0.9)'
  ctx.fillText('房间', cx, boxY + 18)

  ctx.font = 'bold 18px Arial'
  ctx.fillStyle = 'rgba(0,0,0,0.3)'
  ctx.fillText(label, cx + 1, boxY + 39)
  const rg = ctx.createLinearGradient(cx - 30, 0, cx + 30, 0)
  rg.addColorStop(0, '#67E8F9')
  rg.addColorStop(0.5, '#22D3EE')
  rg.addColorStop(1, '#06B6D4')
  ctx.fillStyle = rg
  ctx.fillText(label, cx, boxY + 38)
}

function formatRemainTime(remainingSec) {
  const safeSec = Math.max(0, Math.floor(remainingSec || 0))
  const minutes = String(Math.floor(safeSec / 60)).padStart(2, '0')
  const seconds = String(safeSec % 60).padStart(2, '0')
  return `${minutes}:${seconds}`
}

export function drawRoomTimerCard(ctx, remainingSec, totalWidth = SCREEN_WIDTH) {
  const label = formatRemainTime(remainingSec)
  const boxY = SAFE_AREA_TOP + 8
  const boxH = 44
  const r = 10

  ctx.save()
  ctx.font = 'bold 22px Arial'
  const timeW = ctx.measureText(label).width
  ctx.font = 'bold 11px Arial'
  const titleW = ctx.measureText('时间').width
  const boxW = Math.max(timeW, titleW) + 34
  const boxX = totalWidth / 2 - boxW / 2

  ctx.shadowColor = 'rgba(0,0,0,0.45)'
  ctx.shadowBlur = 10
  ctx.shadowOffsetY = 4
  const bg = ctx.createLinearGradient(boxX, boxY, boxX, boxY + boxH)
  bg.addColorStop(0, 'rgba(139,92,246,0.92)')
  bg.addColorStop(1, 'rgba(124,58,237,0.97)')
  ctx.fillStyle = bg
  roundRectPath(ctx, boxX, boxY, boxW, boxH, r)
  ctx.fill()
  ctx.shadowBlur = 0

  const hl = ctx.createLinearGradient(boxX, boxY, boxX + boxW, boxY)
  hl.addColorStop(0, 'rgba(167,139,250,0.55)')
  hl.addColorStop(0.5, 'rgba(196,181,253,0.88)')
  hl.addColorStop(1, 'rgba(167,139,250,0.55)')
  ctx.fillStyle = hl
  ctx.fillRect(boxX + 4, boxY + 4, boxW - 8, 3)

  ctx.strokeStyle = 'rgba(167,139,250,0.55)'
  ctx.lineWidth = 1.5
  roundRectPath(ctx, boxX, boxY, boxW, boxH, r)
  ctx.stroke()

  const cx = boxX + boxW / 2
  ctx.textAlign = 'center'
  ctx.textBaseline = 'alphabetic'
  ctx.font = 'bold 11px Arial'
  ctx.fillStyle = 'rgba(221,214,254,0.95)'
  ctx.fillText('时间', cx, boxY + 18)

  ctx.font = 'bold 22px Arial'
  ctx.fillStyle = 'rgba(0,0,0,0.32)'
  ctx.fillText(label, cx + 1, boxY + 39)
  const tg = ctx.createLinearGradient(cx - 35, 0, cx + 35, 0)
  tg.addColorStop(0, '#FDE68A')
  tg.addColorStop(0.5, '#FCD34D')
  tg.addColorStop(1, '#F59E0B')
  ctx.fillStyle = tg
  ctx.fillText(label, cx, boxY + 38)
  ctx.restore()
}

// ─── 游戏结束大卡片 ───────────────────────────────────────────────────────────

function getStarCount(score) {
  if (score >= 70) return 3
  if (score >= 30) return 2
  return 1
}

function sortPlayersByScore(players) {
  return [...(players || [])].sort((a, b) => (Number(b.score) || 0) - (Number(a.score) || 0))
}

function drawOverlay(ctx) {
  ctx.save()
  const cx = SCREEN_WIDTH / 2
  const cy = SCREEN_HEIGHT / 2
  const g = ctx.createRadialGradient(cx, cy, 60, cx, cy, SCREEN_HEIGHT * 0.75)
  g.addColorStop(0, 'rgba(0,0,0,0.55)')
  g.addColorStop(1, 'rgba(0,0,0,0.92)')
  ctx.fillStyle = g
  ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)
  ctx.restore()
}

function drawGameOverCard(ctx, score, nickname = '') {
  const cw = 300
  const ch = 360
  const cx = SCREEN_WIDTH / 2
  const cardX = cx - cw / 2
  const cardY = SCREEN_HEIGHT / 2 - ch / 2 - 10
  const r = 24

  ctx.save()
  ctx.shadowColor = 'rgba(0,0,0,0.8)'
  ctx.shadowBlur = 60
  ctx.shadowOffsetY = 20
  const bg = ctx.createLinearGradient(cardX, cardY, cardX, cardY + ch)
  bg.addColorStop(0, '#2d1b69')
  bg.addColorStop(1, '#0f0c29')
  ctx.fillStyle = bg
  roundRectPath(ctx, cardX, cardY, cw, ch, r)
  ctx.fill()
  ctx.shadowBlur = 0
  ctx.shadowOffsetY = 0

  // 顶部彩色光条
  ctx.save()
  roundRectPath(ctx, cardX, cardY, cw, ch, r)
  ctx.clip()
  const bar = ctx.createLinearGradient(cardX, 0, cardX + cw, 0)
  bar.addColorStop(0, '#a855f7')
  bar.addColorStop(0.5, '#ec4899')
  bar.addColorStop(1, '#f97316')
  ctx.fillStyle = bar
  ctx.fillRect(cardX, cardY, cw, 8)
  ctx.restore()

  // 装饰星星
  drawStar(ctx, cardX + 30, cardY + 50, 12, 5, '#fbbf24', 0.5)
  drawStar(ctx, cardX + cw - 30, cardY + 50, 10, 4, '#f472b6', 0.45)
  drawStar(ctx, cardX + 18, cardY + 145, 7, 3, '#60a5fa', 0.35)
  drawStar(ctx, cardX + cw - 18, cardY + 145, 8, 3, '#fbbf24', 0.35)

  // 标题
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.shadowColor = 'rgba(236,72,153,0.9)'
  ctx.shadowBlur = 22
  ctx.font = 'bold 34px Arial'
  const tg = ctx.createLinearGradient(cx - 80, 0, cx + 80, 0)
  tg.addColorStop(0, '#f9a8d4')
  tg.addColorStop(0.5, '#ffffff')
  tg.addColorStop(1, '#c4b5fd')
  ctx.fillStyle = tg
  ctx.fillText('游戏结束', cx, cardY + 68)
  ctx.shadowBlur = 0

  // 昵称（有昵称才显示）
  if (nickname) {
    ctx.font = 'bold 14px Arial'
    ctx.fillStyle = 'rgba(196,181,253,0.85)'
    ctx.fillText(nickname, cx, cardY + 100)
  }

  // 分割线
  const dg = ctx.createLinearGradient(cardX + 20, 0, cardX + cw - 20, 0)
  dg.addColorStop(0, 'rgba(255,255,255,0)')
  dg.addColorStop(0.5, 'rgba(255,255,255,0.25)')
  dg.addColorStop(1, 'rgba(255,255,255,0)')
  ctx.strokeStyle = dg
  ctx.lineWidth = 1
  ctx.beginPath()
  ctx.moveTo(cardX + 20, cardY + 108)
  ctx.lineTo(cardX + cw - 20, cardY + 108)
  ctx.stroke()

  // 本局得分标签
  ctx.font = '15px Arial'
  ctx.fillStyle = 'rgba(255,255,255,0.5)'
  ctx.fillText('本局得分', cx, cardY + 140)


  // 分数数字
  ctx.shadowColor = 'rgba(251,191,36,0.7)'
  ctx.shadowBlur = 30
  ctx.font = 'bold 72px Arial'
  const sg = ctx.createLinearGradient(cx - 55, 0, cx + 55, 0)
  sg.addColorStop(0, '#fde047')
  sg.addColorStop(0.5, '#fbbf24')
  sg.addColorStop(1, '#f59e0b')
  ctx.fillStyle = sg
  ctx.fillText(String(score), cx, cardY + 218)
  ctx.shadowBlur = 0

  // 星星评级
  const starY = cardY + 295
  const litCount = getStarCount(score)
  ;[
    { x: cx - 44, oR: 13, iR: 5 },
    { x: cx,      oR: 17, iR: 7 },
    { x: cx + 44, oR: 13, iR: 5 },
  ].forEach((s, i) => {
    if (i < litCount) drawStar(ctx, s.x, starY, s.oR, s.iR, '#fbbf24')
    else drawStar(ctx, s.x, starY, s.oR, s.iR, '#4a4a6a', 0.5)
  })

  ctx.restore()
}

// ─── 公开导出 ─────────────────────────────────────────────────────────────────

export function drawGameInfo(ctx, score = 0, isGameOver = false, roomId = '', nickname = '') {
  drawScoreCard(ctx, score)
  if (roomId !== '' && roomId !== null && roomId !== undefined) {
    drawRoomCard(ctx, roomId)
  }
  // 游戏进行中底部显示昵称
  if (nickname && !isGameOver) {
    drawNicknameBar(ctx, nickname)
  }
  if (isGameOver) {
    drawOverlay(ctx)
    drawGameOverCard(ctx, score, nickname)
  }
}

// ─── 队伍比分覆盖层（游戏结束时）──────────────────────────────────────────────

export function drawTeamResultOverlay(ctx, playerStates, getPlayerTeam, totalWidth) {
  const states = playerStates || []
  if (states.length === 0) return

  // 使用传入的总宽度或默认单屏宽度
  const canvasWidth = totalWidth || SCREEN_WIDTH
  const canvasHeight = SCREEN_HEIGHT

  console.log('[drawTeamResultOverlay]', { totalWidth, canvasWidth, canvasHeight, SCREEN_WIDTH, SCREEN_HEIGHT, statesCount: states.length })
  console.log('[drawTeamResultOverlay] 玩家状态:', states.map(s => ({ playerId: s.playerId, nickname: s.nickname, score: s.score, team: getPlayerTeam(s.playerId ?? 1) })))

  // 按队伍分组
  const teamAPlayers = sortPlayersByScore(states.filter(s => getPlayerTeam(s.playerId ?? 1) === 'A'))
  const teamBPlayers = sortPlayersByScore(states.filter(s => getPlayerTeam(s.playerId ?? 1) === 'B'))
  console.log('[drawTeamResultOverlay] 队伍分组:', { A: teamAPlayers.length, B: teamBPlayers.length })

  // 计算总分
  const teamAScore = teamAPlayers.reduce((sum, p) => sum + (p.score || 0), 0)
  const teamBScore = teamBPlayers.reduce((sum, p) => sum + (p.score || 0), 0)

  // 判断胜负
  const isDraw = teamAScore === teamBScore
  const winner = teamAScore > teamBScore ? 'A' : 'B'

  const cx = canvasWidth / 2
  const startY = canvasHeight * 0.1

  // 轻遮罩 + 氛围光，保留背景层次，避免整页发黑发闷
  ctx.save()
  const veil = ctx.createLinearGradient(0, 0, 0, canvasHeight)
  veil.addColorStop(0, 'rgba(14,8,26,0.42)')
  veil.addColorStop(0.55, 'rgba(10,6,22,0.58)')
  veil.addColorStop(1, 'rgba(6,3,14,0.72)')
  ctx.fillStyle = veil
  ctx.fillRect(0, 0, canvasWidth, canvasHeight)

  const leftGlow = ctx.createRadialGradient(
    canvasWidth * 0.18, canvasHeight * 0.62, 0,
    canvasWidth * 0.18, canvasHeight * 0.62, canvasWidth * 0.28
  )
  leftGlow.addColorStop(0, 'rgba(245,158,11,0.16)')
  leftGlow.addColorStop(1, 'rgba(245,158,11,0)')
  ctx.fillStyle = leftGlow
  ctx.fillRect(0, 0, canvasWidth, canvasHeight)

  const rightGlow = ctx.createRadialGradient(
    canvasWidth * 0.82, canvasHeight * 0.24, 0,
    canvasWidth * 0.82, canvasHeight * 0.24, canvasWidth * 0.24
  )
  rightGlow.addColorStop(0, 'rgba(236,72,153,0.14)')
  rightGlow.addColorStop(1, 'rgba(236,72,153,0)')
  ctx.fillStyle = rightGlow
  ctx.fillRect(0, 0, canvasWidth, canvasHeight)
  ctx.restore()

  // 标题
  ctx.save()
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.font = 'bold 42px Arial'
  const titleText = isDraw ? '平局!' : `${getTeamDisplayName(winner)}胜利!`
  const titleColor = isDraw ? '#FCD34D' : winner === 'A' ? '#8B5CF6' : '#EC4899'
  ctx.shadowColor = titleColor
  ctx.shadowBlur = 25
  ctx.fillStyle = titleColor
  ctx.fillText(titleText, cx, startY)
  ctx.shadowBlur = 0
  ctx.restore()

  // 队伍比分卡片 - 使用更宽的卡片确保覆盖所有内容
  const cardY = startY + 50
  const cardW = Math.min(800, canvasWidth * 0.85)
  const cardH = 140
  const cardX = cx - cardW / 2

  ctx.save()
  const scoreCardBg = ctx.createLinearGradient(cardX, cardY, cardX, cardY + cardH)
  scoreCardBg.addColorStop(0, 'rgba(64,33,116,0.74)')
  scoreCardBg.addColorStop(0.5, 'rgba(40,19,76,0.66)')
  scoreCardBg.addColorStop(1, 'rgba(20,10,42,0.72)')
  ctx.fillStyle = scoreCardBg
  ctx.strokeStyle = 'rgba(196,181,253,0.36)'
  ctx.lineWidth = 2
  ctx.shadowColor = 'rgba(0,0,0,0.24)'
  ctx.shadowBlur = 26
  ctx.shadowOffsetY = 10
  ctx.beginPath()
  ctx.roundRect(cardX, cardY, cardW, cardH, 16)
  ctx.fill()
  ctx.shadowBlur = 0
  ctx.stroke()

  ctx.beginPath()
  ctx.roundRect(cardX, cardY, cardW, cardH, 16)
  ctx.clip()
  const scoreHl = ctx.createLinearGradient(cardX, cardY, cardX, cardY + cardH * 0.45)
  scoreHl.addColorStop(0, 'rgba(255,255,255,0.16)')
  scoreHl.addColorStop(1, 'rgba(255,255,255,0)')
  ctx.fillStyle = scoreHl
  ctx.fillRect(cardX, cardY, cardW, cardH * 0.45)
  ctx.restore()

  // A队分数（左侧）
  const teamAX = cardX + cardW * 0.25
  drawTeamScoreBig(ctx, teamAX, cardY + cardH / 2, 'A', teamAScore, winner === 'A' && !isDraw)

  // VS（中间）
  ctx.save()
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.font = 'bold 36px Arial'
  ctx.fillStyle = 'rgba(251,191,36,0.9)'
  ctx.fillText('VS', cx, cardY + cardH / 2)
  ctx.restore()

  // B队分数（右侧）
  const teamBX = cardX + cardW * 0.75
  drawTeamScoreBig(ctx, teamBX, cardY + cardH / 2, 'B', teamBScore, winner === 'B' && !isDraw)

  // 玩家详细列表 - 使用更宽的卡片
  const listY = cardY + cardH + 40
  const listCardW = cardW
  const listCardH = Math.min(380, canvasHeight - listY - 60)
  const listCardX = cx - listCardW / 2

  ctx.save()
  const listBg = ctx.createLinearGradient(listCardX, listY, listCardX, listY + listCardH)
  listBg.addColorStop(0, 'rgba(28,14,52,0.66)')
  listBg.addColorStop(1, 'rgba(12,7,26,0.58)')
  ctx.fillStyle = listBg
  ctx.strokeStyle = 'rgba(196,181,253,0.3)'
  ctx.lineWidth = 2
  ctx.shadowColor = 'rgba(0,0,0,0.18)'
  ctx.shadowBlur = 22
  ctx.shadowOffsetY = 8
  ctx.beginPath()
  ctx.roundRect(listCardX, listY, listCardW, listCardH, 12)
  ctx.fill()
  ctx.shadowBlur = 0
  ctx.stroke()

  ctx.beginPath()
  ctx.roundRect(listCardX, listY, listCardW, listCardH, 12)
  ctx.clip()
  const listHl = ctx.createLinearGradient(listCardX, listY, listCardX, listY + listCardH * 0.28)
  listHl.addColorStop(0, 'rgba(255,255,255,0.12)')
  listHl.addColorStop(1, 'rgba(255,255,255,0)')
  ctx.fillStyle = listHl
  ctx.fillRect(listCardX, listY, listCardW, listCardH * 0.28)
  ctx.restore()

  // 左右两列显示玩家 - 调整列宽以适应更宽的卡片
  const colW = listCardW / 2 - 40
  const colX_A = listCardX + 25
  const colX_B = listCardX + listCardW / 2 + 15

  // A队玩家列表
  drawTeamPlayerList(ctx, colX_A, listY + 15, colW, listCardH - 30, 'A', teamAPlayers, winner === 'A' && !isDraw)

  // B队玩家列表
  drawTeamPlayerList(ctx, colX_B, listY + 15, colW, listCardH - 30, 'B', teamBPlayers, winner === 'B' && !isDraw)

  // 提示文字
  ctx.save()
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.font = '16px Arial'
  ctx.fillStyle = 'rgba(196,181,253,0.6)'
  ctx.fillText('等待大屏切换...', cx, canvasHeight - 35)
  ctx.restore()
}

function drawTeamScoreBig(ctx, x, y, team, score, isWinner) {
  const color = team === 'A' ? '#8B5CF6' : '#EC4899'
  const glowColor = isWinner ? color : 'transparent'

  ctx.save()

  // 队伍标签（失败方变灰）
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.font = 'bold 18px Arial'
  ctx.fillStyle = isWinner ? color : 'rgba(150,150,150,0.6)'
  ctx.fillText(getTeamDisplayName(team), x, y - 28)

  // 分数（胜利方更大更亮，失败方灰色暗淡）
  ctx.font = isWinner ? 'bold 56px Arial' : 'bold 42px Arial'
  ctx.shadowColor = glowColor
  ctx.shadowBlur = isWinner ? 30 : 0
  if (isWinner) {
    const sg = ctx.createLinearGradient(x - 50, 0, x + 50, 0)
    sg.addColorStop(0, '#FDE68A')
    sg.addColorStop(0.5, '#FCD34D')
    sg.addColorStop(1, '#F59E0B')
    ctx.fillStyle = sg
  } else {
    ctx.fillStyle = 'rgba(120,120,120,0.5)'
  }
  ctx.fillText(String(score), x, y + 15)
  ctx.shadowBlur = 0

  ctx.restore()
}

function drawTeamPlayerList(ctx, x, y, w, h, team, players, isWinner) {
  const color = team === 'A' ? '#8B5CF6' : '#EC4899'
  const rowHeight = 36

  ctx.save()

  // 失败方用灰色替换队伍主色
  const displayColor = isWinner ? color : 'rgba(150,150,150,0.6)'

  // 队伍标题
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.font = 'bold 16px Arial'
  ctx.fillStyle = displayColor
  ctx.fillText(`${getTeamDisplayName(team)}成员`, x + w / 2, y + 12)

  // 分割线
  ctx.strokeStyle = isWinner ? color + '40' : 'rgba(150,150,150,0.2)'
  ctx.lineWidth = 1
  ctx.beginPath()
  ctx.moveTo(x + 5, y + 26)
  ctx.lineTo(x + w - 5, y + 26)
  ctx.stroke()

  // 玩家列表
  ctx.font = '13px Arial'
  players.forEach((player, index) => {
    const rowY = y + 45 + index * rowHeight
    if (rowY > y + h - 20) return // 超出范围不显示

    // 背景高亮（仅胜利方）
    if (isWinner) {
      ctx.fillStyle = color + '15'
      ctx.beginPath()
      ctx.roundRect(x + 2, rowY - 14, w - 4, 28, 6)
      ctx.fill()
    }

    if (index > 0) {
      ctx.strokeStyle = 'rgba(255,255,255,0.05)'
      ctx.lineWidth = 1
      ctx.beginPath()
      ctx.moveTo(x + 8, rowY - rowHeight / 2)
      ctx.lineTo(x + w - 8, rowY - rowHeight / 2)
      ctx.stroke()
    }

    // 排名
    ctx.textAlign = 'center'
    ctx.fillStyle = isWinner
      ? (index === 0 ? '#FCD34D' : 'rgba(196,181,253,0.6)')
      : 'rgba(120,120,120,0.5)'
    ctx.fillText(String(index + 1), x + 15, rowY)

    // 昵称
    ctx.textAlign = 'left'
    ctx.fillStyle = isWinner ? 'rgba(255,255,255,0.9)' : 'rgba(130,130,130,0.6)'
    const nickname = player.nickname || `玩家${player.playerId}`
    const displayName = nickname.length > 8 ? nickname.slice(0, 8) + '...' : nickname
    ctx.fillText(displayName, x + 30, rowY)

    // 分数
    ctx.textAlign = 'right'
    ctx.fillStyle = isWinner ? '#FCD34D' : 'rgba(120,120,120,0.5)'
    ctx.font = 'bold 13px Arial'
    ctx.fillText(String(player.score || 0), x + w - 10, rowY)
    ctx.font = '13px Arial'
  })

  ctx.restore()
}

// ─── 底部昵称条 ───────────────────────────────────────────────────────────────

function drawNicknameBar(ctx, nickname) {
  const cx   = SCREEN_WIDTH / 2
  const barY = SCREEN_HEIGHT - 28
  const barH = 22

  ctx.save()

  // 背景胶囊
  ctx.font = `bold 12px Arial`
  const tw = ctx.measureText(nickname).width
  const bw = tw + 24
  const bx = cx - bw / 2

  ctx.shadowColor   = 'rgba(139,92,246,0.4)'
  ctx.shadowBlur    = 8
  ctx.shadowOffsetY = 2
  const bg = ctx.createLinearGradient(bx, barY, bx, barY + barH)
  bg.addColorStop(0, 'rgba(139,92,246,0.75)')
  bg.addColorStop(1, 'rgba(109,40,217,0.8)')
  ctx.fillStyle = bg
  roundRectPath(ctx, bx, barY, bw, barH, barH / 2)
  ctx.fill()
  ctx.shadowBlur = 0

  // 边框
  ctx.strokeStyle = 'rgba(196,181,253,0.5)'
  ctx.lineWidth   = 1
  roundRectPath(ctx, bx, barY, bw, barH, barH / 2)
  ctx.stroke()

  // 昵称文字
  ctx.textAlign    = 'center'
  ctx.textBaseline = 'middle'
  ctx.fillStyle    = '#fff'
  ctx.fillText(nickname, cx, barY + barH / 2)

  ctx.restore()
}
