import type { PartyRole } from './actionCombatCore'

export type ArenaClassId =
  | 'priest'
  | 'knight'
  | 'ranger'
  | 'mage'
  | 'rogue'
  | 'warrior'
  | 'paladin'
  | 'druid'
  | 'shaman'
  | 'priest_holy'
  | 'priest_discipline'
  | 'priest_shadow'
  | 'warrior_protection'
  | 'warrior_arms'
  | 'warrior_fury'
  | 'paladin_protection'
  | 'paladin_holy'
  | 'paladin_retribution'
  | 'druid_restoration'
  | 'druid_feral_tank'
  | 'druid_feral_cat'
  | 'druid_balance'
  | 'mage_arcane'
  | 'mage_fire'
  | 'mage_frost'
  | 'rogue_assassination'
  | 'rogue_combat'
  | 'rogue_subtlety'
  | 'hunter_beast_mastery'
  | 'hunter_marksmanship'
  | 'hunter_survival'
  | 'shaman_restoration'
  | 'shaman_elemental'
  | 'shaman_enhancement'
  | 'warlock_affliction'
  | 'warlock_demonology'
  | 'warlock_destruction'

export type ArenaAbilitySchool = 'arcane' | 'fire' | 'frost' | 'holy' | 'nature' | 'physical' | 'shadow'

export type ArenaAbilityId = string

export type ArenaAbilityKind = 'attack' | 'buff' | 'damage' | 'heal' | 'shield'

export type ArenaAbilityDefinition = {
  animation: 'block' | 'dual' | 'melee' | 'ranged' | 'spell'
  castTime: number
  cooldown: number
  damage?: number
  dot?: {
    damage: number
    seconds: number
  }
  heal?: number
  id: ArenaAbilityId
  kind: ArenaAbilityKind
  name: string
  range: number
  school: ArenaAbilitySchool
  shield?: number
}

export type ArenaClassKit = {
  actionBar: ArenaAbilityId[]
  attackSeconds: number
  basicAttack: ArenaAbilityId
  defaultPvpSpec: string
  displayName: string
  id: ArenaClassId
  model: string
  role: PartyRole
  weapons: Array<{ hand: 'handslot.l' | 'handslot.r'; model: string }>
}

const ROOT = '/action-assets/models/claudecraft'

export const ARENA_PVP_EFFECTIVE_LEVEL = 20
export const ARENA_PVP_DEFAULT_TALENT_POINTS = ARENA_PVP_EFFECTIVE_LEVEL - 9

export type ArenaClassVitalsTemplate = {
  baseHp: number
  baseMana: number
  baseStats: { int: number, sta: number }
  hpPerLevel: number
  manaPerLevel: number
  resourceType: 'energy' | 'mana' | 'rage'
  statsPerLevel: { int: number, sta: number }
}

const ARENA_PVP_GEAR_STATS: Partial<Record<ArenaClassId, { int: number, sta: number }>> = {
  druid: { int: 12, sta: 10 },
  knight: { int: 0, sta: 16 },
  mage: { int: 12, sta: 8 },
  paladin: { int: 8, sta: 15 },
  priest: { int: 12, sta: 8 },
  ranger: { int: 5, sta: 10 },
  rogue: { int: 0, sta: 9 },
  shaman: { int: 11, sta: 11 },
  warrior: { int: 0, sta: 17 },
}

const ARENA_CLASS_VITALS: Partial<Record<ArenaClassId, ArenaClassVitalsTemplate>> = {
  knight: {
    baseHp: 50,
    baseMana: 100,
    baseStats: { int: 10, sta: 22 },
    hpPerLevel: 18,
    manaPerLevel: 0,
    resourceType: 'rage',
    statsPerLevel: { int: 0, sta: 2 },
  },
  mage: {
    baseHp: 40,
    baseMana: 100,
    baseStats: { int: 24, sta: 14 },
    hpPerLevel: 12,
    manaPerLevel: 24,
    resourceType: 'mana',
    statsPerLevel: { int: 3, sta: 1 },
  },
  paladin: {
    baseHp: 52,
    baseMana: 90,
    baseStats: { int: 16, sta: 21 },
    hpPerLevel: 17,
    manaPerLevel: 14,
    resourceType: 'mana',
    statsPerLevel: { int: 1, sta: 2 },
  },
  priest: {
    baseHp: 38,
    baseMana: 110,
    baseStats: { int: 22, sta: 13 },
    hpPerLevel: 11,
    manaPerLevel: 26,
    resourceType: 'mana',
    statsPerLevel: { int: 2, sta: 1 },
  },
  druid: {
    baseHp: 44,
    baseMana: 115,
    baseStats: { int: 21, sta: 16 },
    hpPerLevel: 12,
    manaPerLevel: 24,
    resourceType: 'mana',
    statsPerLevel: { int: 2, sta: 1 },
  },
  shaman: {
    baseHp: 47,
    baseMana: 105,
    baseStats: { int: 20, sta: 17 },
    hpPerLevel: 13,
    manaPerLevel: 22,
    resourceType: 'mana',
    statsPerLevel: { int: 2, sta: 1 },
  },
  ranger: {
    baseHp: 50,
    baseMana: 80,
    baseStats: { int: 13, sta: 19 },
    hpPerLevel: 15,
    manaPerLevel: 18,
    resourceType: 'mana',
    statsPerLevel: { int: 1, sta: 2 },
  },
  rogue: {
    baseHp: 45,
    baseMana: 100,
    baseStats: { int: 11, sta: 17 },
    hpPerLevel: 15,
    manaPerLevel: 0,
    resourceType: 'energy',
    statsPerLevel: { int: 0, sta: 1 },
  },
  warrior: {
    baseHp: 54,
    baseMana: 100,
    baseStats: { int: 10, sta: 23 },
    hpPerLevel: 19,
    manaPerLevel: 0,
    resourceType: 'rage',
    statsPerLevel: { int: 0, sta: 2 },
  },
}

export function getArenaClassVitals(classId: ArenaClassId, level: number = ARENA_PVP_EFFECTIVE_LEVEL) {
  const template = ARENA_CLASS_VITALS[classId] ?? getArenaFallbackVitals(classId)
  const gear = ARENA_PVP_GEAR_STATS[classId] ?? getArenaFallbackGear(classId)
  const stamina = template.baseStats.sta + template.statsPerLevel.sta * (level - 1) + gear.sta
  const intellect = template.baseStats.int + template.statsPerLevel.int * (level - 1) + gear.int
  const maxHp = template.baseHp + template.hpPerLevel * (level - 1) + statResourceFromPrimary(stamina, 10)
  const maxMana = template.resourceType === 'mana'
    ? template.baseMana + template.manaPerLevel * (level - 1) + statResourceFromPrimary(intellect, 15)
    : 100
  return { maxHp, maxMana, resourceType: template.resourceType }
}

function getArenaFallbackVitals(classId: ArenaClassId): ArenaClassVitalsTemplate {
  const kit = getArenaClassKit(classId)
  if (kit.role === 'tank') {
    return {
      baseHp: 52,
      baseMana: 95,
      baseStats: { int: 12, sta: 22 },
      hpPerLevel: 18,
      manaPerLevel: classId.includes('paladin') ? 14 : 0,
      resourceType: classId.includes('paladin') ? 'mana' : classId.includes('druid') ? 'rage' : 'rage',
      statsPerLevel: { int: classId.includes('paladin') ? 1 : 0, sta: 2 },
    }
  }
  if (kit.role === 'healer') {
    return {
      baseHp: 42,
      baseMana: 110,
      baseStats: { int: 22, sta: 15 },
      hpPerLevel: 12,
      manaPerLevel: 24,
      resourceType: 'mana',
      statsPerLevel: { int: 2, sta: 1 },
    }
  }
  if (kit.role === 'melee') {
    return {
      baseHp: 46,
      baseMana: 100,
      baseStats: { int: 11, sta: 18 },
      hpPerLevel: 15,
      manaPerLevel: classId.includes('paladin') || classId.includes('shaman') ? 16 : 0,
      resourceType: classId.includes('paladin') || classId.includes('shaman') ? 'mana' : classId.includes('rogue') || classId.includes('druid_feral_cat') ? 'energy' : 'rage',
      statsPerLevel: { int: classId.includes('paladin') || classId.includes('shaman') ? 1 : 0, sta: 1 },
    }
  }
  return {
    baseHp: 40,
    baseMana: 100,
    baseStats: { int: 22, sta: 14 },
    hpPerLevel: 12,
    manaPerLevel: 22,
    resourceType: 'mana',
    statsPerLevel: { int: 2, sta: 1 },
  }
}

function getArenaFallbackGear(classId: ArenaClassId) {
  const kit = getArenaClassKit(classId)
  if (kit.role === 'tank') return { int: classId.includes('paladin') ? 8 : 0, sta: 16 }
  if (kit.role === 'healer') return { int: 12, sta: 9 }
  if (kit.role === 'melee') return { int: classId.includes('paladin') || classId.includes('shaman') ? 7 : 0, sta: 10 }
  return { int: 11, sta: 8 }
}

function statResourceFromPrimary(value: number, overTwentyMultiplier: number) {
  const stat = Math.max(0, value)
  return Math.min(stat, 20) + Math.max(0, stat - 20) * overTwentyMultiplier
}

export const ARENA_ABILITIES: Record<ArenaAbilityId, ArenaAbilityDefinition> = {
  aimed_shot: ability('aimed_shot', 'Aimed Shot', 'damage', 'physical', 'ranged', 3, 6, 312, { damage: 56 }),
  arcane_explosion: ability('arcane_explosion', 'Arcane Explosion', 'damage', 'arcane', 'spell', 0, 8, 120, { damage: 44 }),
  arcane_intellect: ability('arcane_intellect', 'Arcane Intellect', 'buff', 'arcane', 'spell', 0, 0, 288),
  arcane_missiles: ability('arcane_missiles', 'Arcane Missiles', 'damage', 'arcane', 'spell', 0, 0, 288, { damage: 66 }),
  arcane_shot: ability('arcane_shot', 'Arcane Shot', 'damage', 'arcane', 'ranged', 0, 6, 336, { damage: 43 }),
  ambush: ability('ambush', 'Ambush', 'attack', 'physical', 'dual', 0, 0, 58, { damage: 92 }),
  aspect_of_the_hawk: ability('aspect_of_the_hawk', 'Aspect of the Hawk', 'buff', 'physical', 'ranged', 0, 0, 0),
  backstab: ability('backstab', 'Backstab', 'attack', 'physical', 'dual', 0, 0, 58, { damage: 74 }),
  barkskin: ability('barkskin', 'Barkskin', 'shield', 'nature', 'spell', 0, 12, 0, { shield: 90 }),
  bear_charge: ability('bear_charge', 'Bear Charge', 'damage', 'physical', 'melee', 0, 15, 230, { damage: 8 }),
  blessing_of_might: ability('blessing_of_might', 'Blessing of Might', 'buff', 'holy', 'spell', 0, 0, 288),
  bloodthirst: ability('bloodthirst', 'Bloodthirst', 'attack', 'physical', 'melee', 0, 4, 58, { damage: 72 }),
  charge: ability('charge', 'Charge', 'damage', 'physical', 'melee', 0, 15, 230, { damage: 8 }),
  claw: ability('claw', 'Claw', 'attack', 'physical', 'dual', 0, 0, 58, { damage: 48 }),
  cleave: ability('cleave', 'Cleave', 'attack', 'physical', 'melee', 0, 4, 86, { damage: 58 }),
  concussive_shot: ability('concussive_shot', 'Concussive Shot', 'damage', 'physical', 'ranged', 0, 12, 336, { damage: 5 }),
  consecration: ability('consecration', 'Consecration', 'damage', 'holy', 'spell', 0, 8, 96, { damage: 44 }),
  corruption: ability('corruption', 'Corruption', 'damage', 'shadow', 'spell', 0, 0, 288, { damage: 0, dot: { damage: 78, seconds: 18 } }),
  curse_of_agony: ability('curse_of_agony', 'Curse of Agony', 'damage', 'shadow', 'spell', 0, 0, 288, { damage: 0, dot: { damage: 86, seconds: 24 } }),
  demon_skin: ability('demon_skin', 'Demon Skin', 'shield', 'shadow', 'spell', 0, 20, 0, { shield: 80 }),
  demoralizing_roar: ability('demoralizing_roar', 'Demoralizing Roar', 'buff', 'physical', 'melee', 0, 10, 96),
  divine_protection: ability('divine_protection', 'Divine Protection', 'shield', 'holy', 'spell', 0, 30, 0, { shield: 130 }),
  drain_life: ability('drain_life', 'Drain Life', 'damage', 'shadow', 'spell', 0, 0, 240, { damage: 52, heal: 35 }),
  earth_shock: ability('earth_shock', 'Earth Shock', 'damage', 'nature', 'spell', 0, 6, 240, { damage: 62 }),
  eviscerate: ability('eviscerate', 'Eviscerate', 'attack', 'physical', 'dual', 0, 0, 58, { damage: 104 }),
  exorcism: ability('exorcism', 'Exorcism', 'damage', 'holy', 'spell', 0, 15, 240, { damage: 70 }),
  faerie_fire: ability('faerie_fire', 'Faerie Fire', 'damage', 'nature', 'spell', 0, 6, 288, { damage: 18 }),
  fear: ability('fear', 'Fear', 'buff', 'shadow', 'spell', 0, 20, 240),
  ferocious_bite: ability('ferocious_bite', 'Ferocious Bite', 'attack', 'physical', 'dual', 0, 0, 58, { damage: 94 }),
  fire_blast: ability('fire_blast', 'Fire Blast', 'damage', 'fire', 'spell', 0, 8, 240, { damage: 75 }),
  fireball: ability('fireball', 'Fireball', 'damage', 'fire', 'spell', 3, 0, 288, { damage: 68, dot: { damage: 12, seconds: 8 } }),
  flame_shock: ability('flame_shock', 'Flame Shock', 'damage', 'fire', 'spell', 0, 6, 240, { damage: 24, dot: { damage: 52, seconds: 12 } }),
  flash_heal: ability('flash_heal', 'Flash Heal', 'heal', 'holy', 'spell', 1.5, 0, 288, { heal: 131 }),
  flash_of_light: ability('flash_of_light', 'Flash of Light', 'heal', 'holy', 'spell', 1.5, 0, 288, { heal: 126 }),
  frost_shock: ability('frost_shock', 'Frost Shock', 'damage', 'frost', 'spell', 0, 6, 240, { damage: 56 }),
  frost_nova: ability('frost_nova', 'Frost Nova', 'damage', 'frost', 'spell', 0, 22, 110, { damage: 7 }),
  frostbolt: ability('frostbolt', 'Frostbolt', 'damage', 'frost', 'spell', 2.5, 0, 288, { damage: 70 }),
  gouge: ability('gouge', 'Gouge', 'attack', 'physical', 'dual', 0, 10, 58, { damage: 26 }),
  growl: ability('growl', 'Growl', 'buff', 'physical', 'block', 0, 10, 92),
  heal: ability('heal', 'Heal', 'heal', 'holy', 'spell', 2.5, 0, 288, { heal: 250 }),
  healing_touch: ability('healing_touch', 'Healing Touch', 'heal', 'nature', 'spell', 2.5, 0, 288, { heal: 248 }),
  healing_wave: ability('healing_wave', 'Healing Wave', 'heal', 'nature', 'spell', 2.5, 0, 288, { heal: 238 }),
  heroic_strike: ability('heroic_strike', 'Heroic Strike', 'attack', 'physical', 'melee', 0, 0, 58, { damage: 74 }),
  holy_light: ability('holy_light', 'Holy Light', 'heal', 'holy', 'spell', 2.5, 0, 288, { heal: 245 }),
  ice_barrier: ability('ice_barrier', 'Ice Barrier', 'shield', 'frost', 'spell', 0, 20, 0, { shield: 115 }),
  immolate: ability('immolate', 'Immolate', 'damage', 'fire', 'spell', 2, 0, 288, { damage: 44, dot: { damage: 44, seconds: 12 } }),
  insect_swarm: ability('insect_swarm', 'Insect Swarm', 'damage', 'nature', 'spell', 0, 0, 288, { damage: 0, dot: { damage: 70, seconds: 12 } }),
  judgement: ability('judgement', 'Judgement', 'damage', 'holy', 'spell', 0, 8, 240, { damage: 64 }),
  lay_on_hands: ability('lay_on_hands', 'Lay on Hands', 'heal', 'holy', 'spell', 0, 60, 288, { heal: 360 }),
  lesser_heal: ability('lesser_heal', 'Lesser Heal', 'heal', 'holy', 'spell', 2, 0, 288, { heal: 121 }),
  lightning_bolt: ability('lightning_bolt', 'Lightning Bolt', 'damage', 'nature', 'spell', 2.5, 0, 288, { damage: 68 }),
  lightning_shield: ability('lightning_shield', 'Lightning Shield', 'shield', 'nature', 'spell', 0, 10, 0, { shield: 72 }),
  maul: ability('maul', 'Maul', 'attack', 'physical', 'melee', 0, 0, 58, { damage: 72 }),
  mind_blast: ability('mind_blast', 'Mind Blast', 'damage', 'shadow', 'spell', 1.5, 8, 288, { damage: 90 }),
  mind_flay: ability('mind_flay', 'Mind Flay', 'damage', 'shadow', 'spell', 0, 0, 220, { damage: 36 }),
  moonfire: ability('moonfire', 'Moonfire', 'damage', 'arcane', 'spell', 0, 0, 288, { damage: 32, dot: { damage: 50, seconds: 12 } }),
  mortal_strike: ability('mortal_strike', 'Mortal Strike', 'attack', 'physical', 'melee', 0, 6, 58, { damage: 88 }),
  overpower: ability('overpower', 'Overpower', 'attack', 'physical', 'melee', 0, 5, 58, { damage: 64 }),
  power_word_fortitude: ability('power_word_fortitude', 'Power Word: Fortitude', 'shield', 'holy', 'spell', 0, 0, 288, { shield: 120 }),
  power_word_shield: ability('power_word_shield', 'Power Word: Shield', 'shield', 'holy', 'spell', 0, 6, 288, { shield: 145 }),
  pyroblast: ability('pyroblast', 'Pyroblast', 'damage', 'fire', 'spell', 4, 12, 288, { damage: 105, dot: { damage: 30, seconds: 12 } }),
  rapid_fire: ability('rapid_fire', 'Rapid Fire', 'buff', 'physical', 'ranged', 0, 300, 0),
  raptor_strike: ability('raptor_strike', 'Raptor Strike', 'attack', 'physical', 'melee', 0, 0, 58, { damage: 64 }),
  rake: ability('rake', 'Rake', 'attack', 'physical', 'dual', 0, 0, 58, { damage: 34, dot: { damage: 48, seconds: 9 } }),
  regrowth: ability('regrowth', 'Regrowth', 'heal', 'nature', 'spell', 2, 0, 288, { heal: 145 }),
  rejuvenation: ability('rejuvenation', 'Rejuvenation', 'heal', 'nature', 'spell', 0, 0, 288, { heal: 32 }),
  rend: ability('rend', 'Rend', 'attack', 'physical', 'melee', 0, 0, 58, { damage: 18, dot: { damage: 52, seconds: 15 } }),
  rip: ability('rip', 'Rip', 'attack', 'physical', 'dual', 0, 0, 58, { damage: 0, dot: { damage: 88, seconds: 12 } }),
  renew: ability('renew', 'Renew', 'heal', 'holy', 'spell', 0, 0, 288, { heal: 28 }),
  righteous_fury: ability('righteous_fury', 'Righteous Fury', 'buff', 'holy', 'block', 0, 10, 0),
  rupture: ability('rupture', 'Rupture', 'attack', 'physical', 'dual', 0, 0, 58, { damage: 0, dot: { damage: 76, seconds: 12 } }),
  scorch: ability('scorch', 'Scorch', 'damage', 'fire', 'spell', 1.5, 0, 240, { damage: 54 }),
  searing_pain: ability('searing_pain', 'Searing Pain', 'damage', 'fire', 'spell', 1.5, 0, 240, { damage: 58 }),
  serpent_sting: ability('serpent_sting', 'Serpent Sting', 'damage', 'nature', 'ranged', 0, 0, 336, { damage: 0, dot: { damage: 55, seconds: 15 } }),
  seal_of_righteousness: ability('seal_of_righteousness', 'Seal of Righteousness', 'damage', 'holy', 'melee', 0, 0, 58, { damage: 56 }),
  shadow_word_pain: ability('shadow_word_pain', 'Shadow Word: Pain', 'damage', 'shadow', 'spell', 0, 0, 288, { damage: 0, dot: { damage: 84, seconds: 18 } }),
  shadow_bolt: ability('shadow_bolt', 'Shadow Bolt', 'damage', 'shadow', 'spell', 2.5, 0, 288, { damage: 76 }),
  shadowburn: ability('shadowburn', 'Shadowburn', 'damage', 'shadow', 'spell', 0, 15, 240, { damage: 92 }),
  shield_slam: ability('shield_slam', 'Shield Slam', 'attack', 'physical', 'block', 0, 6, 58, { damage: 66 }),
  slam: ability('slam', 'Slam', 'attack', 'physical', 'melee', 1.5, 0, 58, { damage: 78 }),
  sinister_strike: ability('sinister_strike', 'Sinister Strike', 'attack', 'physical', 'dual', 0, 0, 58, { damage: 42 }),
  smite: ability('smite', 'Smite', 'damage', 'holy', 'spell', 2.5, 0, 288, { damage: 71 }),
  starfire: ability('starfire', 'Starfire', 'damage', 'arcane', 'spell', 3, 0, 288, { damage: 82 }),
  stormstrike: ability('stormstrike', 'Stormstrike', 'attack', 'nature', 'melee', 0, 10, 58, { damage: 82 }),
  sunder_armor: ability('sunder_armor', 'Sunder Armor', 'attack', 'physical', 'melee', 0, 0, 58, { damage: 12 }),
  swipe: ability('swipe', 'Swipe', 'attack', 'physical', 'melee', 0, 5, 86, { damage: 42 }),
  taunt: ability('taunt', 'Taunt', 'buff', 'physical', 'block', 0, 10, 92),
  thunder_clap: ability('thunder_clap', 'Thunder Clap', 'damage', 'physical', 'melee', 0, 4, 96, { damage: 18 }),
  whirlwind: ability('whirlwind', 'Whirlwind', 'attack', 'physical', 'melee', 0, 8, 86, { damage: 70 }),
  wing_clip: ability('wing_clip', 'Wing Clip', 'attack', 'physical', 'melee', 0, 6, 58, { damage: 28 }),
  wrath: ability('wrath', 'Wrath', 'damage', 'nature', 'spell', 2, 0, 288, { damage: 64 }),
}

export const ARENA_CLASS_KITS: Record<ArenaClassId, ArenaClassKit> = {
  priest: kit('priest', 'Priest', 'holy', 'healer', `${ROOT}/chars/players/mage_classic.glb`, ['smite', 'lesser_heal', 'power_word_fortitude', 'shadow_word_pain', 'power_word_shield', 'renew', 'mind_blast', 'heal', 'mind_flay', 'flash_heal'], 'smite', 1.35, staff('staff')),
  knight: kit('knight', 'Knight', 'protection', 'tank', `${ROOT}/chars/players/knight.glb`, ['heroic_strike', 'charge', 'thunder_clap', 'sunder_armor', 'taunt'], 'heroic_strike', 1.1, swordShield('sword_1handed', 'shield_round')),
  ranger: kit('ranger', 'Hunter', 'marksmanship', 'ranged', `${ROOT}/chars/players/ranger.glb`, ['serpent_sting', 'arcane_shot', 'concussive_shot', 'aimed_shot', 'rapid_fire'], 'arcane_shot', 1.05, bow()),
  mage: kit('mage', 'Mage', 'fire', 'ranged', `${ROOT}/chars/players/mage.glb`, ['fireball', 'scorch', 'fire_blast', 'pyroblast', 'frost_nova'], 'fireball', 1.2, staff('staff')),
  rogue: kit('rogue', 'Rogue', 'combat', 'melee', `${ROOT}/chars/players/rogue.glb`, ['sinister_strike', 'eviscerate', 'backstab', 'gouge', 'rupture'], 'sinister_strike', 0.82, daggers('dagger', 'dagger_a')),
  warrior: kit('warrior', 'Warrior', 'protection', 'tank', `${ROOT}/chars/players/barbarian.glb`, ['charge', 'thunder_clap', 'sunder_armor', 'shield_slam', 'taunt'], 'heroic_strike', 1.02, swordShield('axe_1handed', 'shield_square')),
  paladin: kit('paladin', 'Paladin', 'protection', 'tank', `${ROOT}/chars/players/paladin.glb`, ['judgement', 'consecration', 'divine_protection', 'righteous_fury', 'taunt'], 'judgement', 1.18, swordShield('hammer_b', 'shield_badge')),
  druid: kit('druid', 'Druid', 'restoration', 'healer', `${ROOT}/chars/players/druid.glb`, ['rejuvenation', 'regrowth', 'healing_touch', 'barkskin', 'wrath'], 'wrath', 1.3, staff('adv_druid_staff')),
  shaman: kit('shaman', 'Shaman', 'restoration', 'healer', `${ROOT}/chars/players/barbarian.glb`, ['healing_wave', 'lightning_shield', 'frost_shock', 'flame_shock', 'lightning_bolt'], 'lightning_bolt', 1.25, oneHand('hammer_a')),

  priest_holy: kit('priest_holy', 'Priest', 'holy', 'healer', `${ROOT}/chars/players/mage_classic.glb`, ['lesser_heal', 'renew', 'heal', 'flash_heal', 'smite'], 'smite', 1.35, staff('staff')),
  priest_discipline: kit('priest_discipline', 'Priest', 'discipline', 'healer', `${ROOT}/chars/players/mage_classic.glb`, ['power_word_shield', 'power_word_fortitude', 'lesser_heal', 'renew', 'smite'], 'smite', 1.3, staff('staff_b')),
  priest_shadow: kit('priest_shadow', 'Priest', 'shadow', 'ranged', `${ROOT}/chars/players/mage_classic.glb`, ['shadow_word_pain', 'mind_blast', 'mind_flay', 'smite', 'power_word_shield'], 'mind_blast', 1.2, staff('scythe')),

  warrior_protection: kit('warrior_protection', 'Warrior', 'protection', 'tank', `${ROOT}/chars/players/barbarian.glb`, ['charge', 'thunder_clap', 'sunder_armor', 'shield_slam', 'taunt'], 'heroic_strike', 1.02, swordShield('axe_1handed', 'shield_square')),
  warrior_arms: kit('warrior_arms', 'Warrior', 'arms', 'melee', `${ROOT}/chars/players/barbarian.glb`, ['charge', 'mortal_strike', 'rend', 'overpower', 'slam'], 'mortal_strike', 1.12, twoHand('sword_2handed')),
  warrior_fury: kit('warrior_fury', 'Warrior', 'fury', 'melee', `${ROOT}/chars/players/barbarian.glb`, ['charge', 'bloodthirst', 'whirlwind', 'heroic_strike', 'cleave'], 'bloodthirst', 0.86, daggers('axe_1handed', 'axe_b')),

  paladin_protection: kit('paladin_protection', 'Paladin', 'protection', 'tank', `${ROOT}/chars/players/paladin.glb`, ['judgement', 'consecration', 'divine_protection', 'righteous_fury', 'taunt'], 'judgement', 1.18, swordShield('hammer_b', 'shield_badge')),
  paladin_holy: kit('paladin_holy', 'Paladin', 'holy', 'healer', `${ROOT}/chars/players/paladin.glb`, ['holy_light', 'flash_of_light', 'lay_on_hands', 'blessing_of_might', 'judgement'], 'judgement', 1.28, oneHand('hammer_a')),
  paladin_retribution: kit('paladin_retribution', 'Paladin', 'retribution', 'melee', `${ROOT}/chars/players/paladin.glb`, ['seal_of_righteousness', 'judgement', 'exorcism', 'consecration', 'blessing_of_might'], 'judgement', 1.05, twoHand('hammer_d')),

  druid_restoration: kit('druid_restoration', 'Druid', 'restoration', 'healer', `${ROOT}/chars/players/druid.glb`, ['rejuvenation', 'regrowth', 'healing_touch', 'barkskin', 'wrath'], 'wrath', 1.3, staff('adv_druid_staff')),
  druid_feral_tank: kit('druid_feral_tank', 'Druid', 'feral tank', 'tank', `${ROOT}/chars/players/druid.glb`, ['bear_charge', 'maul', 'swipe', 'demoralizing_roar', 'growl'], 'maul', 1.05, twoHand('staff_c')),
  druid_feral_cat: kit('druid_feral_cat', 'Druid', 'feral cat', 'melee', `${ROOT}/chars/players/druid.glb`, ['claw', 'rake', 'rip', 'ferocious_bite', 'faerie_fire'], 'claw', 0.84, daggers('dagger_b', 'dagger_c')),
  druid_balance: kit('druid_balance', 'Druid', 'balance', 'ranged', `${ROOT}/chars/players/druid.glb`, ['wrath', 'moonfire', 'starfire', 'insect_swarm', 'faerie_fire'], 'wrath', 1.18, staff('staff_d')),

  mage_arcane: kit('mage_arcane', 'Mage', 'arcane', 'ranged', `${ROOT}/chars/players/mage.glb`, ['arcane_missiles', 'arcane_explosion', 'arcane_intellect', 'frost_nova', 'fire_blast'], 'arcane_missiles', 1.12, staff('staff')),
  mage_fire: kit('mage_fire', 'Mage', 'fire', 'ranged', `${ROOT}/chars/players/mage.glb`, ['fireball', 'scorch', 'fire_blast', 'pyroblast', 'frost_nova'], 'fireball', 1.2, staff('staff_a')),
  mage_frost: kit('mage_frost', 'Mage', 'frost', 'ranged', `${ROOT}/chars/players/mage.glb`, ['frostbolt', 'frost_nova', 'ice_barrier', 'arcane_missiles', 'fire_blast'], 'frostbolt', 1.2, staff('staff_b')),

  rogue_assassination: kit('rogue_assassination', 'Rogue', 'assassination', 'melee', `${ROOT}/chars/players/rogue_hooded.glb`, ['ambush', 'backstab', 'rupture', 'eviscerate', 'sinister_strike'], 'backstab', 0.78, daggers('adv_dagger', 'dagger_c')),
  rogue_combat: kit('rogue_combat', 'Rogue', 'combat', 'melee', `${ROOT}/chars/players/rogue.glb`, ['sinister_strike', 'eviscerate', 'backstab', 'gouge', 'rupture'], 'sinister_strike', 0.82, daggers('dagger', 'dagger_a')),
  rogue_subtlety: kit('rogue_subtlety', 'Rogue', 'subtlety', 'melee', `${ROOT}/chars/players/rogue_hooded.glb`, ['ambush', 'gouge', 'backstab', 'eviscerate', 'rupture'], 'ambush', 0.8, daggers('dagger_b', 'dagger_a')),

  hunter_beast_mastery: kit('hunter_beast_mastery', 'Hunter', 'beast mastery', 'ranged', `${ROOT}/chars/players/ranger.glb`, ['aspect_of_the_hawk', 'serpent_sting', 'arcane_shot', 'raptor_strike', 'rapid_fire'], 'arcane_shot', 1.05, bow()),
  hunter_marksmanship: kit('hunter_marksmanship', 'Hunter', 'marksmanship', 'ranged', `${ROOT}/chars/players/ranger.glb`, ['serpent_sting', 'arcane_shot', 'concussive_shot', 'aimed_shot', 'rapid_fire'], 'arcane_shot', 1.05, bow()),
  hunter_survival: kit('hunter_survival', 'Hunter', 'survival', 'ranged', `${ROOT}/chars/players/ranger.glb`, ['serpent_sting', 'wing_clip', 'raptor_strike', 'concussive_shot', 'arcane_shot'], 'arcane_shot', 0.98, bow()),

  shaman_restoration: kit('shaman_restoration', 'Shaman', 'restoration', 'healer', `${ROOT}/chars/players/barbarian.glb`, ['healing_wave', 'lightning_shield', 'frost_shock', 'flame_shock', 'lightning_bolt'], 'lightning_bolt', 1.25, oneHand('hammer_a')),
  shaman_elemental: kit('shaman_elemental', 'Shaman', 'elemental', 'ranged', `${ROOT}/chars/players/barbarian.glb`, ['lightning_bolt', 'earth_shock', 'flame_shock', 'frost_shock', 'lightning_shield'], 'lightning_bolt', 1.15, oneHand('hammer_c')),
  shaman_enhancement: kit('shaman_enhancement', 'Shaman', 'enhancement', 'melee', `${ROOT}/chars/players/barbarian.glb`, ['stormstrike', 'earth_shock', 'flame_shock', 'frost_shock', 'lightning_shield'], 'stormstrike', 0.98, twoHand('hammer_d')),

  warlock_affliction: kit('warlock_affliction', 'Warlock', 'affliction', 'ranged', `${ROOT}/chars/players/mage_classic.glb`, ['corruption', 'curse_of_agony', 'drain_life', 'shadow_bolt', 'fear'], 'shadow_bolt', 1.25, staff('scythe')),
  warlock_demonology: kit('warlock_demonology', 'Warlock', 'demonology', 'ranged', `${ROOT}/chars/players/mage_classic.glb`, ['demon_skin', 'shadow_bolt', 'corruption', 'drain_life', 'immolate'], 'shadow_bolt', 1.22, staff('adv_staff')),
  warlock_destruction: kit('warlock_destruction', 'Warlock', 'destruction', 'ranged', `${ROOT}/chars/players/mage_classic.glb`, ['shadow_bolt', 'immolate', 'searing_pain', 'shadowburn', 'corruption'], 'shadow_bolt', 1.18, staff('staff_d')),
}

function kit(
  id: ArenaClassId,
  displayName: string,
  defaultPvpSpec: string,
  role: PartyRole,
  model: string,
  actionBar: ArenaAbilityId[],
  basicAttack: ArenaAbilityId,
  attackSeconds: number,
  weapons: ArenaClassKit['weapons'],
): ArenaClassKit {
  return { actionBar, attackSeconds, basicAttack, defaultPvpSpec, displayName, id, model, role, weapons }
}

function staff(model: string): ArenaClassKit['weapons'] {
  return [{ hand: 'handslot.r', model: `${ROOT}/weapons/${model}.glb` }]
}

function oneHand(model: string): ArenaClassKit['weapons'] {
  return [{ hand: 'handslot.r', model: `${ROOT}/weapons/${model}.glb` }]
}

function twoHand(model: string): ArenaClassKit['weapons'] {
  return [{ hand: 'handslot.r', model: `${ROOT}/weapons/${model}.glb` }]
}

function daggers(right: string, left: string): ArenaClassKit['weapons'] {
  return [
    { hand: 'handslot.r', model: `${ROOT}/weapons/${right}.glb` },
    { hand: 'handslot.l', model: `${ROOT}/weapons/${left}.glb` },
  ]
}

function swordShield(right: string, left: string): ArenaClassKit['weapons'] {
  return [
    { hand: 'handslot.r', model: `${ROOT}/weapons/${right}.glb` },
    { hand: 'handslot.l', model: `${ROOT}/weapons/${left}.glb` },
  ]
}

function bow(): ArenaClassKit['weapons'] {
  return [
    { hand: 'handslot.r', model: `${ROOT}/weapons/crossbow_1handed.glb` },
    { hand: 'handslot.l', model: `${ROOT}/weapons/quiver.glb` },
  ]
}

export function createArenaAbilityCooldowns(classId: ArenaClassId) {
  return Object.fromEntries(ARENA_CLASS_KITS[classId].actionBar.map((id) => [id, 0])) as Record<string, number>
}

export function getArenaClassKit(classId: ArenaClassId) {
  return ARENA_CLASS_KITS[classId]
}

export function getArenaAbility(abilityId: ArenaAbilityId) {
  return ARENA_ABILITIES[abilityId]
}

function ability(
  id: ArenaAbilityId,
  name: string,
  kind: ArenaAbilityKind,
  school: ArenaAbilitySchool,
  animation: ArenaAbilityDefinition['animation'],
  castTime: number,
  cooldown: number,
  range: number,
  effects: Partial<Pick<ArenaAbilityDefinition, 'damage' | 'dot' | 'heal' | 'shield'>> = {},
): ArenaAbilityDefinition {
  return { animation, castTime, cooldown, id, kind, name, range, school, ...effects }
}
