import type { DungeonReward } from '../profile'

export type RewardSummaryBase = {
  experienceGained: number
  previousLevel: number | null
  newLevel: number | null
  levelsGained: number
  talentPointsGained: number
  unlockedAbilities: DungeonReward['unlockedAbilities']
}

export type PvpRunRewardSummary = RewardSummaryBase & {
  bossesKilled: number
  loot: Array<NonNullable<DungeonReward['bonusItem']>>
}

export function createEmptyRewardSummary(): RewardSummaryBase {
  return {
    experienceGained: 0,
    previousLevel: null,
    newLevel: null,
    levelsGained: 0,
    talentPointsGained: 0,
    unlockedAbilities: [],
  }
}

export function createEmptyPvpRunSummary(): PvpRunRewardSummary {
  return {
    bossesKilled: 0,
    ...createEmptyRewardSummary(),
    loot: [],
  }
}

export function mergeUnlockedAbilities(
  current: DungeonReward['unlockedAbilities'],
  next: DungeonReward['unlockedAbilities'],
) {
  const unlockedById = new Map(current.map((ability) => [ability.id, ability]))
  next.forEach((ability) => unlockedById.set(ability.id, ability))
  return Array.from(unlockedById.values())
}

export function mergeDungeonRewardSummary<TSummary extends RewardSummaryBase>(
  current: TSummary,
  reward: DungeonReward,
) {
  return {
    ...current,
    experienceGained: current.experienceGained + reward.experienceGained,
    previousLevel: current.previousLevel ?? reward.previousLevel,
    newLevel: reward.newLevel,
    levelsGained: current.levelsGained + reward.levelsGained,
    talentPointsGained: current.talentPointsGained + reward.talentPointsGained,
    unlockedAbilities: mergeUnlockedAbilities(current.unlockedAbilities, reward.unlockedAbilities),
  }
}

export function mergePvpRunRewardSummary(
  current: PvpRunRewardSummary,
  reward: DungeonReward,
  { bossKilled }: { bossKilled: boolean },
) {
  return {
    ...mergeDungeonRewardSummary(current, reward),
    bossesKilled: current.bossesKilled + (bossKilled ? 1 : 0),
    loot: reward.bonusItem ? [...current.loot, reward.bonusItem] : current.loot,
  }
}
