import { world, system, Player, EntityComponentTypes, EquipmentSlot, ItemStack, ItemLockMode } from "@minecraft/server";
import { ActionFormData, ModalFormData } from "@minecraft/server-ui";
import { cooldownMap, twoTall } from "./block_randomizer";
const playerData = /* @__PURE__ */ new Map();
const CLICK_COOLDOWN = 200;
const clickIntervals = /* @__PURE__ */ new Map();
const blacklist = [
  "minecraft:end_portal_frame",
  "minecraft:reinforced_deepslate",
  "minecraft:bedrock"
];
const toolSet = /* @__PURE__ */ new Set([
  "maca_probuilder:rotate",
  "maca_probuilder:copy",
  "maca_probuilder:painter",
  "maca_probuilder:variant",
  "maca_probuilder:randomizer"
]);
const OGtoolSet = /* @__PURE__ */ new Set([
  "maca_probuilder:rotate",
  "maca_probuilder:copy",
  "maca_probuilder:painter",
  "maca_probuilder:variant",
  "maca_probuilder:editor_off",
  "maca_probuilder:editor_on"
]);
const vanillaTags = /* @__PURE__ */ new Set([
  "minecraft:is_pickaxe",
  "minecraft:is_axe",
  "minecraft:is_hoe",
  "minecraft:is_shovel",
  "minecraft:is_shears"
]);
system.runInterval(() => {
  const players = world.getAllPlayers();
  if (players.length == 0)
    return;
  for (const player of players) {
    const equippable = player.getComponent(EntityComponentTypes.Equippable);
    const itemStack = equippable.getEquipment(EquipmentSlot.Mainhand);
    const offhand = equippable.getEquipment(EquipmentSlot.Offhand);
    if (!player.hasTag("maca_pb:claw_active") && (!player.hasTag("maca_pb:exchange_selected") || itemStack?.typeId !== "maca_probuilder:exchange") && !toolSet.has(itemStack?.typeId) && player.hasTag("maca_pb:highlight_active")) {
      if (!playerData.has(player.id))
        return;
      player.removeTag("maca_pb:highlight_active");
      try {
        const data = playerData.get(player.id);
        if (data.intervalId != void 0) {
          const data2 = playerData.get(player.id);
          try {
            system.clearRun(data2.intervalId);
            data2.intervalId = null;
          } catch {
            data2.intervalId = null;
          }
          system.runTimeout(() => {
            if (data2.highlightEntity?.typeId != void 0) {
              try {
                data2.highlightEntity.triggerEvent("despawn");
                data2.highlightEntity = null;
              } catch {
                data2.highlightEntity = null;
              }
              if (!player.hasTag("maca_pb:exchange_selected")) {
                playerData.delete(player.id);
              }
            }
          });
        }
      } catch (e) {
        return;
      }
      return;
    } else if (!player.hasTag("maca_pb:highlight_active") && (player.hasTag("maca_pb:claw_active") || player.hasTag("maca_pb:exchange_selected") && itemStack?.typeId === "maca_probuilder:exchange" || toolSet.has(itemStack?.typeId))) {
      const highlightState = player.getDynamicProperty("maca_probuilder:highlight") == void 0 ? true : player.getDynamicProperty("maca_probuilder:highlight");
      if (highlightState == false) {
        if (!player.hasTag("maca:highlight_warning")) {
          player.onScreenDisplay.setActionBar(`Highlight has been disabled
Re-enable in builder tool menu settings`);
          player.addTag("maca:highlight_warning");
        }
        return;
      } else if (player.hasTag("maca:highlight_warning")) {
        player.removeTag("maca:highlight_warning");
      }
      let range = 8;
      if (player.hasTag("maca_pb:claw_active") && itemStack?.typeId !== "maca_probuilder:exchange") {
        range = 32;
      } else if (itemStack?.typeId === "maca_probuilder:exchange")
        range = 48;
      player.addTag("maca_pb:highlight_active");
      highlightInterval(player, range);
    }
  }
}, 2);
world.afterEvents.itemStartUse.subscribe((event) => {
  const player = event.source;
  const item = event.itemStack;
  if (item?.typeId !== "maca_probuilder:exchange" || player.isSneaking)
    return;
  if (!playerData.has(player.id))
    return;
  const blockData = playerData.get(player.id);
  if (blockData.setBlock == void 0)
    return;
  const currentTime = Date.now();
  if (!cooldownMap.has(player.id)) {
    cooldownMap.set(player.id, { lastClickTime: currentTime - (CLICK_COOLDOWN + 100) });
  }
  const data = cooldownMap.get(player.id);
  if (data.lastClickTime - currentTime < CLICK_COOLDOWN) {
    data.lastClickTime = currentTime;
    if (clickIntervals.has(player.id))
      return;
    system.run(() => {
      swapBlocks(player);
      clickInterval(player);
    });
  } else {
    data.lastClickTime = currentTime;
  }
});
function clickInterval(player) {
  const interval = system.runInterval(() => {
    swapBlocks(player);
  }, 4);
  clickIntervals.set(player.id, interval);
}
world.afterEvents.itemStopUse.subscribe((event) => {
  const player = event.source;
  const item = event.itemStack;
  if (item?.typeId !== "maca_probuilder:exchange")
    return;
  if (!clickIntervals.has(player.id))
    return;
  const interval = clickIntervals.get(player.id);
  system.clearRun(interval);
  clickIntervals.delete(player.id);
  return;
});
world.beforeEvents.itemUse.subscribe((event) => {
  const player = event.source;
  const item = event.itemStack;
  if (item?.typeId !== "maca_probuilder:exchange")
    return;
  if (player.isSneaking) {
    event.cancel = true;
    system.run(() => {
      buildToolMenu(player);
    });
    return;
  }
});
world.afterEvents.entityHitBlock.subscribe((e) => {
  const { damagingEntity: player, hitBlock: block } = e;
  if (!(player instanceof Player))
    return;
  const currentTime = Date.now();
  if (!cooldownMap.has(player.id)) {
    cooldownMap.set(player.id, { lastClickTime: currentTime - 200 });
  }
  const cooldown = cooldownMap.get(player.id);
  if (currentTime - cooldown.lastClickTime < 200) {
    return;
  } else {
    cooldownMap.set(player.id, { lastClickTime: currentTime });
  }
  const inventory = player.getComponent("equippable");
  const itemStack = inventory.getEquipment("Mainhand");
  const offHand = inventory.getEquipment("Offhand");
  const data = playerData.get(player.id);
  if (itemStack == void 0 && offHand?.typeId !== "maca_probuilder:claw_on" && offHand?.typeId !== "maca_probuilder:claw_off")
    return;
  if (player.isSneaking) {
    if (itemStack?.typeId === "maca_probuilder:exchange") {
      player.removeTag("maca_pb:exchange_selected");
    }
    if (itemStack?.typeId === "maca_probuilder:claw_on" || offHand?.typeId === "maca_probuilder:claw_on") {
      data.clawSwap = data.clawSwap ? false : true;
      system.run(() => {
        player.playSound(`maca_probuilder.tool.editor_${data.clawSwap ? "on" : "off"}`);
        player.onScreenDisplay.setActionBar(`Replace Blocks Mode: ${data.clawSwap ? "On" : "Off"}`);
      });
      playerData.set(player.id, data);
    }
    if (itemStack?.typeId === "maca_probuilder:randomizer") {
      const data2 = playerData.get(player.id);
      data2.randomSwap = data2.randomSwap ? false : true;
      system.run(() => {
        player.playSound(`maca_probuilder.tool.editor_${data2.randomSwap ? "on" : "off"}`);
        player.onScreenDisplay.setActionBar(`Replace Blocks Mode: ${data2.randomSwap ? "On" : "Off"}`);
      });
      playerData.set(player.id, data2);
    }
    return;
  }
  let vanilla = false;
  for (const tag of vanillaTags) {
    if (itemStack != void 0 && itemStack?.hasTag(tag)) {
      vanilla = true;
    }
  }
  if (!OGtoolSet.has(itemStack?.typeId) && itemStack?.typeId !== "maca_probuilder:exchange" && !vanilla) {
    const equippableComponent = player.getComponent(EntityComponentTypes.Equippable);
    if (offHand?.typeId === "maca_probuilder:claw_on") {
      equippableComponent.setEquipment(EquipmentSlot.Offhand, new ItemStack("maca_probuilder:claw_off"));
      player.playSound("maca_probuilder.tool.editor_off");
      if (data.highlightEntity?.typeId != void 0) {
        try {
          data.highlightEntity.triggerEvent("despawn");
          data.highlightEntity = null;
        } catch {
          data.highlightEntity = null;
        }
      }
      if (data.intervalId != void 0) {
        try {
          system.clearRun(data.intervalId);
          data.intervalId = null;
        } catch {
          data.intervalId = null;
        }
      }
      player.removeTag("maca_pb:claw_active");
      player.removeTag("maca_pb:highlight_active");
      return;
    } else if (offHand?.typeId === "maca_probuilder:claw_off") {
      player.addTag("maca_pb:claw_active");
      let activeItem = new ItemStack("maca_probuilder:claw_on");
      activeItem.lockMode = ItemLockMode.inventory;
      equippableComponent.setEquipment(EquipmentSlot.Offhand, activeItem);
      player.playSound("maca_probuilder.tool.editor_on");
      if (data.highlightEntity?.typeId != void 0) {
        try {
          data.highlightEntity.triggerEvent("despawn");
          data.highlightEntity = null;
        } catch {
          data.highlightEntity = null;
        }
      }
      if (data.intervalId != void 0) {
        try {
          system.clearRun(data.intervalId);
          data.intervalId = null;
        } catch {
          data.intervalId = null;
        }
      }
      return;
    }
  }
  if (itemStack?.typeId !== "maca_probuilder:exchange" && itemStack?.typeId !== "maca_probuilder:randomizer" && itemStack?.typeId !== "maca_probuilder:claw_off" && itemStack?.typeId !== "maca_probuilder:claw_on")
    return;
  system.run(() => {
    const equippableComponent = player.getComponent(EntityComponentTypes.Equippable);
    let time = Date.now();
    if (!playerData.has(player.id)) {
      playerData.set(player.id, { setBlock: block.typeId, intervalId: 0, highlightEntity: {}, permutations: void 0, randomSwap: false, clawSwap: false, blockItems: [], clickedBlockLocation: {}, clickedBlockFace: void 0 });
    }
    switch (itemStack.typeId) {
      case "maca_probuilder:exchange":
        const data2 = playerData.get(player.id);
        if (twoTall.has(block.typeId)) {
          player.playSound("maca_probuilder.tool.wrong_block");
          player.onScreenDisplay.setActionBar(`Two tall blocks cannot be used with the Exchange Tool`);
          return;
        }
        data2.setBlock = block.typeId;
        data2.permutations = block.permutation.getAllStates();
        system.run(() => {
          player.playSound("maca_probuilder.tool.editor_on");
          player.onScreenDisplay.setActionBar(`Selected block type: ${block.typeId.split(":")[1].replace("_", " ").toUpperCase()}`);
          system.runTimeout(() => {
            player.onScreenDisplay.setActionBar("Crouch and punch a block to disable");
          }, 80);
          player.addTag("maca_pb:exchange_selected");
        });
        break;
      case "maca_probuilder:randomizer":
        break;
      case "maca_probuilder:claw_on":
        equippableComponent.setEquipment(EquipmentSlot.Mainhand, new ItemStack("maca_probuilder:claw_off"));
        player.playSound("maca_probuilder.tool.editor_off");
        player.removeTag("maca_pb:claw_active");
        break;
      case "maca_probuilder:claw_off":
        player.addTag("maca_pb:claw_active");
        let activeItem = new ItemStack("maca_probuilder:claw_on");
        activeItem.lockMode = ItemLockMode.inventory;
        equippableComponent.setEquipment(EquipmentSlot.Mainhand, activeItem);
        player.playSound("maca_probuilder.tool.editor_on");
        break;
    }
    return;
  });
});
function swapBlocks(player) {
  const raycast = player.getBlockFromViewDirection({ maxDistance: 48 });
  if (!raycast || !raycast.block)
    return;
  const block = raycast.block;
  const blockID = raycast.block.typeId;
  if (blacklist.includes(block.typeId))
    return;
  const blockInventory = block.getComponent("inventory")?.container;
  if (blockInventory != void 0) {
    player.playSound("maca_probuilder.tool.wrong_block");
    return;
  }
  const data = playerData.get(player.id);
  const hasBlocks = checkInventory(data.setBlock, player);
  if (hasBlocks != null || player.getGameMode() === "creative") {
    if (data.setBlock === block.typeId)
      return;
    if (twoTall.has(block.typeId)) {
      if (block.below().typeId === block.typeId) {
        block.below().setType("air");
      }
      if (block.above().typeId === block.typeId) {
        block.above().setType("air");
      }
    }
    block.setType(data.setBlock);
    if (data.permutations) {
      for (const [perm, value] of Object.entries(data.permutations)) {
        block.setPermutation(block.permutation.withState(perm, value));
      }
    }
    player.dimension.playSound("maca_probuilder.tool.paste", block.location);
    decrementStack(player, hasBlocks, blockID);
  } else {
    player.playSound("maca_probuilder.tool.wrong_block");
    system.clearRun(data.intervalId);
    data.highlightEntity.triggerEvent("despawn");
    playerData.delete(player.id);
  }
}
function checkInventory(blockType, player) {
  const inventory = player.getComponent("inventory").container;
  for (let i = 0; i < inventory.size; i++) {
    const item = inventory.getItem(i);
    if (item?.typeId === blockType) {
      return i;
    }
  }
  return null;
}
function decrementStack(player, index, blockID) {
  if (player.getGameMode() === "creative")
    return;
  if (blockID != false) {
    player.runCommand(`gamerule sendcommandfeedback false`);
    player.runCommand(`give @s ${blockID} 1`);
    player.runCommand(`gamerule sendcommandfeedback true`);
  }
  const inventory = player.getComponent("inventory").container;
  let item = inventory.getItem(index);
  if (item.amount == 1) {
    inventory.setItem(index, void 0);
  } else {
    item.amount--;
    inventory.setItem(index, item);
  }
}
function spawnParticleCube(spawnLoc, x, y, z, player) {
  const opacity = player.getDynamicProperty("maca_probuilder:opacity") || "opacity4";
  let highlight = player.dimension.spawnEntity(`maca_probuilder:highlight_entity<${opacity}>`, spawnLoc);
  highlight.setProperty("maca_probuilder:active", true);
  highlight.setProperty("maca_probuilder:height", y);
  highlight.setProperty("maca_probuilder:width", z);
  highlight.setProperty("maca_probuilder:length", x);
  return highlight;
}
function highlightInterval(player, range) {
  let lastPos = void 0;
  const data = playerData.get(player.id) || {};
  if (data.highlightEntity?.typeId != void 0) {
    try {
      data.highlightEntity.triggerEvent("despawn");
      data.highlightEntity = null;
    } catch {
      data.highlightEntity = null;
    }
  }
  if (data.intervalId != void 0) {
    try {
      system.clearRun(data.intervalId);
      data.intervalId = null;
    } catch {
      data.intervalId = null;
    }
  }
  data.intervalId = system.runInterval(() => {
    const highlightState = player.getDynamicProperty("maca_probuilder:highlight") == void 0 ? true : player.getDynamicProperty("maca_probuilder:highlight");
    const equippable = player.getComponent("equippable");
    const item = equippable.getEquipment("Mainhand");
    const raycast = player.getBlockFromViewDirection({ maxDistance: range });
    if (!raycast || !raycast.block || !highlightState) {
      if (data.highlightEntity?.typeId != void 0) {
        try {
          data.highlightEntity.triggerEvent("despawn");
          data.highlightEntity = null;
        } catch {
          data.highlightEntity = null;
        }
      }
      return;
    }
    let spawnPos = raycast.block;
    if (data?.clawSwap == false && item?.typeId !== "maca_probuilder:randomizer" && item?.typeId !== "maca_probuilder:exchange" && !item?.hasTag("minecraft:is_axe") && !item?.hasTag("minecraft:is_shovel") && !item?.hasTag("minecraft:is_hoe") || data?.randomSwap == false && item?.typeId === "maca_probuilder:randomizer" && !OGtoolSet.has(item?.typeId) && !player.hasTag("maca_probuilder:editormode") && !raycast.block.typeId.includes("door")) {
      switch (raycast.face.toLowerCase()) {
        case "up":
          spawnPos = raycast.block.above();
          break;
        case "down":
          spawnPos = raycast.block.below();
          break;
        case "east":
          spawnPos = raycast.block.east();
          break;
        case "west":
          spawnPos = raycast.block.west();
          break;
        case "north":
          spawnPos = raycast.block.north();
          break;
        case "south":
          spawnPos = raycast.block.south();
          break;
      }
      spawnPos = { x: spawnPos.x + 0.5, y: spawnPos.y, z: spawnPos.z + 0.5 };
    } else {
      spawnPos = { x: raycast.block.x + 0.5, y: raycast.block.y, z: raycast.block.z + 0.5 };
    }
    if (lastPos != void 0) {
      if (JSON.stringify(spawnPos) === JSON.stringify(lastPos))
        return;
      if (data.highlightEntity?.typeId != void 0) {
        try {
          data.highlightEntity.triggerEvent("despawn");
          data.highlightEntity = null;
        } catch {
          data.highlightEntity = null;
        }
      }
      data.highlightEntity = spawnParticleCube(spawnPos, 1, 1, 1, player);
    } else {
      data.highlightEntity = spawnParticleCube(spawnPos, 1, 1, 1, player);
    }
    lastPos = spawnPos;
    playerData.set(player.id, data);
    savePlayerData();
  }, 2);
}
function buildToolMenu(player) {
  let toolForm = new ActionFormData().title("Builder Tools");
  toolForm.button("Exchange Tool", "textures/maca/probuilder/items/exchanger");
  toolForm.button("Randomizer Tool", "textures/maca/probuilder/items/block_randomizer");
  toolForm.button("Claw Tool", "textures/maca/probuilder/items/claw_tool_on");
  toolForm.button("Settings", "textures/gui/newgui/anvil-hammer");
  player.playSound(`maca_probuilder.tool.menu`);
  toolForm.show(player).then((response) => {
    if (response.canceled)
      return;
    const equippableComponent = player.getComponent(EntityComponentTypes.Equippable);
    switch (response.selection) {
      case 0:
        equippableComponent.setEquipment(EquipmentSlot.Mainhand, new ItemStack("maca_probuilder:exchange"));
        break;
      case 1:
        equippableComponent.setEquipment(EquipmentSlot.Mainhand, new ItemStack("maca_probuilder:randomizer"));
        break;
      case 2:
        equippableComponent.setEquipment(EquipmentSlot.Mainhand, new ItemStack("maca_probuilder:claw_off"));
        break;
      case 3:
        settingsMenu(player);
        break;
      default:
        break;
    }
  }).catch((e) => {
    console.error(e, e.stack);
  });
}
function settingsMenu(player) {
  const highlight = player.getDynamicProperty("maca_probuilder:highlight") == true ? true : false;
  const opacity = player.getDynamicProperty("maca_probuilder:opacity") == void 0 ? 4 : player.getDynamicProperty("maca_probuilder:opacity").split("opacity")[1];
  const settingsForm = new ModalFormData().title("Highlight Settings").slider("Select Opacity", 1, 4, 1, parseInt(opacity)).toggle("Highlight on/off", highlight);
  settingsForm.show(player).then((response) => {
    if (response.canceled)
      return;
    player.setDynamicProperty("maca_probuilder:opacity", `opacity${response.formValues[0]}`);
    player.setDynamicProperty("maca_probuilder:highlight", response.formValues[1]);
    system.run(() => {
      player.removeTag("maca_pb:highlight_active");
      const equippableComponent = player.getComponent(EntityComponentTypes.Equippable);
      const offHand = equippableComponent.getEquipment(EquipmentSlot.Offhand);
      if (offHand?.typeId === "maca_probuilder:claw_on") {
        player.addTag("maca_pb:claw_active");
      }
    });
  }).catch((error) => {
    console.error(error, error.stack);
  });
}
function savePlayerData() {
  const data = {
    PlayerIds: Object.fromEntries(playerData)
  };
  world.setDynamicProperty("maca_sd:ToolData", JSON.stringify(data));
}
function loadPlayerData() {
  const data = world.getDynamicProperty("maca_sd:ToolData");
  if (data) {
    try {
      const parsedData = JSON.parse(data);
      playerData.clear();
      if (parsedData.PlayerIds) {
        for (const [key, value] of Object.entries(parsedData.PlayerIds)) {
          playerData.set(key, value);
        }
      }
    } catch (error) {
      console.error(`Error parsing door data: ${error}`);
    }
  }
}
export {
  buildToolMenu,
  decrementStack,
  loadPlayerData,
  playerData
};
