import { world, system, ItemStack, Player } from "@minecraft/server";
const DATA_KEY = "maca_probuilder:crate_data";
const crateLocations = /* @__PURE__ */ new Map();
const flowerSet = /* @__PURE__ */ new Set([
  "minecraft:dandelion",
  "minecraft:poppy",
  "minecraft:blue_orchid",
  "minecraft:allium",
  "minecraft:azure_bluet",
  "minecraft:red_tulip",
  "minecraft:orange_tulip",
  "minecraft:white_tulip",
  "minecraft:pink_tulip",
  "minecraft:cornflower",
  "minecraft:lily_of_the_valley",
  "minecraft:wither_rose",
  "mincraft:oxeye_daisy"
]);
const flowerStates = {
  "minecraft:dandelion": 2,
  "minecraft:poppy": 1,
  "minecraft:blue_orchid": 4,
  "minecraft:allium": 3,
  "minecraft:azure_bluet": 6,
  "minecraft:red_tulip": 11,
  "minecraft:orange_tulip": 9,
  "minecraft:white_tulip": 12,
  "minecraft:pink_tulip": 10,
  "minecraft:cornflower": 5,
  "minecraft:lily_of_the_valley": 7,
  "mincraft:oxeye_daisy": 8,
  "minecraft:wither_rose": 13
};
const crateId = {
  "minecraft:potato": 5,
  "minecraft:bread": 1,
  "minecraft:carrot": 2,
  "minecraft:beetroot": 3,
  "minecraft:apple": 4,
  "minecraft:melon": 6,
  "minecraft:glow_berries": 7,
  "minecraft:sweet_berries": 8,
  "minecraft:reeds": 9,
  "minecraft:wheat": 10
};
const crateItems = /* @__PURE__ */ new Set([
  "minecraft:potato",
  "minecraft:bread",
  "minecraft:carrot",
  "minecraft:beetroot",
  "minecraft:apple",
  "minecraft:melon",
  "minecraft:glow_berries",
  "minecraft:sweet_berries",
  "minecraft:reeds",
  "minecraft:wheat"
]);
const maxQty = 3456;
world.beforeEvents.worldInitialize.subscribe(({ blockComponentRegistry }) => {
  blockComponentRegistry.registerCustomComponent("maca_probuilder:crates", crateComponent);
  blockComponentRegistry.registerCustomComponent("maca_probuilder:crate_items", crateItemsComponent);
  blockComponentRegistry.registerCustomComponent("maca_probuilder:flower_break", destroyFlowerComponent);
  loadCrateData();
});
world.afterEvents.blockExplode.subscribe((e) => {
  const { dimension, block, explodedBlockPermutation, source } = e;
  if (!explodedBlockPermutation.hasTag("maca_probuilder:is_crate") && !explodedBlockPermutation.hasTag("maca_probuilder:is_flowerBlock") && !explodedBlockPermutation.hasTag("maca_probuilder:is_flowerPot"))
    return;
  if (explodedBlockPermutation.hasTag("maca_probuilder:is_crate")) {
    if (explodedBlockPermutation.type.id.includes("items")) {
      handleBreakCrates(block, dimension, source, explodedBlockPermutation, true);
    } else {
      handleBreakCrates(block, dimension, source, explodedBlockPermutation, false);
    }
  } else {
    if (explodedBlockPermutation.hasTag("maca_probuilder:is_flowerBlock")) {
      handleBreakFlowers(dimension, block, explodedBlockPermutation, source, true);
    } else {
      handleBreakFlowers(dimension, block, explodedBlockPermutation, source, false);
    }
  }
});
world.afterEvents.entityHitBlock.subscribe((e) => {
  const { damagingEntity, hitBlock } = e;
  if (!hitBlock.hasTag("maca_probuilder:is_crate"))
    return;
  if (!(damagingEntity instanceof Player))
    return;
  const inventory = damagingEntity.getComponent("equippable");
  const itemStack = inventory.getEquipment("Mainhand");
  if (itemStack?.typeId === "maca_probuilder:painter" || itemStack?.typeId === "maca_probuilder:rotate" || itemStack?.typeId === "maca_probuilder:copy" || itemStack?.typeId === "maca_probuilder:variant" || itemStack?.typeId.includes("editor"))
    return;
  if (damagingEntity.getGameMode() === "creative")
    return;
  const player = damagingEntity;
  const blockLocation = hitBlock.typeId === "maca_probuilder:crate_items" ? hitBlock.below().location : hitBlock.location;
  const blockLocationString = `${Math.floor(blockLocation.x)},${Math.floor(blockLocation.y)},${Math.floor(blockLocation.z)},${hitBlock.dimension.id}`;
  const data = crateLocations.get(blockLocationString);
  if (!data)
    return;
  if (player.isSneaking) {
    let dropQty = data.qty;
    const dropItem = data.item;
    if (dropQty <= 64) {
      incrementStack(player, dropItem, dropQty);
      crateLocations.delete(blockLocationString);
      saveCrateData();
      if (hitBlock.typeId.includes("items")) {
        hitBlock.setType("minecraft:air");
      } else {
        hitBlock.above().setType("minecraft:air");
      }
    } else {
      dropQty = dropQty - 64;
      incrementStack(player, dropItem, 64);
      crateLocations.set(blockLocationString, { item: data.item, qty: dropQty, ownerId: player.id });
      player.onScreenDisplay.setActionBar(`${dropQty} ${data.item.split(":")[1]} item${dropQty > 1 ? "s" : ""} remaining`);
      saveCrateData();
    }
  } else {
    let qty = data.qty;
    qty--;
    incrementStack(player, data.item, 1);
    if (qty != 0) {
      player.onScreenDisplay.setActionBar(`${qty} ${data.item.split(":")[1]} item${qty > 1 ? "s" : ""} remaining`);
      crateLocations.set(blockLocationString, { item: data.item, qty, ownerId: player.id });
      saveCrateData();
    } else {
      crateLocations.delete(blockLocationString);
      saveCrateData();
      if (hitBlock.typeId.includes("items")) {
        hitBlock.setType("minecraft:air");
      } else {
        hitBlock.above().setType("minecraft:air");
      }
    }
  }
  return;
});
let count = 0;
world.beforeEvents.itemUseOn.subscribe((data) => {
  const { block, source: player, itemStack } = data;
  if (!block.hasTag("maca_probuilder:is_crate") && block.typeId !== "maca_probuilder:window_planter")
    return;
  if (itemStack.typeId.includes("maca_probuilder"))
    return;
  count++;
  if (count != 1)
    return;
  system.runTimeout(() => {
    count = 0;
  }, 10);
  if (!(player instanceof Player))
    return;
  const inventory = player.getComponent("equippable");
  if (itemStack == void 0)
    return;
  if (block.hasTag("maca_probuilder:is_crate")) {
    const blockLocation = block.typeId === "maca_probuilder:crate_items" ? block.below().location : block.location;
    const blockLocationString = `${Math.floor(blockLocation.x)},${Math.floor(blockLocation.y)},${Math.floor(blockLocation.z)},${block.dimension.id}`;
    if (crateItems.has(itemStack?.typeId) && crateLocations.has(blockLocationString)) {
      system.runTimeout(() => {
        const data2 = crateLocations.get(blockLocationString);
        if (data2.item !== itemStack?.typeId)
          return;
        if (player.isSneaking) {
          let qty = data2.qty + itemStack.amount;
          if (data2.qty >= maxQty) {
            player.onScreenDisplay.setActionBar(`Storage full: ${qty} items`);
            return;
          }
          if (qty >= maxQty) {
            let partialStack = qty - maxQty;
            itemStack.amount = partialStack;
            inventory.setEquipment("Mainhand", itemStack);
            crateLocations.set(blockLocationString, { item: itemStack.typeId, qty: maxQty, ownerId: player.id });
            player.onScreenDisplay.setActionBar(`Storage full: ${qty} items`);
            saveCrateData();
            return;
          }
          inventory.setEquipment("Mainhand", void 0);
          crateLocations.set(blockLocationString, { item: itemStack.typeId, qty, ownerId: player.id });
          player.onScreenDisplay.setActionBar(`${qty} ${itemStack.typeId.split(":")[1]} items in storage`);
          saveCrateData();
          try {
            restock(player.getComponent("inventory"), player.selectedSlotIndex, itemStack);
          } catch (error) {
            console.warn(error);
          }
          return;
        } else {
          let qty = data2.qty;
          if (qty >= maxQty) {
            player.onScreenDisplay.setActionBar(`Storage full: ${qty} items`);
            return;
          }
          qty++;
          decrementStack(player);
          crateLocations.set(blockLocationString, { item: itemStack.typeId, qty, ownerId: player.id });
          player.onScreenDisplay.setActionBar(`${qty} ${itemStack.typeId.split(":")[1]} items in storage`);
          saveCrateData();
          return;
        }
      });
    }
    if (crateItems.has(itemStack?.typeId) && !crateLocations.has(blockLocationString)) {
      system.runTimeout(() => {
        crateStorage(itemStack, player, block);
        player.onScreenDisplay.setActionBar(`1 ${itemStack.typeId.split(":")[1]} item in storage`);
        return;
      });
    }
  } else {
    if (flowerSet.has(itemStack.typeId)) {
      if (block.above().typeId !== "minecraft:air")
        return;
      data.cancel = true;
      system.run(() => {
        block.above()?.setType("maca_probuilder:flowers_half_block");
        const flowerBlock = block.dimension.getBlock({ x: block.location.x, y: block.location.y + 1, z: block.location.z });
        const newState = flowerStates[itemStack.typeId];
        const dir = block.permutation.getState("minecraft:cardinal_direction");
        flowerBlock?.setPermutation(
          flowerBlock.permutation.withState("maca_probuilder:texture_bit_0", newState).withState("minecraft:cardinal_direction", dir)
        );
        decrementStack(player);
      });
    }
  }
});
const crateComponent = {
  onPlayerDestroy(e) {
    const { dimension, block, destroyedBlockPermutation, player } = e;
    handleBreakCrates(block, dimension, player, destroyedBlockPermutation, true);
  }
};
const destroyFlowerComponent = {
  onPlayerDestroy(e) {
    const { dimension, block, destroyedBlockPermutation, player } = e;
    const isFlower = destroyedBlockPermutation.hasTag("maca_probuilder:is_flowerBlock") || false;
    handleBreakFlowers(dimension, block, destroyedBlockPermutation, player, isFlower, block.above());
  }
};
const crateItemsComponent = {
  onPlayerDestroy(e) {
    const { dimension, block, destroyedBlockPermutation, player } = e;
    handleBreakCrates(block, dimension, player, destroyedBlockPermutation, false);
  }
};
function getItemTypeFromState(stateValue, object) {
  for (const [key, value] of Object.entries(object)) {
    if (value === stateValue) {
      return key;
    }
  }
  return null;
}
function handleBreakCrates(block, dimension, player, destroyedBlockPermutation, breakBottom) {
  if (breakBottom) {
    const blockLocation = block.below().location;
    const blockLocationString = `${Math.floor(blockLocation.x)},${Math.floor(blockLocation.y)},${Math.floor(blockLocation.z)},${dimension.id}`;
    const storage = crateLocations.get(blockLocationString);
    if (!storage || storage == null || storage == void 0) {
      const stateValue = destroyedBlockPermutation.getState("maca_probuilder:texture_bit_0");
      let dropItem2 = getItemTypeFromState(stateValue, crateId);
      if (dropItem2 == null) {
        dropItem2 = "minecraft:scaffolding";
      }
      const item = new ItemStack(dropItem2, 1);
      dimension.spawnItem(item, block.location);
      if (player instanceof Player) {
        player.onScreenDisplay.setActionBar(`this is no longer a block item, now available only when used as storage`);
      }
      return;
    }
    const dropItem = storage.item;
    const dropQty = storage.qty;
    if (dropQty <= 64) {
      const items = new ItemStack(dropItem, dropQty);
      dimension.spawnItem(items, block.location);
      crateLocations.delete(blockLocationString);
      saveCrateData();
    } else {
      for (let remaining = dropQty; remaining > 0; remaining = remaining - 64) {
        system.runTimeout(() => {
          if (remaining > 64) {
            const items = new ItemStack(dropItem, 64);
            dimension.spawnItem(items, block.location);
          } else {
            const items = new ItemStack(dropItem, remaining);
            dimension.spawnItem(items, block.location);
            crateLocations.delete(blockLocationString);
            saveCrateData();
            return;
          }
        });
      }
    }
  } else {
    const maxStack = 64;
    const blockLocationString = `${Math.floor(block.location.x)},${Math.floor(block.location.y)},${Math.floor(block.location.z)},${dimension.id}`;
    const storage = crateLocations.get(blockLocationString);
    if (!storage || storage == null || storage == void 0)
      return;
    block.above().setType("minecraft:air");
    const dropItem = storage.item;
    const dropQty = storage.qty;
    if (dropQty <= maxStack) {
      const items = new ItemStack(dropItem, dropQty);
      dimension.spawnItem(items, block.location);
      crateLocations.delete(blockLocationString);
      saveCrateData();
    } else {
      for (let remaining = dropQty; remaining > 0; remaining = remaining - maxStack) {
        system.runTimeout(() => {
          if (remaining > 64) {
            const items = new ItemStack(dropItem, maxStack);
            dimension.spawnItem(items, block.location);
          } else {
            const items = new ItemStack(dropItem, remaining);
            dimension.spawnItem(items, block.location);
            crateLocations.delete(blockLocationString);
            saveCrateData();
            return;
          }
        });
      }
    }
  }
}
function handleBreakFlowers(dimension, block, destroyedBlockPermutation, player, isFlower) {
  if (isFlower) {
    let dropItem;
    const brokenPerm = destroyedBlockPermutation.getState("maca_probuilder:texture_bit_0");
    if (brokenPerm == 0) {
      dropItem = "minecraft:scaffolding";
      if (player instanceof Player) {
        player.onScreenDisplay.setActionBar(`this is no longer a block item, use the desired flower item instead`);
      }
    } else {
      dropItem = getItemTypeFromState(brokenPerm, flowerStates);
    }
    const stack = new ItemStack(dropItem, 1);
    dimension.spawnItem(stack, block.location);
    return;
  } else {
    const brokenBlock = block.above();
    if (!brokenBlock || brokenBlock?.typeId === "minecraft:air" || !brokenBlock.hasTag("maca_probuilder:is_flowerBlock"))
      return;
    let dropItem;
    const brokenPerm = brokenBlock.permutation.getState("maca_probuilder:texture_bit_0");
    if (brokenPerm == 0) {
      dropItem = "minecraft:scaffolding";
      if (player instanceof Player) {
        player.onScreenDisplay.setActionBar(`this is no longer a block item, use the desired flower item instead`);
      }
    } else {
      dropItem = getItemTypeFromState(brokenPerm, flowerStates);
    }
    dimension.playSound("random_pop", brokenBlock.location);
    brokenBlock.setType("minecraft:air");
    const stack = new ItemStack(dropItem, 1);
    dimension.spawnItem(stack, brokenBlock.location);
  }
}
function restock(inventory, selectedSlot, selectedBlock) {
  for (let i = 9; i < inventory.container.size; i++) {
    const invItem = inventory.container.getItem(i);
    if (invItem && invItem.typeId === selectedBlock.typeId) {
      const transferAmount = invItem.amount;
      selectedBlock.amount = transferAmount;
      inventory.container.setItem(selectedSlot, selectedBlock);
      inventory.container.setItem(i, void 0);
      break;
    }
  }
}
function crateStorage(itemStack, player, block) {
  const blockLocation = block.location;
  const dimension = block.dimension;
  const blockLocationString = `${Math.floor(blockLocation.x)},${Math.floor(blockLocation.y)},${Math.floor(blockLocation.z)},${dimension.id}`;
  const crateData = crateLocations.get(blockLocationString);
  if (!crateData) {
    const above = block.above();
    if (above.typeId !== "minecraft:air")
      return;
    above.setType("maca_probuilder:crate_items");
    const cropBlock = dimension.getBlock({ x: blockLocation.x, y: blockLocation.y + 1, z: blockLocation.z });
    const dir = block.permutation.getState("minecraft:cardinal_direction");
    const texture = crateId[itemStack.typeId];
    cropBlock.setPermutation(
      cropBlock.permutation.withState("maca_probuilder:texture_bit_0", texture).withState("minecraft:cardinal_direction", dir)
    );
    decrementStack(player);
    crateLocations.set(blockLocationString, { item: itemStack.typeId, qty: 1, ownerId: player.id });
    saveCrateData();
    return;
  }
  decrementStack(player);
}
function decrementStack(player) {
  const inventory = player.getComponent("equippable");
  const selectedItem = inventory.getEquipment("Mainhand");
  if (selectedItem != void 0 && player.getGameMode() !== "creative") {
    if (selectedItem.amount === 1) {
      inventory.setEquipment("Mainhand", void 0);
    } else {
      selectedItem.amount -= 1;
      inventory.setEquipment("Mainhand", selectedItem);
    }
  }
}
function incrementStack(player, item, qty) {
  player.runCommand(`gamerule sendcommandfeedback false`);
  player.runCommand(`give @s ${item} ${qty}`);
  player.runCommand(`gamerule sendcommandfeedback true`);
}
function saveCrateData() {
  const crateData = {
    crates: Object.fromEntries(crateLocations)
  };
  world.setDynamicProperty(DATA_KEY, JSON.stringify(crateData));
}
function loadCrateData() {
  const crateData = world.getDynamicProperty(DATA_KEY);
  if (crateData) {
    try {
      const parsedData = JSON.parse(crateData);
      crateLocations.clear();
      for (const [key, value] of Object.entries(parsedData.crates)) {
        crateLocations.set(key, value);
      }
    } catch (error) {
      console.error(`Error parsing crate data: ${error}`);
    }
  }
}
