import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
import 'package:wolf_3d_entities/src/entities/collectible.dart';
import 'package:wolf_3d_entities/src/entities/decorative.dart';
import 'package:wolf_3d_entities/src/entities/enemies/bosses/hans_grosse.dart';
import 'package:wolf_3d_entities/src/entities/enemies/enemy.dart';
import 'package:wolf_3d_entities/src/entity.dart';

typedef EntitySpawner =
    Entity? Function(
      int objId,
      double x,
      double y,
      Difficulty difficulty, {
      bool isSharewareMode,
    });

abstract class EntityRegistry {
  static final List<EntitySpawner> _spawners = [
    // Enemies need to try to spawn first
    Enemy.spawn,

    // Bosses
    HansGrosse.trySpawn,

    // Everything else
    Collectible.trySpawn,
    Decorative.trySpawn,
  ];

  static Entity? spawn(
    int objId,
    double x,
    double y,
    Difficulty difficulty,
    int maxSprites, {
    bool isSharewareMode = false,
  }) {
    // 1. Difficulty check before even looking for a spawner
    if (!MapObject.shouldSpawn(objId, difficulty)) return null;

    // If the checkbox is checked, block non-Shareware enemies
    if (isSharewareMode && !MapObject.isSharewareCompatible(objId)) return null;

    if (objId == 0) return null;

    for (final spawner in _spawners) {
      Entity? entity = spawner(objId, x, y, difficulty);

      final EnemyType? type = EnemyType.fromMapId(objId);
      if (type != null) {
        print("Spawning ${type.name} enemy");
      }

      if (entity != null) {
        // Safety bounds check for the VSWAP array
        if (entity.spriteIndex >= 0 && entity.spriteIndex < maxSprites) {
          print("Spawned entity with objId $objId");
          return entity;
        }
        print("VSWAP doesn't have this sprite! objId $objId");
        return null; // VSWAP doesn't have this sprite!
      }
    }
    print("No class claimed this Map ID > objId $objId");
    return null; // No class claimed this Map ID
  }
}
