import 'package:wolf_3d_dart/src/data_types/sprite_frame_range.dart';

/// The set of animation states an enemy can be in.
enum EnemyAnimation { idle, walking, attacking, pain, dying, dead }

/// A mapping container that defines the sprite index ranges for an enemy's life cycle.
///
/// Wolfenstein 3D enemies use specific ranges within the global sprite list
/// to handle state transitions like walking, attacking, or dying.
class EnemyAnimationMap {
  final SpriteFrameRange idle;
  final SpriteFrameRange walking;
  final SpriteFrameRange attacking;
  final SpriteFrameRange pain;
  final SpriteFrameRange dying;
  final SpriteFrameRange dead;

  const EnemyAnimationMap({
    required this.idle,
    required this.walking,
    required this.attacking,
    required this.pain,
    required this.dying,
    required this.dead,
  });

  /// Identifies which [EnemyAnimation] state a specific [spriteIndex] belongs to.
  ///
  /// Returns `null` if the index is outside this enemy's defined animation ranges.
  EnemyAnimation? getAnimation(int spriteIndex) {
    if (idle.contains(spriteIndex)) return EnemyAnimation.idle;
    if (walking.contains(spriteIndex)) return EnemyAnimation.walking;
    if (attacking.contains(spriteIndex)) return EnemyAnimation.attacking;
    if (pain.contains(spriteIndex)) return EnemyAnimation.pain;
    if (dying.contains(spriteIndex)) return EnemyAnimation.dying;
    if (dead.contains(spriteIndex)) return EnemyAnimation.dead;
    return null;
  }

  /// All animation states mapped to their corresponding [SpriteFrameRange].
  Map<EnemyAnimation, SpriteFrameRange> get allRanges => {
    EnemyAnimation.idle: idle,
    EnemyAnimation.walking: walking,
    EnemyAnimation.attacking: attacking,
    EnemyAnimation.pain: pain,
    EnemyAnimation.dying: dying,
    EnemyAnimation.dead: dead,
  };

  /// Returns the [SpriteFrameRange] associated with a specific [animation] state.
  SpriteFrameRange getRange(EnemyAnimation animation) {
    return switch (animation) {
      EnemyAnimation.idle => idle,
      EnemyAnimation.walking => walking,
      EnemyAnimation.attacking => attacking,
      EnemyAnimation.pain => pain,
      EnemyAnimation.dying => dying,
      EnemyAnimation.dead => dead,
    };
  }

  /// Checks if any animation range in this map overlaps with any range in [other].
  bool overlapsWith(EnemyAnimationMap other) {
    final myRanges = [idle, walking, attacking, pain, dying, dead];
    final otherRanges = [
      other.idle,
      other.walking,
      other.attacking,
      other.pain,
      other.dying,
      other.dead,
    ];

    for (final mine in myRanges) {
      for (final theirs in otherRanges) {
        if (mine.overlaps(theirs)) return true;
      }
    }
    return false;
  }
}
