import { world, system, ItemStack } from "@minecraft/server";
import BlockUtils from "./BlockUtils";
import ItemUtils from "./ItemUtils";
import PlayerUtils from "./PlayerUtils";
import "./Door/onInteract";
import "./Door/onPlace";
import "./Door/onTick";
import "./forms";

system.beforeEvents.watchdogTerminate.subscribe((scb) => (scb.cancel = true));

world.beforeEvents.worldInitialize.subscribe((scb) => {
  scb.blockTypeRegistry.registerCustomComponent("scb:components", {
    onStepOn({ block }) {
      const blockUtils = new BlockUtils(block);
      blockUtils.mineOnStep();
    },
  });
  scb.itemComponentRegistry.registerCustomComponent("scb:components", {
    onUseOn() {},
  });
});

world.afterEvents.itemUseOn.subscribe((scb) => {
  const { source: player, itemStack: item, block } = scb;
  const idKeys = [
    "barrel",
    "chest",
    "door",
    "anvil",
    "trapdoor",
    "bed",
    "bedrock",
    "tnt",
    "shulker",
    "lit",
    "hopper",
    "amethyst",
    "sculk",
    "spawner",
    "chorus_plant",
    "reinforced",
    "deny",
    "allow",
    "barrier",
    "command_block",
    "structure",
    "infested",
    "egg",
    "scb:",
    "flower",
    "tallgrass",
    "furnace",
  ];
  const loc = block.location;
  const dimension = player.dimension;
  const somePlayers = world
    .getDynamicPropertyIds()
    .find((e) => e.includes(`${loc.x} ${loc.y} ${loc.z}`));
  const items = [
    "scb:block_reinforcer",
    "scb:remover",
    "scb:mine_injector",
    "scb:turret_item",
    "scb:dron_item",
  ];
  if (
    item?.typeId == items[0] &&
    !idKeys.some((e) => block?.typeId.includes(e))
  ) {
    if (!somePlayers) {
      player.playSound("armor.equip_chain", { pitch: 0.6, volume: 1 });
      world.setDynamicProperty(
        `${dimension.id}:${loc.x} ${loc.y} ${loc.z}`,
        `${player.name}:${dimension.id}:${loc.x} ${loc.y} ${loc.z}`
      );
    } else if (somePlayers) {
      const property = world.getDynamicProperty(somePlayers);
      if (property == "") {
        player.playSound("armor.equip_chain", { pitch: 0.6, volume: 1 });
        world.setDynamicProperty(
          `${dimension.id}:${loc.x} ${loc.y} ${loc.z}`,
          `${player.name}:${dimension.id}:${loc.x} ${loc.y} ${loc.z}`
        );
      } else {
        const owner = world.getDynamicProperty(somePlayers).split(":")[0];
        player.sendMessage(`§cProperty of ${owner.split(":")[0]}`);
      }
    } else {
      const owner = world.getDynamicProperty(somePlayers).split(":")[0];
      player.sendMessage(`§cProperty of ${owner.split(":")[0]}`);
    }
  }
  if (item?.typeId == items[1]) {
    if (somePlayers) {
      const owner = world.getDynamicProperty(somePlayers).split(":")[0];
      if (player.name == owner) {
        player.playSound("block.stonecutter.use");
        world.setDynamicProperty(
          `${dimension.id}:${loc.x} ${loc.y} ${loc.z}`,
          ``
        );
        const removedBlock = player.dimension.getBlock(loc);
        const returnBlock = new ItemStack(removedBlock?.typeId);
        dimension.spawnItem(returnBlock, loc);
        dimension.setBlockType(block.location, "minecraft:air");
      } else {
        if (owner) {
          player.sendMessage(`§cProperty of ${owner.split(":")[0]}`);
        }
      }
    }
  }
  if (item?.typeId == items[3]) {
    const inv = player.getComponent("inventory").container;
    const newAmount = item.amount - 1;
    const blockUtils = new BlockUtils(block, player, item);
    if (newAmount > 0) {
      const clearTurret = new ItemStack(item?.typeId, newAmount);
      inv.setItem(player.selectedSlot, clearTurret);
      blockUtils.turretOnPlaced();
    } else {
      player.runCommand(`replaceitem entity @s slot.weapon.mainhand 0 air`);
      blockUtils.turretOnPlaced();
    }
  }
  if (item?.typeId == items[4]) {
    player.runCommand(`replaceitem entity @s slot.weapon.mainhand 0 air`);
    const newTurret = dimension.spawnEntity("scb:drone", {
      x: loc.x + 0.5,
      y: loc.y + 1,
      z: loc.z + 0.5,
    });
  }
});

world.beforeEvents.playerBreakBlock.subscribe((e) => {
  const { player, block } = e;
  const dimension = player.dimension;
  const loc = block.location;
  const somePlayers = world
    .getDynamicPropertyIds()
    ?.find((e) => e.includes(`${loc.x} ${loc.y} ${loc.z}`));
  if (somePlayers) {
    const owner = world.getDynamicProperty(somePlayers)?.split(":")[0];
    const property = world.getDynamicProperty(somePlayers);
    if (property != "") {
      e.cancel = true;
      if (player.name == owner) {
        player.sendMessage(`§cTo remove this, use the Block Remover`);
        system.run(() => {
          player.teleport(player.location);
        });
      } else {
        player.sendMessage(`§cProperty of ${owner.split(":")[0]}`);
        system.run(() => {
          player.teleport(player.location);
        });
      }
    }
  }
});

world.beforeEvents.explosion.subscribe((e) => {
  const impactedBlocks = e.getImpactedBlocks();
  const reinforcedBlocks = [];
  const nonReinforcedBlocks = [];

  impactedBlocks.forEach((block) => {
    const loc = block.location;
    const playersInLocation = world
      .getDynamicPropertyIds()
      .find((id) => id.includes(`${loc.x} ${loc.y} ${loc.z}`));

    if (playersInLocation) {
      const property = world.getDynamicProperty(playersInLocation);
      if (property === "") {
        nonReinforcedBlocks.push(block);
      } else {
        reinforcedBlocks.push(block);
      }
    } else {
      nonReinforcedBlocks.push(block);
    }
  });
  e.setImpactedBlocks(nonReinforcedBlocks);
});

world.afterEvents.playerInteractWithBlock.subscribe((e) => {
  const { block, player } = e;
  const loc = block.location;
  const somePlayers = world
    .getDynamicPropertyIds()
    .find((e) => e.includes(`${loc.x} ${loc.y} ${loc.z}`));
  if (somePlayers) {
    const owner = world.getDynamicProperty(somePlayers);
    owner == "" || undefined
      ? null
      : player.onScreenDisplay.setActionBar(
          "§bSecurityCraft\n§cOwner: " +
            owner.split(":")[0] +
            "\n§aBlock: " +
            block?.typeId
        );
  }
});

world.afterEvents.playerPlaceBlock.subscribe((scb) => {
  const { block, player } = scb;
  const loc = block.location;
  const blockUtils = new BlockUtils(block, player);
  blockUtils.bigReinforcedChestKeypadOnPlaced();
  blockUtils.bigReinforcedChestOnPlaced();
  blockUtils.reinforcedChestKeypadOnPlaced();
  blockUtils.reinforcedChestOnPlaced();
  blockUtils.keyPadOnPlaced();
  blockUtils.mineOnPlaced();
  blockUtils.cameraOnPlaced();
  blockUtils.scannerOnPlaced();
  blockUtils.reinforcedDoorOnPlaced();
  blockUtils.removePiston();
});

world.beforeEvents.chatSend.subscribe((scb) => {
  const { sender: player, message } = scb;
  const prefix = "scb:";
  const command = message.split(":")[1];
  if (message.startsWith(prefix) && player.isOp()) {
    if (command === "remove") {
      scb.cancel = true;
      system.run(() => {
        const scbEntity = player.getEntitiesFromViewDirection({
          maxDistance: 6,
        })[0]?.entity;
        if (scbEntity?.typeId.startsWith("scb:")) {
          const block = scbEntity?.dimension.getBlock(scbEntity.location);
          block.above(1)?.typeId.startsWith("scb:")
            ? block.above(1)?.setType("minecraft:air")
            : null;
          block?.setType("minecraft:air");
          scbEntity?.remove();
        } else {
          const block = player.getBlockFromViewDirection({
            maxDistance: 6,
          }).block;
          if (block?.typeId.startsWith("scb:")) block?.setType("minecraft:air");
          else
            block
              ?.above(1)
              .dimension.getBlock({ x: block?.x, y: block?.y + 1, z: block?.z })
              .typeId.startsWith("scb:")
              ? block?.above(1).setType("minecraft:air")
              : null;
        }
      });
    }
  }
});

system.runInterval(() => {
  world.gameRules.doFireTick = false;
  for (const player of world.getPlayers()) {
    const playerUtils = new PlayerUtils(player);
    playerUtils.scannerOpen();
  }
}, 20);
