import type { PartyMember } from '../game'
import type { PvpMatchSnapshot, PvpMatchSide } from '../pvpRoguelike'
import { resetParty } from './rules'
import type { StadiumRoundOutcome, StadiumWins } from './stadiumLifecycle'

export type StadiumSetupSide<TBuff extends string> = {
  party: PartyMember[]
  resource: number
  cooldowns: Record<string, number>
  buffs: TBuff[]
  castsTowardFree: number
  freeCastReady: boolean
  survivalSeconds: number
  dampeningPercent: number
  roundIndex: number
  roundWins: number
  roundStatus: 'playing' | 'shop' | 'won' | 'lost'
  lastRoundOutcome?: StadiumRoundOutcome
  shopReady: boolean
}

export type StadiumLiveMatchSetup = {
  id: string
  side: PvpMatchSide
  opponentSide: PvpMatchSide
  opponentName: string
  opponentClassName: string
}

export function createStadiumStarterSide<TBuff extends string>({
  partyTemplate,
  maxResource,
  roundIndex,
  buffs = [],
  roundWins = 0,
}: {
  partyTemplate: readonly PartyMember[]
  maxResource: number
  roundIndex: number
  buffs?: TBuff[]
  roundWins?: number
}): StadiumSetupSide<TBuff> {
  return {
    party: resetParty([...partyTemplate]),
    resource: maxResource,
    cooldowns: {},
    buffs,
    castsTowardFree: 0,
    freeCastReady: false,
    survivalSeconds: 0,
    dampeningPercent: 0,
    roundIndex,
    roundWins,
    roundStatus: 'playing',
    shopReady: false,
  }
}

export function createStadiumMatchStart<TBuff extends string>({
  partyTemplate,
  opponentPartyTemplate,
  maxResource,
}: {
  partyTemplate: readonly PartyMember[]
  opponentPartyTemplate: readonly PartyMember[]
  maxResource: number
}) {
  const roundIndex = 1
  return {
    playerSide: createStadiumStarterSide<TBuff>({ partyTemplate, maxResource, roundIndex }),
    opponentSide: createStadiumStarterSide<TBuff>({ partyTemplate: opponentPartyTemplate, maxResource, roundIndex }),
    defaults: {
      roundIndex,
      roundWins: { player: 0, opponent: 0 } satisfies StadiumWins,
      elapsedTicks: 0,
      shopPoints: 0,
      shopReady: false,
      paused: false,
      rewardError: '',
      showEndLog: false,
    },
  }
}

export function createStadiumLiveMatchStart<TBuff extends string>({
  match,
  side,
  partyTemplate,
  opponentPartyTemplate,
  maxResource,
  message,
}: {
  match: PvpMatchSnapshot<StadiumSetupSide<TBuff>>
  side: PvpMatchSide
  partyTemplate: readonly PartyMember[]
  opponentPartyTemplate: readonly PartyMember[]
  maxResource: number
  message?: string
}) {
  const opponentSideId: PvpMatchSide = side === 'a' ? 'b' : 'a'
  const opponent = match.players[opponentSideId]
  const opponentTemplate = opponentPartyTemplate.map((member) => ({
    ...member,
    name: member.id === 'mira' ? opponent.characterName : member.name,
  }))
  const setup = createStadiumMatchStart<TBuff>({
    partyTemplate,
    opponentPartyTemplate: opponentTemplate,
    maxResource,
  })
  const liveMatch: StadiumLiveMatchSetup = {
    id: match.id,
    side,
    opponentSide: opponentSideId,
    opponentName: opponent.characterName,
    opponentClassName: opponent.className,
  }

  return {
    ...setup,
    liveMatch,
    logText: message ?? `${opponent.characterName} found. Stadium begins.`,
  }
}
