import type { Iwt2BossId } from '../content/bosses'
import type { Iwt2PlayerClassId } from '../content/classes'

export type Iwt2Vec2 = {
  x: number
  y: number
}

export type Iwt2ArenaBounds = {
  width: number
  height: number
}

export type Iwt2PartyEntityId =
  | 'player-healer'
  | 'paladin-tank'
  | 'ranger'
  | 'mage'
  | 'rogue'
  | 'warrior'

export type Iwt2BossEntityId = Iwt2BossId

export type Iwt2EntityId = Iwt2PartyEntityId | Iwt2BossEntityId | string

export type Iwt2EntityKind = 'party' | 'boss' | 'hostileAdd'

export type Iwt2PartyAiRole = 'player' | 'tank' | 'ranged' | 'flanker' | 'melee'

export type Iwt2StatusState = {
  stunnedSeconds: number
  knockedDownSeconds: number
  invulnerableSeconds: number
}

export type Iwt2HotEffectState = {
  id: string
  label: string
  power: number
  remainingSeconds: number
  tickIntervalSeconds: number
  nextTickInSeconds: number
}

export type Iwt2PartyEntityState = {
  id: Iwt2PartyEntityId
  kind: 'party'
  classId: Iwt2PlayerClassId
  aiRole: Iwt2PartyAiRole
  position: Iwt2Vec2
  velocity: Iwt2Vec2
  facing: Iwt2Vec2
  radius: number
  health: number
  maxHealth: number
  shield: number
  mana: number
  maxMana: number
  damageDone: number
  attackCooldownRemaining: number
  castSecondsRemaining: number
  attackReady: boolean
  status: Iwt2StatusState
  hotEffects: Iwt2HotEffectState[]
  preferredOffset: Iwt2Vec2
  decisionSecondsRemaining: number
}

export type Iwt2ProjectileEntityState = {
  id: string
  sourceId: Iwt2EntityId
  owner: 'party' | 'boss'
  classId?: Iwt2PlayerClassId
  projectileKind: 'arrow' | 'fireball' | 'magic'
  color: string
  position: Iwt2Vec2
  velocity: Iwt2Vec2
  radius: number
  damage: number
  remainingSeconds: number
  bouncesRemaining?: number
  bounceCooldownSeconds?: number
}

export type Iwt2BossAttackPhase =
  | 'idle'
  | 'chargeWindup'
  | 'charging'
  | 'chargeRecover'
  | 'slamWindup'
  | 'slamRecover'
  | 'relocating'
  | 'fireballWindup'
  | 'fireballRecover'
  | 'birdSummonWindup'
  | 'birdSummonRecover'
  | 'packHowlWindup'
  | 'packHowlRecover'
  | 'thunderRingWindup'
  | 'thunderRingRecover'
  | 'lightningStrikeWindup'
  | 'lightningStrikeRecover'

export type Iwt2HostileAddAttackPhase =
  | 'idle'
  | 'flightWindup'
  | 'flying'
  | 'flightRecover'

export type Iwt2BossEntityState = {
  id: Iwt2BossEntityId
  kind: 'boss'
  bossId: Iwt2BossId
  position: Iwt2Vec2
  velocity: Iwt2Vec2
  facing: Iwt2Vec2
  radius: number
  health: number
  maxHealth: number
  meleeCooldownRemaining: number
  chargeCooldownRemaining: number
  chargeCount: number
  attackPhase: Iwt2BossAttackPhase
  phaseSecondsRemaining: number
  chargeStart: Iwt2Vec2
  chargeEnd: Iwt2Vec2
  chargeHitEntityIds: Iwt2EntityId[]
  slamApplied: boolean
  wallContactSeconds: number
  relocateTarget: Iwt2Vec2
  fireballCooldownRemaining: number
  fireballTarget: Iwt2Vec2
  birdWaveThresholdsTriggered: number[]
  mechanicLanes: Iwt2MechanicLaneState[]
  mechanicCircles: Iwt2MechanicCircleState[]
}

export type Iwt2MechanicLaneState = {
  id: string
  start: Iwt2Vec2
  end: Iwt2Vec2
  width: number
}

export type Iwt2MechanicCircleState = {
  id: string
  position: Iwt2Vec2
  radius: number
}

export type Iwt2HostileAddState = {
  id: string
  kind: 'hostileAdd'
  addKind: 'yian-bird'
  sourceBossId: Iwt2BossId
  position: Iwt2Vec2
  velocity: Iwt2Vec2
  facing: Iwt2Vec2
  radius: number
  health: number
  maxHealth: number
  damageDone: number
  attackCooldownRemaining: number
  flightCooldownRemaining: number
  attackPhase: Iwt2HostileAddAttackPhase
  phaseSecondsRemaining: number
  flightStart: Iwt2Vec2
  flightEnd: Iwt2Vec2
  flightHitEntityIds: Iwt2EntityId[]
}

export type Iwt2GroundHazardState = {
  id: string
  kind: 'groundHazard'
  hazardKind: 'firePuddle'
  sourceId: Iwt2EntityId
  position: Iwt2Vec2
  radius: number
  damage: number
  remainingSeconds: number
  fadeSeconds: number
  nextDamageAt: number
}

export type Iwt2ArenaEventType =
  | 'bossDamaged'
  | 'partyHealed'
  | 'partyDamaged'
  | 'partyStunned'
  | 'bossChargeStart'
  | 'bossChargeHit'
  | 'bossSlam'
  | 'entityDefeated'

export type Iwt2ArenaEvent = {
  id: number
  time: number
  type: Iwt2ArenaEventType
  sourceId: Iwt2EntityId
  targetId?: Iwt2EntityId
  value?: number
}

export type Iwt2ArenaIndicatorPhase = 'windup' | 'active' | 'recover'

export type Iwt2ArenaIndicatorBase = {
  id: string
  mechanicId: string
  sourceId: Iwt2EntityId
  phase: Iwt2ArenaIndicatorPhase
  color: string
  fillAlpha?: number
  lineAlpha?: number
}

export type Iwt2ArenaLaneIndicator = Iwt2ArenaIndicatorBase & {
  kind: 'lane'
  start: Iwt2Vec2
  end: Iwt2Vec2
  width: number
}

export type Iwt2ArenaCircleIndicator = Iwt2ArenaIndicatorBase & {
  kind: 'circle'
  position: Iwt2Vec2
  radius: number
}

export type Iwt2ArenaConeIndicator = Iwt2ArenaIndicatorBase & {
  kind: 'cone'
  origin: Iwt2Vec2
  direction: Iwt2Vec2
  range: number
  angleRadians: number
}

export type Iwt2ArenaDonutIndicator = Iwt2ArenaIndicatorBase & {
  kind: 'donut'
  position: Iwt2Vec2
  innerRadius: number
  outerRadius: number
}

export type Iwt2ArenaIndicator =
  | Iwt2ArenaLaneIndicator
  | Iwt2ArenaCircleIndicator
  | Iwt2ArenaConeIndicator
  | Iwt2ArenaDonutIndicator

export type Iwt2ArenaState = {
  schemaVersion: 1
  time: number
  bounds: Iwt2ArenaBounds
  party: Iwt2PartyEntityState[]
  projectiles: Iwt2ProjectileEntityState[]
  hostileAdds: Iwt2HostileAddState[]
  hazards: Iwt2GroundHazardState[]
  boss: Iwt2BossEntityState
  bosses: Iwt2BossEntityState[]
  indicators: Iwt2ArenaIndicator[]
  nextEventId: number
  nextProjectileId: number
  nextAddId: number
  nextHazardId: number
  events: Iwt2ArenaEvent[]
}

export type Iwt2ArenaInput = {
  moveX: number
  moveY: number
}

export type Iwt2Circle = {
  position: Iwt2Vec2
  radius: number
}
