import 'dart:math' as math;

import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
import 'package:wolf_3d_entities/wolf_3d_entities.dart';

class DoorManager {
  // Key is '$x,$y'
  final Map<String, Door> doors = {};

  // Callback to play sounds without tightly coupling to the audio engine
  final void Function(int sfxId) onPlaySound;

  DoorManager({required this.onPlaySound});

  void initDoors(SpriteMap wallGrid) {
    doors.clear();
    for (int y = 0; y < wallGrid.length; y++) {
      for (int x = 0; x < wallGrid[y].length; x++) {
        int id = wallGrid[y][x];
        if (id >= 90) {
          doors['$x,$y'] = Door(x: x, y: y, mapId: id);
        }
      }
    }
  }

  void update(Duration elapsed) {
    for (final door in doors.values) {
      final newState = door.update(elapsed.inMilliseconds);

      // The Manager decides: "If a door just started closing, play the close sound."
      if (newState == DoorState.closing) {
        onPlaySound(WolfSound.closeDoor);
      }
    }
  }

  void handleInteraction(double playerX, double playerY, double playerAngle) {
    int targetX = (playerX + math.cos(playerAngle)).toInt();
    int targetY = (playerY + math.sin(playerAngle)).toInt();

    String key = '$targetX,$targetY';
    if (doors.containsKey(key)) {
      if (doors[key]!.interact()) {
        // The Manager decides: "Player successfully opened a door, play the sound."
        onPlaySound(WolfSound.openDoor);
      }
    }
  }

  void tryOpenDoor(int x, int y) {
    String key = '$x,$y';
    if (doors.containsKey(key) && doors[key]!.offset == 0.0) {
      if (doors[key]!.interact()) {
        onPlaySound(WolfSound.openDoor);
      }
    }
  }

  // Helper method for the raycaster
  Map<String, double> getOffsetsForRenderer() {
    Map<String, double> offsets = {};
    for (var entry in doors.entries) {
      if (entry.value.offset > 0.0) {
        offsets[entry.key] = entry.value.offset;
      }
    }
    return offsets;
  }

  bool isDoorOpenEnough(int x, int y) {
    String key = '$x,$y';
    if (doors.containsKey(key)) {
      // 0.7 offset means 70% open, similar to the original engine's check
      return doors[key]!.offset > 0.7;
    }
    return false; // Not a door we manage
  }
}
