export type PvpRoguelikeStatus = 'queueing' | 'round-countdown' | 'playing' | 'upgrade-choice' | 'won' | 'lost'
export type PvpRoguelikeLogTone = 'system' | 'heal' | 'danger' | 'loot'

export type PvpRoguelikeCombatOutcome =
  | {
    type: 'none'
  }
  | {
    type: 'lost'
    status: 'lost'
    log: { text: string; tone: PvpRoguelikeLogTone }
  }
  | {
    type: 'won'
    status: 'won'
    markOpponentDefeated: boolean
    log: { text: string; tone: PvpRoguelikeLogTone }
  }
  | {
    type: 'upgrade-choice'
    status: 'upgrade-choice'
    log: { text: string; tone: PvpRoguelikeLogTone }
  }

export function resolvePvpRoguelikeCombatOutcome({
  playerAlive,
  opponentAlive,
  playerCleared,
  encounterIsBoss,
  encounterName,
  opponentDefeated,
  liveMatchActive,
  opponentLabel,
}: {
  playerAlive: boolean
  opponentAlive: boolean
  playerCleared: boolean
  encounterIsBoss: boolean
  encounterName: string
  opponentDefeated: boolean
  liveMatchActive: boolean
  opponentLabel: string
}): PvpRoguelikeCombatOutcome {
  if (!playerAlive) {
    return {
      type: 'lost',
      status: 'lost',
      log: { text: 'Your party fell first.', tone: 'danger' },
    }
  }
  if (!liveMatchActive && !opponentAlive && !opponentDefeated) {
    return {
      type: 'won',
      status: 'won',
      markOpponentDefeated: true,
      log: { text: `${opponentLabel} fell. Match complete.`, tone: 'loot' },
    }
  }
  if (!playerCleared) return { type: 'none' }
  if (encounterIsBoss && opponentDefeated) {
    return {
      type: 'won',
      status: 'won',
      markOpponentDefeated: false,
      log: { text: `${opponentLabel} defeated. Match complete.`, tone: 'loot' },
    }
  }
  return {
    type: 'upgrade-choice',
    status: 'upgrade-choice',
    log: { text: `${encounterName} cleared. Choose your next edge.`, tone: 'loot' },
  }
}

export function resolvePvpRoguelikeLiveSnapshot({
  currentStatus,
  opponentStatus,
  opponentAlive,
  alreadyLoggedOpponentDone,
  opponentName,
}: {
  currentStatus: PvpRoguelikeStatus
  opponentStatus?: string
  opponentAlive?: boolean
  alreadyLoggedOpponentDone: boolean
  opponentName: string
}) {
  if (currentStatus === 'won' || currentStatus === 'lost') return { type: 'none' as const }
  if ((opponentStatus === 'lost' || opponentAlive === false) && !alreadyLoggedOpponentDone) {
    return {
      type: 'won' as const,
      status: 'won' as const,
      markOpponentDefeated: true,
      log: { text: `${opponentName} fell. Match complete.`, tone: 'loot' as const },
    }
  }
  if (opponentStatus === 'won') {
    return {
      type: 'lost' as const,
      status: 'lost' as const,
      log: { text: `${opponentName} finished first.`, tone: 'danger' as const },
    }
  }
  return { type: 'none' as const }
}

export function resolvePvpRoguelikeUpgradeCompletion({
  clearedBoss,
  opponentDefeated,
  opponentLabel,
}: {
  clearedBoss: boolean
  opponentDefeated: boolean
  opponentLabel: string
}) {
  if (!clearedBoss || !opponentDefeated) return { type: 'none' as const }
  return {
    type: 'won' as const,
    status: 'won' as const,
    log: { text: `${opponentLabel} defeated. Match complete.`, tone: 'loot' as const },
  }
}

export function nextPvpRoguelikeStage<TEncounter>({
  clearedBoss,
  stage,
  encounterIndex,
  encounters,
  nextSegment,
}: {
  clearedBoss: boolean
  stage: number
  encounterIndex: number
  encounters: readonly TEncounter[]
  nextSegment: readonly TEncounter[]
}) {
  const nextStage = clearedBoss ? stage + 1 : stage
  const nextEncounter = clearedBoss ? nextSegment[0] : encounters[encounterIndex + 1]
  if (!nextEncounter) {
    return {
      type: 'complete' as const,
      status: 'won' as const,
      log: { text: 'No further encounters remain.', tone: 'loot' as const },
    }
  }
  return {
    type: 'next' as const,
    nextStage,
    nextEncounter,
    nextEncounterIndex: encounterIndex + 1,
    appendSegment: clearedBoss,
  }
}
