import { world } from "@minecraft/server";

export function AoeKnockback(damager, hit_entity, knockbackValueHorizontal, knockbackValueVertical) {
  const kbVector = calculateKnockbackVector(hit_entity.location, damager.location, 1);
  hit_entity.applyKnockback(kbVector.x, kbVector.z, knockbackValueHorizontal, knockbackValueVertical);
}

export function pushAwayEntities(hit_entity, player, PullValue, VerticalStrength) {
  const kbVector = calculateKnockbackVector(hit_entity.location, player.location, 1);
  let PullStrength = 0.15;
  let Ydirection = getDirectionofVector(hit_entity.location, player.location).y * 0.7;
  if ((Ydirection > -1.5 && Ydirection <= 0) || (Ydirection >= 0 && Ydirection < 1.5)) {
    Ydirection += 2.5;
  }
  hit_entity.applyKnockback(kbVector.x * (PullStrength * 2), kbVector.z * (PullStrength * 2), PullValue, VerticalStrength);
}

export function randomKnockback(hit_entity, player, knockbackValueHorizontal, knockbackValueVertical) {
  const kbVector = calculateKnockbackVectorRandom(player.location, hit_entity.location, 1);
  hit_entity.applyKnockback(kbVector.x * (Math.random() * 0.3 + 0.6), kbVector.z * (Math.random() * 0.3 + 0.6), knockbackValueHorizontal * 1.5, knockbackValueVertical * 0.7);
}

export function pullInEntities(hit_entity, player, PullValue, VerticalStrength) {
  const kbVector = calculateKnockbackVector(player.location, hit_entity.location, 1);
  let PullStrength = getPullStrengthBasedOnDistance(getDirectionofVector(player.location, hit_entity.location));
  hit_entity.applyKnockback(kbVector.x, kbVector.z, PullValue, VerticalStrength);
}
export function pullInItems(hit_item, player) {
  hit_item.clearVelocity();
  const kbVector = calculateKnockbackVector(player.location, hit_item.location, 1);
  let PullStrength = getPullStrengthBasedOnDistance(getDirectionofVector(player.location, hit_item.location));

  // multiply in order to set the strength of the magnet
  hit_item.applyImpulse({
    x: kbVector.x * PullStrength,
    y: kbVector.y * PullStrength * 0.01,
    z: kbVector.z * PullStrength,
  });
}
export function getDirectionofVector(entityPosition, pusherPosition) {
  let direction = {
    x: entityPosition.x - pusherPosition.x,
    y: entityPosition.y - pusherPosition.y,
    z: entityPosition.z - pusherPosition.z,
  };

  return direction;
}
export function getDirectionofVector2D(entityPosition, pusherPosition) {
  let direction = {
    x: entityPosition.x - pusherPosition.x,
    y: entityPosition.y - pusherPosition.y,
  };

  return direction;
}

export function getPullStrengthBasedOnDistance(directionVector) {
  let pullMultiplier;
  if ((directionVector.x > 10 && directionVector.x <= 15) || (directionVector.x >= -15 && directionVector.x < -10) || (directionVector.z > 10 && directionVector.z <= 15) || (directionVector.z >= -15 && directionVector.z < -10)) {
    pullMultiplier = 5.8;
  } else if ((directionVector.x > 5 && directionVector.x <= 10) || (directionVector.x >= -10 && directionVector.x < -5) || (directionVector.z > 5 && directionVector.z <= 10) || (directionVector.z >= -10 && directionVector.z < -5)) {
    pullMultiplier = 4;
  } else if ((directionVector.x >= 0 && directionVector.x <= 3) || (directionVector.x >= -3 && directionVector.x < 0) || (directionVector.z >= 0 && directionVector.z <= 3) || (directionVector.z >= -5 && directionVector.z < 0)) {
    pullMultiplier = 1.5;
  } else if ((directionVector.x >= 0 && directionVector.x <= 1) || (directionVector.x >= -1 && directionVector.x < 0) || (directionVector.z >= 0 && directionVector.z <= 1) || (directionVector.z >= -5 && directionVector.z < 0)) {
    pullMultiplier = 1;
  }
  return pullMultiplier;
}

export function calculateKnockbackVector(entityPosition, pusherPosition, forceMagnitude) {
  let direction = {
    x: entityPosition.x - pusherPosition.x,
    y: entityPosition.y - pusherPosition.y,
    z: entityPosition.z - pusherPosition.z,
  };

  let distance = magnitude(direction);
  // Normalize the direction vector so it has a magnitude of 1
  direction = {
    x: direction.x / distance,
    y: direction.y / distance,
    z: direction.z / distance,
  };

  // Scale the direction vector by the force magnitude to get the final knockback vector
  let knockback = {
    x: direction.x * forceMagnitude,
    y: direction.y * forceMagnitude,
    z: direction.z * forceMagnitude,
  };

  return knockback;
}
export function calculateKnockbackVectorRandom(entityPosition, pusherPosition, forceMagnitude) {
  let direction = {
    x: entityPosition.x * (Math.random() * (1.5 - -1.5) + -1.5) - pusherPosition.x * (Math.random() * (1.5 - -1.5) + -1.5),
    y: entityPosition.y * (Math.random() * (1.5 - -1.5) + -1.5) - pusherPosition.y * (Math.random() * (1.5 - -1.5) + -1.5),
    z: entityPosition.z * (Math.random() * (1.5 - -1.5) + -1.5) - pusherPosition.z * (Math.random() * (1.5 - -1.5) + -1.5),
  };

  let distance = magnitude(direction);

  // Normalize the direction vector so it has a magnitude of 1
  direction = {
    x: direction.x / distance,
    y: direction.y / distance,
    z: direction.z / distance,
  };

  // Scale the direction vector by the force magnitude to get the final knockback vector
  let knockback = {
    x: direction.x * forceMagnitude,
    y: direction.y * forceMagnitude,
    z: direction.z * forceMagnitude,
  };

  return knockback;
}

function magnitude(vector) {
  return Math.sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);
}
