export type GameClass = {
  id: number
  slug: string
  name: string
  resourceName: string
  maxResource: number
  themeColor: string
  description: string
  spells: Ability[]
  talents: Talent[]
}

export type Ability = {
  id: number
  classId: number
  slug: string
  name: string
  spellType: string
  cost: number
  cooldown: number
  power: number
  unlockLevel: number
  glyph: string
  description: string
}

export type Talent = {
  id: number
  classId: number
  slug: string
  name: string
  maxRank: number
  tier: number
  branch: number
  prerequisiteTalentId: number | null
  prerequisiteRank: number
  prerequisiteName: string | null
  effectType: string
  effectValuePerRank: number
  glyph: string
  description: string
  rank: number
}

export type EquipmentSlot =
  | 'weapon'
  | 'helmet'
  | 'chest'
  | 'gloves'
  | 'boots'
  | 'pants'
  | 'ring'
  | 'necklace'
  | 'trinket'
  | 'component'

export type Item = {
  id: number
  slug: string
  name: string
  slot: EquipmentSlot
  rarity: 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary'
  itemLevel: number
  healingPower: number
  maxResourceBonus: number
  glyph: string
  description: string
  setId?: number | null
  setSlug?: string | null
  setName?: string | null
  quantity: number
  equipped: boolean
}

export type SetBonus = {
  setId: number
  setSlug: string
  setName: string
  requiredPieces: number
  effectType: 'mend_extra_target' | 'renew_extra_target' | 'mend_applies_renew' | string
  description: string
  equippedPieces: number
  active: boolean
}

export type Difficulty = {
  dungeonId: number
  id: number
  slug: string
  name: string
  droppedItemLevel: number
  unlockLevel: number
  healthMultiplier: number
  damageMultiplier: number
  experienceMultiplier: number
  description: string
}

export type DungeonEncounter = {
  id: number
  dungeonId: number
  sequence: number
  slug: string
  enemyName: string
  encounterType: 'trash' | 'boss'
  maxHealth: number
  damage: number
  tankDamage: number
  partyDamage: number
  description: string
  imageUrl: string
  isBoss: boolean
  lootTables: LootTableEntry[]
}

export type LootTableEntry = Omit<Item, 'quantity' | 'equipped'> & {
  encounterId: number
  difficultyId: number
  dropWeight: number
  dropChance: number
}

export type CraftingRecipe = {
  id: number
  difficultyId: number | null
  sourceDungeonId: number | null
  sourceEncounterId: number | null
  item: Omit<Item, 'quantity' | 'equipped'>
  components: Array<{
    item: Omit<Item, 'quantity' | 'equipped'>
    quantity: number
    owned: number
  }>
  canCraft: boolean
}

export type GearUpgradePath = {
  fromItemId: number
  toItemId: number
}

export type LootRollItem = Omit<Item, 'quantity' | 'equipped'> & {
  quantity: number
  duplicate: boolean
  quantityAfter: number
}

export type PetAward = {
  encounterId: number
  petName: string
  quantity: number
  duplicate: boolean
  quantityAfter: number
}

export type LootRoll = {
  encounterId: number
  encounterName: string
  difficultyId: number
  difficultyName: string
  dropChance: number
  dropped: boolean
  item: LootRollItem | null
  items: LootRollItem[]
  awarded: boolean
  duplicate: boolean
  quantityAfter: number
  petAwarded?: PetAward | null
}

export type Dungeon = {
  id: number
  slug: string
  name: string
  recommendedLevel: number
  contentType: 'dungeon' | 'raid'
  partySize: number
  completionItemLevel: number | null
  experienceReward: number
  imageUrl: string
  description: string
  locationName: string
  difficulties: Difficulty[]
  encounters: DungeonEncounter[]
  completionLoot: Array<Omit<Item, 'quantity' | 'equipped'>>
  completionCount?: number
  leaderboard: LeaderboardEntry[]
  leaderboards: {
    part_1: LeaderboardEntry[]
    part_2: LeaderboardEntry[]
    part_3: LeaderboardEntry[]
    full_run: LeaderboardEntry[]
  }
}

export type LeaderboardEntry = {
  rank: number
  dungeonId: number
  difficultyId: number
  characterName: string
  className: string
  characterLevel: number
  averageItemLevel: number
  resourceSpent: number
  durationSeconds: number
  completedAt: string
}

export type CharacterProfile = {
  character: {
    id: number
    name: string
    level: number
    experience: number
    currentLevelExperience: number
    nextLevelExperience: number
    talentPoints: number
    classId: number
    classSlug: string
    className: string
    resourceName: string
    maxResource: number
    themeColor: string
    classDescription: string
  }
  classes: GameClass[]
  abilitySlots: Array<number | null>
  maxLevel: number
  maxTalentPoints: number
  allocatedTalentPoints: number
  equipmentSlots: EquipmentSlot[]
  inventory: Item[]
  completedDungeonParts: number
  completedRaidPhases: number
  gearStats: {
    averageItemLevel: number
    healingPower: number
    maxResourceBonus: number
  }
  setBonuses: SetBonus[]
  craftingRecipes: CraftingRecipe[]
  gearUpgradePaths: GearUpgradePath[]
  dungeons: Dungeon[]
  hunterStats: {
    bossKills: Record<string, number>
    bossPets: Record<string, number>
    pvpMatchesPlayed: number
    pvpMatchesWon: number
  }
}

export type Account = {
  id: number
  username: string
}

export type AuthSession = {
  account: Account | null
  profile: CharacterProfile | null
  token?: string
}

export type BonusItem = {
  id: number
  slug: string
  name: string
  slot: string
  rarity: string
  itemLevel: number
  healingPower: number
  maxResourceBonus: number
  glyph: string
  description: string
  quantity: number
  duplicate: boolean
  quantityAfter: number
}

export type DungeonReward = {
  dungeonName: string
  difficultyName: string
  droppedItemLevel: number
  experienceGained: number
  previousLevel: number
  newLevel: number
  levelsGained: number
  talentPointsGained: number
  resourceSpent: number
  durationSeconds: number
  averageItemLevel: number
  unlockedAbilities: Array<{
    id: number
    name: string
    unlockLevel: number
    glyph: string
  }>
  bonusItem: BonusItem | null
  petAwarded?: PetAward | null
  profile: CharacterProfile
}

import { activeGameRepository } from './gameRepository'

export function loadAuthSession(): Promise<AuthSession> {
  return activeGameRepository().loadSession()
}

export function registerAccount(
  username: string,
  password: string,
  characterName: string,
): Promise<AuthSession> {
  return activeGameRepository().register(username, password, characterName)
}

export function loginAccount(
  username: string,
  password: string,
): Promise<AuthSession> {
  return activeGameRepository().login(username, password)
}

export async function logoutAccount(): Promise<void> {
  await activeGameRepository().logout()
}

export async function loadProfile(): Promise<CharacterProfile> {
  return activeGameRepository().loadProfile()
}

export async function saveProfile(
  classId: number,
  abilitySlots: Array<number | null>,
): Promise<CharacterProfile> {
  return activeGameRepository().saveProfile(classId, abilitySlots)
}

export async function completeDungeon(
  dungeonId: number,
  difficultyId: number,
  resourceSpent: number,
  durationSeconds: number,
  completedPart?: number,
  startPart?: number,
  partDurationSeconds?: [number, number, number],
  hardMode?: boolean,
): Promise<DungeonReward> {
  return activeGameRepository().completeDungeon(
    dungeonId,
    difficultyId,
    resourceSpent,
    durationSeconds,
    completedPart,
    startPart,
    partDurationSeconds,
    hardMode,
  )
}

export async function completeRoguelike(
  dungeonId: number,
  difficultyId: number,
  encountersCleared: number,
  resourceSpent: number,
  durationSeconds: number,
  options?: {
    bossesCleared?: number
    experienceMode?: 'default' | 'pvp-boss-quarter-level' | 'pvp-fight-twelfth-level' | 'pvp-match-win-half-level' | 'pvp-stadium-round-win-quarter-level' | 'pvp-stadium-round-loss-tenth-level' | 'pvp-stadium-match-half-level'
    fightsCleared?: number
    lootSourceEncounterId?: number
    roguelikeStage?: number
  },
): Promise<DungeonReward> {
  return activeGameRepository().completeRoguelike(
    dungeonId,
    difficultyId,
    encountersCleared,
    resourceSpent,
    durationSeconds,
    options,
  )
}

export async function recordBossKill(
  encounterId: number,
  options?: { petVariant?: 'normal' | 'purple' },
): Promise<{
  profile: CharacterProfile
  petAwarded: PetAward | null
}> {
  return activeGameRepository().recordBossKill(encounterId, options)
}

export async function recordPvpMatch(won: boolean): Promise<CharacterProfile> {
  return activeGameRepository().recordPvpMatch(won)
}

export async function allocateTalent(talentId: number): Promise<CharacterProfile> {
  return activeGameRepository().allocateTalent(talentId)
}

export async function resetTalents(): Promise<CharacterProfile> {
  return activeGameRepository().resetTalents()
}

export async function equipItem(itemId: number): Promise<CharacterProfile> {
  return activeGameRepository().equipItem(itemId)
}

export async function discardExtraItem(itemId: number): Promise<CharacterProfile> {
  return activeGameRepository().discardExtraItem(itemId)
}

export async function breakdownItem(itemId: number): Promise<CharacterProfile> {
  return activeGameRepository().breakdownItem(itemId)
}

export async function craftItem(recipeId: number): Promise<CharacterProfile> {
  return activeGameRepository().craftItem(recipeId)
}

export async function upgradeItem(itemId: number): Promise<CharacterProfile> {
  return activeGameRepository().upgradeItem(itemId)
}

export async function rollEncounterLoot(
  encounterId: number,
  difficultyId: number,
  runToken: string,
): Promise<LootRoll> {
  return activeGameRepository().rollEncounterLoot(
    encounterId,
    difficultyId,
    runToken,
  )
}
