import { world, system, Direction } from "@minecraft/server";

const cooldowns = new Set();
const activeSeats = new Map();
const seatCheckIntervals = new Map();
const cooldownDuration = 5;
const SEAT_DATA_KEY = "furnideco:seat_data"; // World dynamic property key
let loadedSeatData = null;
const names = ["sofa", "cabinet"];

// Initialize script
world.afterEvents.worldInitialize.subscribe(() => {
  system.runTimeout(() => {
    loadedSeatData = loadSeatData();
  }, 10);
});

// Handle player join
world.afterEvents.playerJoin.subscribe((event) => {
  system.runTimeout(() => {
    const { playerId } = event;

    // Skip if no seats are loaded
    if (!loadedSeatData || Object.keys(loadedSeatData).length === 0) {
      return;
    }

    // Check if any loaded seats belong to this player
    const playerHasSeats = Object.values(loadedSeatData).some(seatData => seatData.playerId === playerId);

    if (!playerHasSeats) {
      return;
    }

    const player = world.getAllPlayers().find(p => p.id === playerId);

    if (player) {
      startPlayerMonitor(player);
    } else {
      return;
    }
  }, 50);
});

// Handle player leave
world.afterEvents.playerLeave.subscribe((event) => {
  const { playerId } = event;
  stopPlayerMonitor(playerId);
});

world.afterEvents.entityHurt.subscribe((eventData) => {
  const entity = eventData.hurtEntity;

  if (entity.typeId !== "minecraft:player") return;

  const player = entity;
  const dimension = world.getDimension(player.dimension.id);
  const seatEntities = dimension.getEntities()
    .filter(e => e.typeId === "furnideco:seat");

  seatEntities.forEach(seatEntity => {
    const distance = Math.sqrt(
      Math.pow(player.location.x - seatEntity.location.x, 2) +
      Math.pow(player.location.y - seatEntity.location.y, 2) +
      Math.pow(player.location.z - seatEntity.location.z, 2)
    );
    if (distance <= 0.5) {
      seatEntity.remove();
      activeSeats.delete(seatEntity.id);
      saveSeatData();

      // Check if player has no more seats
      const playerSeats = Array.from(activeSeats.values()).filter(seat => seat.playerId === player.id);
      if (playerSeats.length === 0) {
        stopPlayerMonitor(player.id);
      }
    }
  });
});

function startPlayerMonitor(player) {
  if (!player || !player.id) {
    return;
  }

  // Check if a monitor is already running for this player
  if (seatCheckIntervals.has(player.id)) {
    return;
  }

  const interval = system.runInterval(() => {
    for (const [seatId, locationData] of activeSeats) {
      if (locationData.playerId !== player.id) continue; // Only check seats for this player

      const seatEntity = world.getEntity(seatId);
      if (!seatEntity) {
        activeSeats.delete(seatId);
        saveSeatData();
        continue;
      }

      const dimension = world.getDimension(locationData.dimension);
      const currentBlock = dimension.getBlock(locationData);
      const isBlockRemoved = currentBlock.typeId === "minecraft:air" ||
        currentBlock.typeId === "minecraft:water" ||
        currentBlock.typeId === "minecraft:lava";

      const nearbyPlayers = dimension.getPlayers({
        location: seatEntity.location,
        maxDistance: 0.5
      });

      if (isBlockRemoved || nearbyPlayers.length === 0) {
        seatEntity.remove();
        activeSeats.delete(seatId);
        saveSeatData();
      }
    }

    // If no more active seats for this player, stop the monitor
    const playerSeats = Array.from(activeSeats.values()).filter(seat => seat.playerId === player.id);
    if (playerSeats.length === 0) {
      stopPlayerMonitor(player.id);
    }
  }, 10);

  seatCheckIntervals.set(player.id, interval);
}

function stopPlayerMonitor(playerId) {
  if (seatCheckIntervals.has(playerId)) {
    system.clearRun(seatCheckIntervals.get(playerId));
    seatCheckIntervals.delete(playerId);
  }
}

function saveSeatData() {
  const seatData = Object.fromEntries(activeSeats);
  world.setDynamicProperty(SEAT_DATA_KEY, JSON.stringify(seatData));
}

function loadSeatData() {
  const seatData = world.getDynamicProperty(SEAT_DATA_KEY);
  if (seatData) {
    const parsedData = JSON.parse(seatData);
    for (const [seatId, locationData] of Object.entries(parsedData)) {
      activeSeats.set(seatId, locationData);
    }
    return parsedData;
  } else {
    return null;
  }
}