import { ItemStack, world, system } from "@minecraft/server";
import { getAdjacentBlock } from "./multiblockUtility.js";
import { TTGroupManager } from "./TTGroupManager.js";
import { highlightBlock } from "../blockHighlight.js";

/**
 * Called when the bottom block is placed or activated.
 */
export function multiblockTTFormationManager(block) {
  const statePlaced = block.permutation.getState("pb_gat:mb_placed");
  if (!statePlaced) {
    // Check above for room
    const blockAbove = getAdjacentBlock(block, "above");
    if (blockAbove.typeId !== "minecraft:air") {
      block.dimension.spawnItem(new ItemStack(block.typeId), block.location);
      block.setType("minecraft:air");
      const dim = block.dimension;
      const players = dim.getPlayers({
        location: block.location,
        maxDistance: 5,
      });
      const player = players[0];
      if (player) {
        player.playSound("note.bass", {
          pitch: 0.9,
          volume: 0.6,
          location: player.location,
        });
        highlightBlock(blockAbove, "red", "blocked");
        system.runTimeout(() => {
          highlightBlock(blockAbove, "red", "blocked");
          system.runTimeout(() => {
            highlightBlock(blockAbove, "red", "blocked");
          }, 20);
        }, 20);
        return player.sendMessage(
          "§4->§r No room for Tinker Table, please ensure the block above is free."
        );
      }
      return;
    }

    // Place top block
    blockAbove.setType("pb_gat:mb_tinker_table_top");
    const direction = block.permutation.getState(
      "minecraft:cardinal_direction"
    );
    blockAbove.setPermutation(
      blockAbove.permutation.withState(
        "minecraft:cardinal_direction",
        direction
      )
    );
    blockAbove.setPermutation(
      blockAbove.permutation.withState("pb_gat:mb_placed", true)
    );

    // Spawn entity
    const spawnLocation = {
      x: block.location.x + 0.5,
      y: block.location.y,
      z: block.location.z + 0.5,
    };
    const tableEntity = block.dimension.spawnEntity(
      "pb_gat:mb_tinker_table_entity",
      spawnLocation
    );
    if (tableEntity) tableEntity.setProperty("pb_gat:direction", direction);

    world.playSound("item.spyglass.use", spawnLocation, {
      pitch: 0.6,
      volume: 5.0,
    });

    // Update bottom block state
    block.setPermutation(block.permutation.withState("pb_gat:mb_placed", true));

    // Register the group
    TTGroupManager.createGroup({
      direction,
      master: block,
      blocks: [blockAbove],
      entity: tableEntity, // store the entity directly
    });
  } else {
    // Already placed → run integrity check
    checkTTIntegrity(block);
  }
}

/**
 * Called on the top block (dummy), to ensure the bottom still exists.
 */
export function multiblockTTDummyBlockCheck(block) {
  checkTTIntegrity(block);
}

/**
 * Shared function for checking structure integrity from either top or bottom.
 * Cleans up both blocks and the entity if invalid.
 */
function checkTTIntegrity(block) {
  const dim = block.dimension;
  const groupId = TTGroupManager.getGroupIdAtBlock(block);

  if (!groupId) {
    destroyBlockAndEntity(block, null);
    return;
  }

  const group = TTGroupManager.getGroup(groupId);
  if (!group) {
    destroyBlockAndEntity(block, null);
    return;
  }

  const bottom = dim.getBlock(group.master);
  const top = dim.getBlock(group.blocks[0]);
  const entity = group.entity;

  const bottomIsValid = bottom?.typeId === "pb_gat:mb_tinker_table_bottom";
  const topIsValid = top?.typeId === "pb_gat:mb_tinker_table_top";
  const entityIsValid = entity && !entity.isRemoved;

  if (!bottomIsValid || !topIsValid || !entityIsValid) {
    // Drop bottom as item
    if (bottomIsValid)
      dim.spawnItem(
        new ItemStack("pb_gat:mb_tinker_table_bottom"),
        bottom.location
      );

    // Clear machine blocks only
    if (
      bottom &&
      (bottom.typeId === "pb_gat:mb_tinker_table_bottom" ||
        bottom.typeId === "pb_gat:mb_tinker_table_top")
    ) {
      bottom.setType("minecraft:air");
    }
    if (
      top &&
      (top.typeId === "pb_gat:mb_tinker_table_bottom" ||
        top.typeId === "pb_gat:mb_tinker_table_top")
    ) {
      top.setType("minecraft:air");
    }

    // Remove the entity from the group only
    if (entity) {
      const entities = dim
        .getEntities({ type: "pb_gat:mb_tinker_table_entity" })
        .filter((e) => e.id === entity.id);
      for (const e of entities) e.triggerEvent("pb_gat:drop_item_despawn");
    }

    TTGroupManager.destroyGroup(groupId);
  }
}

// Helper to destroy only machine blocks and the entity stored in the group
function destroyBlockAndEntity(block, entity) {
  const dim = block.dimension;

  if (
    block.typeId === "pb_gat:mb_tinker_table_bottom" ||
    block.typeId === "pb_gat:mb_tinker_table_top"
  ) {
    dim.spawnItem(new ItemStack(block.typeId), block.location);
    block.setType("minecraft:air");
  }

  if (entity) {
    const entities = dim
      .getEntities({ type: "pb_gat:mb_tinker_table_entity" })
      .filter((e) => e.id === entity.id);
    for (const e of entities) e.triggerEvent("pb_gat:drop_item_despawn");
  }
}
