export type StadiumRoundOutcome = 'win' | 'loss' | 'tie'
export type StadiumWins = {
  player: number
  opponent: number
}
export type StadiumRoundStatus = 'playing' | 'shop' | 'won' | 'lost'
export type StadiumExperienceMode =
  | 'pvp-stadium-round-win-quarter-level'
  | 'pvp-stadium-round-loss-tenth-level'
  | 'pvp-stadium-match-half-level'

export const DEFAULT_STADIUM_WIN_ROUNDS = 3

export function stadiumShopPointsForOutcome(outcome: StadiumRoundOutcome, side: 'player' | 'opponent') {
  if (side === 'player') return outcome === 'loss' ? 4 : 3
  return outcome === 'win' ? 4 : 3
}

export function resolveStadiumRound({
  outcome,
  roundIndex,
  wins,
  winRounds = DEFAULT_STADIUM_WIN_ROUNDS,
}: {
  outcome: StadiumRoundOutcome
  roundIndex: number
  wins: StadiumWins
  winRounds?: number
}) {
  const roundExperienceMode: StadiumExperienceMode = outcome === 'loss'
    ? 'pvp-stadium-round-loss-tenth-level'
    : 'pvp-stadium-round-win-quarter-level'
  const logTone = outcome === 'loss' ? 'danger' as const : 'loot' as const
  const nextWins = {
    player: wins.player + (outcome === 'win' ? 1 : 0),
    opponent: wins.opponent + (outcome === 'loss' ? 1 : 0),
  }
  const status: StadiumRoundStatus = nextWins.player >= winRounds
    ? 'won'
    : nextWins.opponent >= winRounds
      ? 'lost'
      : 'shop'

  return {
    nextWins,
    status,
    playerRoundStatus: status,
    roundExperience: {
      key: `round-${roundIndex}-${outcome}`,
      mode: roundExperienceMode,
    },
    matchExperience: status === 'won'
      ? { key: 'match-win', mode: 'pvp-stadium-match-half-level' as StadiumExperienceMode }
      : null,
    log: {
      text: outcome === 'win'
        ? `Round ${roundIndex} won.`
        : outcome === 'loss'
          ? `Round ${roundIndex} lost.`
          : `Round ${roundIndex} tied.`,
      tone: logTone,
    },
  }
}

export function chooseStadiumCpuPurchases<TId extends string, TBuff extends { id: TId; cost: number }>(
  catalog: readonly TBuff[],
  points: number,
  random = Math.random,
) {
  let remaining = points
  const purchases: TId[] = []
  while (remaining > 0) {
    const affordable = catalog.filter((buff) => buff.cost <= remaining)
    if (affordable.length === 0) break
    const selected = affordable[Math.floor(random() * affordable.length)]
    purchases.push(selected.id)
    remaining -= selected.cost
  }
  return purchases
}
