import { world, system, ItemStack } from "@minecraft/server";
import { ItemInventoryContents } from "../utilities.js";
import { torchLauncher } from "./torchLauncher.js";
import { bridgeBuilder } from "./bridgeBuilder.js";
import { barrierBuilder } from "./barrierBuilder.js";
import { summonSnowman } from "./summonSnowman.js";
import { handleShockwave } from "./handleShockwave.js";
import { recallHome } from "./recallHome.js";
import { biomeScanner } from "./biomeScanner.js";
import { bottomlessBucket } from "./bottomlessBucket.js";
import { wateringCan } from "./wateringCan.js";
import { handleEmptyChestJack, handleLoadedChestJack } from "./chestJack.js";
import { handleMirror } from "./handleMirror.js";
import { handleGauntlet } from "./handleGauntlet.js";
import { handleGrapplingHook } from "./handleGrapplingHook.js";
import { playerEquippedItem } from "../blocks/multiblockUtility.js";

const DEFAULT_COOLDOWN = 50;
const UPGRADE_COOLDOWN = 20;

world.afterEvents.itemUse.subscribe((event) => {
  handleGadgetUse(event.source, event.itemStack);
});

// New block interaction handling - this allows for gadgets to be used when clicking whilst looking at a bridge block
world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
  const player = event.player;
  const { selectedItem } = playerEquippedItem(player);
  const block = event.block;
  if (!block) return;

  if (
    block.typeId === "pb_gat:ember_block" ||
    block.typeId === "pb_gat:bridge_block" ||
    block.typeId === "pb_gat:bridge_block_life" ||
    block.typeId === "pb_gat:ember_bridge_block" ||
    block.typeId === "pb_gat:ember_bridge_block_life"
  ) {
    if (selectedItem) {
      // Defer to normal runtime so we have privileges
      system.run(() => {
        handleGadgetUse(player, selectedItem, true);
      });
    }
  }
});

function handleGadgetUse(player, item, fromBlockInteraction = false) {
  if (!item) return;

  // Cooldown handling
  const cooldown = item.getComponent("minecraft:cooldown");
  if (!cooldown) return;
  const ticks = cooldown.getCooldownTicksRemaining(player);

  // Default and upgrade cooldown logic
  let forcedCooldown = DEFAULT_COOLDOWN;
  let contents = [];
  const result = new ItemInventoryContents(item).getContainer();
  contents = result?.content ?? [];
  const hasCooldownUpgrade = contents.some(
    (stack) => stack?.typeId === "pb_gat:orb_cooldown"
  );
  if (hasCooldownUpgrade) forcedCooldown = UPGRADE_COOLDOWN;

  // Helper to decide if gadget should trigger
  function canUse(requiredTicks) {
    return fromBlockInteraction ? ticks === 0 : ticks >= requiredTicks;
  }

  // Match gadgets
  switch (item.typeId) {
    case "pb_gat:gadget_bridge_builder":
      if (canUse(forcedCooldown - 2)) {
        player.startItemCooldown("pb_bridge_builder", forcedCooldown);
        bridgeBuilder(player, item);
      }
      break;

    case "pb_gat:gadget_torch_launcher":
      if (canUse(forcedCooldown - 2)) {
        player.startItemCooldown("pb_torch_launcher", forcedCooldown);
        torchLauncher(player, item);
      }
      break;

    case "pb_gat:gadget_barrier":
      if (canUse(forcedCooldown - 2)) {
        player.startItemCooldown("pb_barrier", forcedCooldown);
        barrierBuilder(player, item);
      }
      break;

    case "pb_gat:gadget_snowman":
      if (canUse(forcedCooldown - 2)) {
        player.startItemCooldown("pb_snowman", forcedCooldown);
        summonSnowman(player, item);
      }
      break;

    case "pb_gat:gadget_shockwave":
      if (canUse(forcedCooldown - 2)) {
        player.startItemCooldown("pb_shockwave", forcedCooldown);
        handleShockwave(player, item);
      }
      break;

    case "pb_gat:gadget_recall":
      if (canUse(forcedCooldown - 2)) {
        // Prevent recall if not in overworld
        if (player.dimension.id !== "minecraft:overworld") {
          player.sendMessage(
            "§4->§r You can only recall home from the Overworld."
          );
          player.playSound("note.bass", {
            pitch: 0.9,
            volume: 0.6,
            location: player.location,
          });
          player.startItemCooldown("pb_recall", 0);
          return; // do NOT set cooldown or call recallHome
        }

        player.startItemCooldown("pb_recall", forcedCooldown);
        recallHome(player, item);
      }
      break;

    case "pb_gat:gadget_biome_scanner":
      biomeScanner(player, item);
      break;

    case "pb_gat:gadget_gauntlet":
      if (canUse(forcedCooldown - 2)) {
        player.startItemCooldown("pb_gauntlet", forcedCooldown);
        handleGauntlet(player, item);
      }
      break;

    case "pb_gat:gadget_grappling_hook":
      if (
        fromBlockInteraction ? ticks === 0 : ticks >= forcedCooldown / 4 - 2
      ) {
        player.startItemCooldown("pb_grappling", forcedCooldown / 4);
        handleGrapplingHook(player, item);
      }
      break;
  }
}

world.beforeEvents.itemUse.subscribe((event) => {
  /// FOR SOME REASON HAVING THIS STOPS THE GADGET THROWING OUT ANY UPGRADES
});

/// Handle specific gadgets that are meant to interact with blocks
world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
  const player = event.player;
  const block = event.block;
  const equippable = player.getComponent("equippable");
  const heldItem = equippable?.getEquipmentSlot("Mainhand")?.getItem();
  let forcedCooldown = DEFAULT_COOLDOWN;
  // Run on next tick to access full itemStack
  system.runTimeout(() => {
    if (!heldItem) {
      return;
    }

    if (heldItem.typeId === "pb_gat:gadget_bucket") {
      const cooldown = heldItem.getComponent("minecraft:cooldown");
      const ticks = cooldown.getCooldownTicksRemaining(player);

      if (ticks < DEFAULT_COOLDOWN - 3) {
        return;
      }
      bottomlessBucket(player, heldItem, event);
    }

    if (heldItem.typeId === "pb_gat:gadget_watering_can") {
      const cooldown = heldItem.getComponent("minecraft:cooldown");
      const ticks = cooldown.getCooldownTicksRemaining(player);
      if (ticks < DEFAULT_COOLDOWN - 3) {
        return;
      }
      wateringCan(player, heldItem, event);
      return;
    }
    if (heldItem?.typeId === "pb_gat:gadget_mirror") {
      const cooldown = heldItem.getComponent("minecraft:cooldown");
      const ticks = cooldown.getCooldownTicksRemaining(player);
      if (ticks < DEFAULT_COOLDOWN - 3) {
        return;
      }
      player.startItemCooldown("pb_mirror", forcedCooldown);
      handleMirror(player, heldItem, block);
      return;
    }
  }, 2);
  if (heldItem?.typeId === "pb_gat:gadget_chest_jack_empty") {
    if (block.typeId != "minecraft:chest") return;
    event.cancel = true;
    handleEmptyChestJack(player, heldItem, event);
    return;
  }
  if (heldItem?.typeId === "pb_gat:gadget_chest_jack_loaded") {
    handleLoadedChestJack(player, heldItem, event);
    return;
  }
});

const DAMAGE = 2;

system.runInterval(() => {
  const dimensions = ["overworld", "nether", "the_end"];

  const players = dimensions.flatMap((dim) =>
    world.getDimension(dim).getEntities({ type: "minecraft:player" })
  );

  players.forEach((player) => {
    const container = player.getComponent("inventory")?.container;
    if (!container) return;

    let jackCount = 0;

    for (let i = 0; i < container.size; i++) {
      const item = container.getItem(i);
      if (item?.typeId === "pb_gat:gadget_chest_jack_loaded") {
        jackCount += item.amount;
      }
    }

    if (jackCount > 0) {
      player.addEffect("slowness", 5, {
        amplifier: jackCount + 1,
        showParticles: false,
      });
    } else {
      player.removeEffect("slowness");
    }
  });
}); // every tick for smooth slowness updates

system.runInterval(() => {
  const dimensions = ["overworld", "nether", "the_end"];

  const players = dimensions.flatMap((dim) =>
    world.getDimension(dim).getEntities({ type: "minecraft:player" })
  );

  const dummies = dimensions.flatMap((dim) =>
    world.getDimension(dim).getEntities({ type: "pb_gat:spike_dummy" })
  );

  const snowmen = dimensions.flatMap((dim) =>
    world.getDimension(dim).getEntities({ type: "pb_gat:snowman_turret" })
  );

  dummies.forEach((dummy) => {
    const variantComponent = dummy.getComponent("minecraft:variant");
    const variant = variantComponent.value;
    const radius = variant === 1 ? 4 : variant === 2 ? 6 : 0;
    if (radius <= 0) return;
    const { x, y, z } = dummy.location;
    const dimension = dummy.dimension;

    const nearby = dimension.getEntities({
      location: { x, y, z },
      maxDistance: radius,
      families: ["monster"],
    });

    for (const entity of nearby) {
      try {
        entity.applyDamage(DAMAGE);
      } catch (e) {}
    }
  });

  snowmen.forEach((snowman) => {
    if (!snowman.hasTag("pb_has_nitrogen")) return;
    snowman.dimension.spawnParticle("pb_gat:snowman_frost", snowman.location);
    const dimension = snowman.dimension;
    const nearby = dimension.getEntities({
      location: snowman.location,
      maxDistance: 6,
      families: ["monster"],
    });

    for (const entity of nearby) {
      try {
        entity.applyDamage(DAMAGE);
        entity.addEffect("slowness", 100, {
          amplifier: 1,
          showParticles: true,
        });
      } catch (e) {}
    }
  });
}, 20); // every second
