import { system } from "@minecraft/server";
import { ItemInventoryContents } from "../utilities.js";

    const notValid = [
      // This add-on
      "pb_gat:grappling_hook_projectile",
      "pb_gat:mb_gam_lever_entity",
      "pb_gat:mb_gam_entity",
      "pb_gat:flight_dummy",
      "pb_gat:mb_tinker_table_entity",
      "pb_gat:mb_tt_item_entity",
      "pb_gat:mb_up_item_entity",
      "pb_gat:mb_upgrade_puncher_entity",
      "pb_gat:shockwave_projectile",
      "pb_gat:spike_dummy",
      "pb_gat:torch_projectile",
      "pb_gat:withered_arrow_dummy",
      // Vanilla
      "minecraft:area_effect_cloud",
      "minecraft:armor_stand",
      "minecraft:arrow",
      "minecraft:breeze_wind_charge_projectile",
      "minecraft:dragon_fireball",
      "minecraft:egg",
      "minecraft:ender_crystal",
      "minecraft:ender_dragon",
      "minecraft:ender_pearl",
      "minecraft:eye_of_ender_signal",
      "minecraft:fireball",
      "minecraft:fireworks_rocket",
      "minecraft:fishing_hook",
      "minecraft:lightning_bolt",
      "minecraft:lingering_potion",
      "minecraft:llama_spit",
      "minecraft:npc",
      "minecraft:ominous_item_spawner",
      "minecraft:shulker_bullet",
      "minecraft:small_fireball",
      "minecraft:snowball",
      "minecraft:splash_potion",
      "minecraft:thrown_trident",
      "minecraft:tripod_camera",
      "minecraft:wind_charge_projectile",
      "minecraft:wither_skull_dangerous",
      "minecraft:wither_skull",
      "minecraft:wither",
      "minecraft:xp_bottle",
    ];

export const SHOCKWAVE_PROJECTILES = new WeakMap();

export function handleShockwave(player, item) {
  const viewVector = player.getViewDirection();
  const location = player.location;
  const dimension = player.dimension;

  let contents = [];
  if (item) {
    const result = new ItemInventoryContents(item).getContainer();
    contents = result?.content ?? [];
  }

  const hasExtraUpgrade = contents.some(
    (stack) => stack?.typeId === "pb_gat:orb_extra"
  );
  const hasPowerUpgrade = contents.some(
    (stack) => stack?.typeId === "pb_gat:orb_power"
  );
  const hasShockUpgrade = contents.some(
    (stack) => stack?.typeId === "pb_gat:orb_shockloader"
  );

  const knockbackStrength = hasPowerUpgrade ? 6 : 3;
  const knockbackHeight = hasPowerUpgrade ? 1.2 : 0.5;
  const shockwaveRadius = 8;

  // IF WE HAVE THE SHOOT UPGRADE, RUN THIS CODE, AND SKIP THE KNOCKBACK FROM THE PLAYER
  if (contents.some((stack) => stack?.typeId === "pb_gat:orb_shoot")) {
    spawnShockwaveProjectile(); // First shot

    if (hasExtraUpgrade) {
      system.runTimeout(() => {
        spawnShockwaveProjectile(); // Second shot after 0.5s
      }, 10);
    }

    return; // Skip local knockback pulse
  }

  function emitShockwave() {
    const entities = dimension.getEntities({
      location: location,
      maxDistance: shockwaveRadius,
    });

    for (const entity of entities) {
      if (!entity.isValid() || entity.id === player.id || notValid.includes(entity.typeId)) continue;

      // Vector from player to entity
      const dx = entity.location.x - location.x;
      const dz = entity.location.z - location.z;

      // Dot product to see if it's in front
      const dot = dx * viewVector.x + dz * viewVector.z;
      if (dot <= 0) continue; // behind the player

      try {
        entity.applyKnockback(
          viewVector.x,
          viewVector.z,
          knockbackStrength,
          knockbackHeight
        );
        entity.dimension.spawnParticle(
          "pb_gat:shockwave_target",
          entity.location
        );
        if (hasShockUpgrade) {
          entity.addEffect("slowness", 40, {
            amplifier: 5,
            showParticles: false,
          });
          system.runTimeout(() => {
            entity.dimension.spawnParticle(
              "pb_gat:shockwave_freeze",
              entity.location
            );
          }, 15);
        }
      } catch (e) {}
    }
  }
  function spawnShockwaveProjectile() {
    const projectile = dimension.spawnEntity("pb_gat:shockwave_projectile", {
      x: location.x + viewVector.x * 1.5,
      y: location.y + 1.5,
      z: location.z + viewVector.z * 1.5,
    });
    player.playSound("crossbow.loading.end", {
      pitch: 1.5,
      volume: 1.5,
      location: player.location,
    });
    system.runTimeout(() => {
      player.playSound("item.spyglass.use", {
        pitch: 1.2,
        volume: 1.5,
        location: player.location,
      });
    }, 10);
    if (projectile && projectile.hasComponent("minecraft:projectile")) {
      const projectileComp = projectile.getComponent("minecraft:projectile");
      projectileComp.owner = player;
      projectileComp.shoot({
        x: viewVector.x * 2.5,
        y: viewVector.y * 2.5,
        z: viewVector.z * 2.5,
      });

      SHOCKWAVE_PROJECTILES.set(projectile, {
        player,
        power: knockbackStrength,
        height: knockbackHeight,
        radius: shockwaveRadius,
        shock: hasShockUpgrade,
      });
    }
  }

  player.playSound("crossbow.loading.end", {
    pitch: 1.5,
    volume: 1.5,
    location: player.location,
  });
  system.runTimeout(() => {
    player.playSound("item.spyglass.use", {
      pitch: 1.2,
      volume: 1.5,
      location: player.location,
    });
  }, 10);
  // Emit first shockwave immediately
  emitShockwave();

  // Emit second if upgrade is present
  if (hasExtraUpgrade) {
    system.runTimeout(() => {
      emitShockwave();
    }, 10); // ~0.5 seconds (10 ticks)
  }
}
