import { world, system, ItemStack } from "@minecraft/server";
import {
  ItemInventoryContents,
  checkInventory,
  removeItem,
} from "../utilities.js";

const POWERED = new WeakMap();
const EMBER = new WeakMap();
const DAMAGE = 4;
const FIRE_TIME = 10;

export function torchLauncher(player, item) {
  const hasAmmo = checkInventory(player, "minecraft:torch");
  if (hasAmmo == undefined) {
    player.startItemCooldown("pb_torch_launcher", 0);
    player.sendMessage("§4->§r You need a torch in your inventory to launch!");
    return;
  }

  shootTorch(player, item);
  removeItem(player, hasAmmo.item, 1);
}

const FIRE_LOCATION_OFFSET = 2.5;

function shootTorch(player, item) {
  let view_vector = player.getViewDirection();
  const location = player.location;
  const dimension = player.dimension.id;

  const fire_location = {
    x: location.x + view_vector.x * FIRE_LOCATION_OFFSET,
    y: location.y + 1.0 + view_vector.y * FIRE_LOCATION_OFFSET,
    z: location.z + view_vector.z * FIRE_LOCATION_OFFSET,
  };

  let contents = [];
  if (item) {
    const result = new ItemInventoryContents(item).getContainer();
    contents = result?.content ?? [];
  }
  const hasReachUpgrade = contents.some(
    (stack) => stack?.typeId === "pb_gat:orb_reach"
  );
  const impulse = hasReachUpgrade ? 3 : 1.5;

  const hasPowerUpgrade = contents.some(
    (stack) => stack?.typeId === "pb_gat:orb_power"
  );
  const hasEmberUpgrade = contents.some(
    (stack) => stack?.typeId === "pb_gat:orb_ember"
  );

  const projectile = world
    .getDimension(dimension)
    .spawnEntity("pb_gat:torch_projectile", fire_location);

  player.playSound("crossbow.shoot", {
    pitch: 1.2,
    volume: 0.6,
    location: player.location,
  });

  const component = projectile.getComponent("minecraft:projectile");

  if (hasPowerUpgrade) {
    POWERED.set(projectile, true); // remember this one is empowered
  }
  if (hasEmberUpgrade) {
    EMBER.set(projectile, true); // remember this one is empowered
  }
  component.owner = player; // This is critical for retaliation logic
  component.shoot({
    x: view_vector.x * impulse,
    y: view_vector.y * impulse,
    z: view_vector.z * impulse,
  });
}

export function torchHitBlock(data, projectile) {
  const hitBlock = data.getBlockHit();
  const block = hitBlock.block;
  const face = hitBlock.face;
  const isEmber = EMBER.has(projectile);
  const placeType = isEmber ? "pb_gat:ember_block" : "minecraft:torch";
  const fallbackItem = new ItemStack("minecraft:torch", 1);

  const placeIfAir = (targetBlock) => {
    if (targetBlock.typeId === "minecraft:air") {
      targetBlock.setType(placeType);
    } else {
      projectile.dimension.spawnItem(fallbackItem, projectile.location);
    }
  };

  if (block.typeId === "minecraft:torch") {
    projectile.dimension.spawnItem(fallbackItem, projectile.location);
  }

  if (block.typeId === "minecraft:air") {
    block.setType(placeType);
  } else {
    switch (face) {
      case "Up":
        placeIfAir(block.above());
        break;
      case "North":
        placeIfAir(block.north());
        break;
      case "East":
        placeIfAir(block.east());
        break;
      case "South":
        placeIfAir(block.south());
        break;
      case "West":
        placeIfAir(block.west());
        break;
      default:
        projectile.dimension.spawnItem(fallbackItem, projectile.location);
        break;
    }
  }

  projectile.remove();
}

export function torchHitEntity(data) {
  const entity = data.getEntityHit()?.entity;
  const projectile = data.projectile;
  if (!entity || !projectile) return;
  const owner = data.source; // this is the shooter (player)

  if (POWERED.has(projectile)) {
    if (owner) {
      entity.applyDamage(DAMAGE, {
        damagingEntity: owner,
        damagingProjectile: owner,
      });
    }
  }
  if (EMBER.has(projectile)) {
    entity.setOnFire(FIRE_TIME);
    entity.applyDamage(1, {
      damagingEntity: owner,
      damagingProjectile: owner,
    });
  }
}
