import {
  world,
  system,
  EntityDamageCause,
  EquipmentSlot
} from "@minecraft/server";
import { visualEffects } from "./visual_effects.js";

// Weapon cooldown system - 2 seconds cooldown for abilities
const weaponCooldowns = new WeakMap(); // player => lastUseTime
const WEAPON_COOLDOWN_MS = 2000; // 2 seconds

// Helper function to check if weapon is on cooldown
function isWeaponOnCooldown(player) {
  const lastUse = weaponCooldowns.get(player) || 0;
  const now = Date.now();
  return (now - lastUse) < WEAPON_COOLDOWN_MS;
}

// Helper function to set weapon cooldown
function setWeaponCooldown(player) {
  weaponCooldowns.set(player, Date.now());
}

// Helper function to check if an entity should be excluded from weapon effects
function isInteractionHandlerEntity(entityTypeId) {
  return (
    // Soul Altars - these have specific interaction handlers
    entityTypeId === "aft_soulhunters:dragon_altar" ||
    entityTypeId === "aft_soulhunters:elephant_altar" ||
    entityTypeId === "aft_soulhunters:fox_altar" ||
    entityTypeId === "aft_soulhunters:leopard_altar" ||
    entityTypeId === "aft_soulhunters:manta_ray_altar" ||
    entityTypeId === "aft_soulhunters:panda_altar" ||
    entityTypeId === "aft_soulhunters:phoenix_altar" ||
    entityTypeId === "aft_soulhunters:red_panda_altar" ||
    entityTypeId === "aft_soulhunters:tiger_altar" ||
    entityTypeId === "aft_soulhunters:wolf_altar" ||
    // Crafting Altar
    entityTypeId === "aft_soulhunters:altar" ||
    entityTypeId === "aft_soulhunters:crafting_altar" ||
    // Companions (only the actual companion entities, not all mod entities)
    entityTypeId === "aft_soulhunters:dragon" ||
    entityTypeId === "aft_soulhunters:elephant" ||
    entityTypeId === "aft_soulhunters:fox" ||
    entityTypeId === "aft_soulhunters:leopard" ||
    entityTypeId === "aft_soulhunters:manta_ray" ||
    entityTypeId === "aft_soulhunters:panda" ||
    entityTypeId === "aft_soulhunters:phoenix" ||
    entityTypeId === "aft_soulhunters:red_panda" ||
    entityTypeId === "aft_soulhunters:tiger" ||
    entityTypeId === "aft_soulhunters:wolf" ||
    // Hook seat entity
    entityTypeId === "aft_soulhunters:hook_seat"
  );
}

// 1. Flame Katana: Prende fuego a los mobs en area
function flameKatanaAbility(center, source, tier = 1) {
  // Area radius: tier 2 = 4, tier 3 = 7, tier 4 = 10
  let radius;
  if (tier === 2) radius = 4;
  else if (tier === 3) radius = 7;
  else if (tier === 4) radius = 10;
  else radius = 3;
  const baseDamage = 6;
  const baseDuration = 5;
  
  // const radius = baseRadius + (tier - 1) * 1.5; // replaced with explicit values
  const damage = baseDamage + (tier - 1) * 4; // 6, 10, 14, 18
  const durationSeconds = baseDuration + (tier - 1) * 2; // 5, 7, 9, 11

  for (const entity of source.dimension.getEntities({
    excludeTypes: ["player"],
    location: center,
    maxDistance: radius
  })) {
    try {
      // Check if entity is still valid before applying effects
      if (!entity || !entity.isValid()) continue;
      
      // Skip interaction handler entities (altars, companions)
      if (isInteractionHandlerEntity(entity.typeId)) continue;
      
      entity.applyDamage(damage, { cause: EntityDamageCause.entityAttack, damagingEntity: source });
      
      // Check again before setting on fire (entity might have died from damage)
      if (entity.isValid()) {
        entity.setOnFire(durationSeconds, false);
      }
    } catch (e) {
      // Entity became invalid between checks, skip it
      // debug log removed
    }
  }
  
  // Play custom weapon sound
  source.playSound("aft_soulhunters_katana");
}

// 2. Wind Naginata: Da levitation a los mobs en area
function windNaginataAbility(center, source, tier = 1) {
  const baseRadius = 4;
  const baseDamage = 4;
  const baseDuration = 4;
  const baseAmplifier = 1;
  
  const radius = baseRadius + (tier - 1) * 1.5; // 4, 5.5, 7, 8.5
  const damage = baseDamage + (tier - 1) * 3; // 4, 7, 10, 13
  const durationSeconds = baseDuration + (tier - 1) * 2; // 4, 6, 8, 10
  const amplifier = baseAmplifier + Math.floor((tier - 1) / 1.5); // 1, 1, 2, 3

  for (const entity of source.dimension.getEntities({
    excludeTypes: ["player"],
    location: center,
    maxDistance: radius
  })) {
    try {
      // Check if entity is still valid before applying effects
      if (!entity || !entity.isValid()) continue;
      
      // Skip interaction handler entities (altars, companions)
      if (isInteractionHandlerEntity(entity.typeId)) continue;
      
      entity.addEffect("levitation", durationSeconds * 20, {
        amplifier,
        showParticles: true
      });
      
      // Check again before applying damage
      if (entity.isValid()) {
        entity.applyDamage(damage, { cause: EntityDamageCause.entityAttack, damagingEntity: source });
      }
    } catch (e) {
      // Entity became invalid between checks, skip it
      // debug log removed
    }
  }
  
  // Play custom weapon sound
  source.playSound("aft_soulhunters_wind_naginata");
}


// 3. Hurricane Sai: Tira 3 misiles de breeze
function hurricaneSaiAbility(source, tier = 1) {
  const forward = source.getViewDirection();
  const origin = {
    x: source.location.x,
    y: source.location.y + 1.5,
    z: source.location.z
  };

  const baseAngles = [-15, 0, 15]; // grados para los 3 misiles
  const baseSpeed = 1.2;
  const baseLifetime = 100;
  const baseDamage = 4;
  
  // Scale projectile count and spread based on tier
  const projectileCount = 3 + Math.floor((tier - 1) / 1.5); // 3, 3, 4, 5 projectiles
  const angles = [];
  if (projectileCount === 3) {
    angles.push(...baseAngles);
  } else if (projectileCount === 4) {
    angles.push(-20, -7, 7, 20); // wider spread for tier 3
  } else {
    angles.push(-25, -12, 0, 12, 25); // even wider spread for tier 4
  }
  
  const speed = baseSpeed + (tier - 1) * 0.4; // 1.2, 1.6, 2.0, 2.4
  const lifetime = baseLifetime + (tier - 1) * 30; // 100, 130, 160, 190
  const damage = baseDamage + (tier - 1) * 3; // 4, 7, 10, 13

  for (const angle of angles.slice(0, projectileCount)) {
    const radians = (angle * Math.PI) / 180;

    const dirX = forward.x * Math.cos(radians) - forward.z * Math.sin(radians);
    const dirZ = forward.x * Math.sin(radians) + forward.z * Math.cos(radians);
    const direction = {
      x: dirX,
      y: forward.y,
      z: dirZ
    };

    // Spawn wind projectile at origin
    const windProjectile = source.dimension.spawnEntity("aft_soulhunters:wind_projectile", origin);
    if (!windProjectile) continue;

    // Create initial wind charge visual effect
    source.runCommandAsync(`particle minecraft:wind_explosion ${origin.x} ${origin.y} ${origin.z}`);

    let ticks = 0;

    const move = system.runInterval(() => {
      if (!windProjectile || !windProjectile.isValid()) {
        system.clearRun(move);
        return;
      }

      ticks++;
      if (ticks > lifetime) {
        windProjectile.triggerEvent("aft_soulhunters:despawn");
        system.clearRun(move);
        return;
      }

      // Check if windProjectile is still valid
      if (!windProjectile.isValid()) {
        system.clearRun(move);
        return;
      }

      const newPos = {
        x: windProjectile.location.x + direction.x * speed,
        y: windProjectile.location.y + direction.y * speed,
        z: windProjectile.location.z + direction.z * speed,
      };

      // Add trailing wind particles
      source.runCommandAsync(`particle minecraft:breeze_wind_charge_shot ${newPos.x} ${newPos.y} ${newPos.z}`);

      // Check collision with blocks
      const block = windProjectile.dimension.getBlock({
        x: Math.floor(newPos.x),
        y: Math.floor(newPos.y),
        z: Math.floor(newPos.z)
      });

      if (block && block.typeId !== "minecraft:air" && block.typeId !== "minecraft:water" && block.typeId !== "minecraft:flowing_water") {
        // Wind explosion on block hit
        source.runCommandAsync(`particle minecraft:wind_explosion ${newPos.x} ${newPos.y} ${newPos.z}`);
        source.playSound("entity.breeze.wind_charge.burst");
        windProjectile.triggerEvent("aft_soulhunters:despawn");
        system.clearRun(move);
        return;
      }

      // Check for entity hit (exclude the source player)
      const hitEntity = windProjectile.dimension.getEntities({
        location: newPos,
        maxDistance: 1.5,
        excludeTypes: ["player", "aft_soulhunters:wind_projectile"],
        excludeNames: [source.name]
      })[0];

      if (hitEntity) {
        // Skip interaction handler entities (altars, companions)
        if (isInteractionHandlerEntity(hitEntity.typeId)) {
          // Continue projectile movement without hitting interaction entities
          windProjectile.teleport(newPos, { facingLocation: newPos });
          return;
        }
        
        // Apply wind charge knockback effect - scales with tier
        const knockbackStrength = 1.5 + (tier - 1) * 0.8; // 1.5, 2.3, 3.1, 3.9
        
        // Store entity location before any operations that might invalidate the entity
        const hitEntityLocation = hitEntity.location;
        
        const direction = {
          x: hitEntityLocation.x - newPos.x,
          y: 0.5,
          z: hitEntityLocation.z - newPos.z
        };
        
        const length = Math.sqrt(direction.x ** 2 + direction.z ** 2) || 1;
        direction.x = (direction.x / length) * knockbackStrength;
        direction.z = (direction.z / length) * knockbackStrength;
        
        hitEntity.applyImpulse(direction);
        hitEntity.applyDamage(damage, { cause: EntityDamageCause.entityAttack, damagingEntity: source });
        
        // Wind explosion effect on hit (use stored location in case entity was removed)
        source.runCommandAsync(`particle minecraft:wind_explosion ${hitEntityLocation.x} ${hitEntityLocation.y} ${hitEntityLocation.z}`);
        source.playSound("entity.breeze.wind_charge.burst");
        
        windProjectile.triggerEvent("aft_soulhunters:despawn");
        system.clearRun(move);
        return;
      }

      windProjectile.teleport(newPos, { facingLocation: newPos });
    }, 1); // update every tick
  }

  source.playSound("entity.breeze.wind_charge.throw");
  // Play custom weapon sound
  source.playSound("aft_soulhunters_hurricane_sai");
}


// 4. Speed Yari: Tres ataques continuos con dash forward
function speedYariAbility(source, tier = 1) {
  const baseRadius = 2.2;
  const baseDamage = 3;
  const baseAttacks = 3;
  const delayTicks = 8; // 0.4 segundos entre cada ataque
  const baseDashStrength = 3; // Dash strength like flame tanto
  
  const radius = baseRadius + (tier - 1) * 0.8; // 2.2, 3.0, 3.8, 4.6
  const damage = baseDamage + (tier - 1) * 3; // 3, 6, 9, 12
  const attackCount = baseAttacks + Math.floor((tier - 1) / 1.5); // 3, 3, 4, 5
  const dashStrength = baseDashStrength + (tier - 1) * 0.3; // 3, 3.3, 3.6, 3.9
  
  const view = source.getViewDirection();
  
  // Apply forward dash knockback to player (like flame tanto)
  try {
    // Use applyKnockback for players instead of applyImpulse
    source.applyKnockback(view.x, view.z, dashStrength, 0.2);
  } catch (e) {
    // debug log removed
  }

  for (let i = 0; i < attackCount; i++) {
    system.runTimeout(() => {
      const center = {
        x: source.location.x + source.getViewDirection().x * 1.5,
        y: source.location.y + 1,
        z: source.location.z + source.getViewDirection().z * 1.5,
      };

      for (const entity of source.dimension.getEntities({
        excludeTypes: ["player"],
        location: center,
        maxDistance: radius
      })) {
        try {
          // Check if entity is still valid before applying damage
          if (!entity || !entity.isValid()) continue;
          
          // Skip interaction handler entities (altars, companions)
          if (isInteractionHandlerEntity(entity.typeId)) continue;
          
          entity.applyDamage(damage, {
            cause: EntityDamageCause.entityAttack,
            damagingEntity: source,
          });
        } catch (e) {
          // Entity became invalid, skip it
          // debug log removed
        }
      }

      source.playSound("mob.trident.throw"); // sonido de ataque opcional
      // Play custom weapon sound
      source.playSound("aft_soulhunters_speed_yari");
    }, i * delayTicks);
  }
}


// 5. Rumbling Hammer: Shake de camara, multiples daños en area
function rumblingHammerAbility(center, source, tier = 1) {
  const baseRadius = 4;
  const baseTotalHits = 3;
  const delayTicks = 6;
  const baseDamage = 4;
  
  const radius = baseRadius + (tier - 1) * 1.5; // 4, 5.5, 7, 8.5
  const totalHits = baseTotalHits + Math.floor((tier - 1) / 1.5); // 3, 3, 4, 5
  const damage = baseDamage + (tier - 1) * 4; // 4, 8, 12, 16
  const shakeRadius = radius + 8;
  const shakeIntensity = 0.5 + (tier - 1) * 0.4; // 0.5, 0.9, 1.3, 1.7

  // Efecto de cámara para todos los jugadores cercanos
  for (const player of source.dimension.getPlayers()) {
    const dx = player.location.x - center.x;
    const dz = player.location.z - center.z;
    const dist = Math.sqrt(dx * dx + dz * dz);
    if (dist <= shakeRadius) {
      player.runCommandAsync(`camerashake add @s ${shakeIntensity} 2 positional`);
    }
  }

  // Golpes secuenciales
  for (let i = 0; i < totalHits; i++) {
    system.runTimeout(() => {
      for (const entity of source.dimension.getEntities({
        excludeTypes: ["player"],
        location: center,
        maxDistance: radius
      })) {
        try {
          // Check if entity is still valid before applying damage
          if (!entity || !entity.isValid()) continue;
          
          // Skip interaction handler entities (altars, companions)
          if (isInteractionHandlerEntity(entity.typeId)) continue;
          
          entity.applyDamage(damage, {
            cause: EntityDamageCause.entityAttack,
            damagingEntity: source
          });
        } catch (e) {
          // Entity became invalid, skip it
          // debug log removed
        }
      }

      // Sonido opcional por golpe
      source.playSound("mob.zombie.infect"); // podés cambiarlo por algo más brutal
      // Play custom weapon sound
      source.playSound("aft_soulhunters_rumbling_hammer");
    }, i * delayTicks);
  }
}


// 6. Thunder Long Bow: Cada tres ataques tira un thunder
const thunderBowHitCount = new WeakMap(); // Guarda los impactos por jugador

// Combined handler for both entity and block hits
function handleThunderBowHit(event, eventType) {
  const { source, projectile, location, hitVector } = event;



  // Validamos jugador y que esté usando el arco correcto
  if (!source?.isValid() || source.typeId !== "minecraft:player") {
  
    return;
  }

  const mainhand = source.getComponent("minecraft:equippable")?.getEquipment(EquipmentSlot.Mainhand);
  if (!mainhand || !mainhand.typeId.startsWith("aft_soulhunters:thunder_long_bow_")) {
  
    return;
  }

  // Extract tier from item ID
  const tierMatch = mainhand.typeId.match(/thunder_long_bow_(\d+)$/);
  if (!tierMatch) {
  
    return;
  }
  
  const tier = parseInt(tierMatch[1]);
  
  // Only tier 2 and above have thunder ability
  if (tier < 2) {
  
    return;
  }

  // Log player position


  // Use event location first, then try to get a safe projectile location
  let hitLocation = null;
  if (location) {
    hitLocation = location;
  
  } else {
    // Try to get projectile location safely
    try {
      if (projectile && projectile.isValid && projectile.isValid()) {
        hitLocation = { ...projectile.location }; // Copy the location to avoid reference issues
      
      }
    } catch (e) {
    
      // Projectile is invalid, hitLocation remains null
    }
  }

  if (!hitLocation) {
  
  }

  thunderLongBowAbility(source, hitLocation, tier);
}

// Handle projectile hits on blocks
world.afterEvents.projectileHitBlock.subscribe(event => {
  handleThunderBowHit(event, "BLOCK_HIT");
});

// Handle projectile hits on entities, but exclude the shooter
world.afterEvents.projectileHitEntity.subscribe(event => {
  const { source, getEntityHit } = event;

  // Check if the hit entity is the shooter - if so, don't trigger lightning
  try { 
    const hitEntity = getEntityHit()?.entity;
    if (hitEntity && hitEntity.id === source.id) {
    
      return; // Don't trigger lightning if arrow hit the shooter
    }
    if (hitEntity) {
    
    }
  } catch (e) {
  
  }

  handleThunderBowHit(event, "ENTITY_HIT");
});

const thunderBowTracker = new WeakMap(); // player => count

function thunderLongBowAbility(source, hitLocation = null, tier = 2) {
  if (!source || !source.isValid()) return;

  const count = (thunderBowTracker.get(source) || 0) + 1;


  if (count >= 3) {
    thunderBowTracker.set(source, 0);
  

    // Spawn lightning at the hit location (where the arrow hit)
    let pos;
    if (hitLocation) {
      pos = {
        x: Math.floor(hitLocation.x),
        y: Math.floor(hitLocation.y) + 1,
        z: Math.floor(hitLocation.z),
      };
    
    } else {
      // Fallback: spawn lightning 8 blocks in front of player if no hit location
      const direction = source.getViewDirection();
      pos = {
        x: Math.floor(source.location.x + direction.x * 8),
        y: Math.floor(source.location.y) + 1,
        z: Math.floor(source.location.z + direction.z * 8),
      };
    
    }

    // Calculate distance from player to lightning
    const playerPos = source.location;
    const distance = Math.sqrt(
      Math.pow(pos.x - playerPos.x, 2) + 
      Math.pow(pos.y - playerPos.y, 2) + 
      Math.pow(pos.z - playerPos.z, 2)
    );
    
  
  
  

    if (distance < 5) {
    
    }

    // Add tier-specific particle effects for everyone to see at player location
    let particleName = "";
    switch (tier) {
      case 2:
        particleName = "aft_soulhunters:thunder_long_bow1.2";
        break;
      case 3:
        particleName = "aft_soulhunters:thunder_long_bow1.3";
        break;
      case 4:
        particleName = "aft_soulhunters:thunder_long_bow1.4";
        break;
      default:
        particleName = "aft_soulhunters:thunder_long_bow1.2"; // fallback
        break;
    }

    // Spawn the tier-specific particle effect at the player's location
    source.dimension.runCommandAsync(`particle ${particleName} ${playerPos.x} ${playerPos.y} ${playerPos.z}`);

    source.dimension.spawnEntity("minecraft:lightning_bolt", pos);
    source.playSound("ambient.weather.thunder");
    // Play custom weapon sound
    source.playSound("aft_soulhunters_thunder_bow");
  
  } else {
    thunderBowTracker.set(source, count);
  }
}


// 7. Flame Tanto: Fuego a un mob
function flameTantoAbility(source, tier = 1) {
  const baseRange = 2;
  const baseDamage = 5;
  const baseBurnTime = 5;
  const baseDashStrength = 4;
  
  const range = baseRange + (tier - 1) * 0.8; // 2, 2.8, 3.6, 4.4
  const damage = baseDamage + (tier - 1) * 4; // 5, 9, 13, 17
  const burnTime = baseBurnTime + (tier - 1) * 3; // 5, 8, 11, 14
  const dashStrength = baseDashStrength + (tier - 1) * 0.3; // 0.8, 1.1, 1.4, 1.7
  
  const view = source.getViewDirection();
  
  // Apply forward dash knockback to player first
  const dashDirection = {
    x: view.x * dashStrength,
    y: 0.2, // Small upward component to help with movement
    z: view.z * dashStrength
  };
  
  try {
    // Use applyKnockback for players instead of applyImpulse
    source.applyKnockback(view.x, view.z, dashStrength, 0.2);
  } catch (e) {
    // debug log removed
  }
  
  const targetPos = {
    x: source.location.x + view.x * range,
    y: source.location.y + 1,
    z: source.location.z + view.z * range,
  };

  const closest = source.dimension.getEntities({
    excludeTypes: ["player"],
    location: targetPos,
    maxDistance: range
  })[0];

  if (!closest) {
    // Still play sound even if no target hit
    source.playSound("aft_soulhunters_flame_tanto");
    return;
  }

  // Skip interaction handler entities (altars, companions)
  if (isInteractionHandlerEntity(closest.typeId)) {
    source.playSound("aft_soulhunters_flame_tanto");
    return;
  }

  try {
    // Check if entity is still valid before applying effects
    if (!closest || !closest.isValid()) return;
    
    closest.applyDamage(damage, {
      cause: EntityDamageCause.entityAttack,
      damagingEntity: source
    });

    // Check again before setting on fire (entity might have died from damage)
    if (closest.isValid()) {
      closest.setOnFire(burnTime, false);
    }
    
    // Play custom weapon sound
    source.playSound("aft_soulhunters_flame_tanto");
  } catch (e) {
    // Entity became invalid, skip it
    // debug log removed
  }
}


// 8. Spirit Masakari: Area damage attack
function spiritMasakariAbility(source, tier = 1) {
  // Area radius: tier 2 = 4, tier 3 = 7, tier 4 = 10
  let radius;
  if (tier === 2) radius = 4;
  else if (tier === 3) radius = 7;
  else if (tier === 4) radius = 10;
  else radius = 4;
  const baseDamage = 8;
  
  // const radius = baseRadius + (tier - 1) * 1.5; // replaced with explicit values
  const damage = baseDamage + (tier - 1) * 5; // 8, 13, 18, 23
  
  const center = source.location;

  for (const entity of source.dimension.getEntities({
    excludeTypes: ["player"],
    location: center,
    maxDistance: radius
  })) {
    try {
      // Check if entity is still valid before applying damage
      if (!entity || !entity.isValid()) continue;
      
      // Skip interaction handler entities (altars, companions)
      if (isInteractionHandlerEntity(entity.typeId)) continue;
      
      entity.applyDamage(damage, {
        cause: EntityDamageCause.entityAttack,
        damagingEntity: source
      });
    } catch (e) {
      // Entity became invalid, skip it
      // debug log removed
    }
  }

  source.playSound("mob.ghast.moan"); // sonido de invocación
  // Play custom weapon sound
  source.playSound("aft_soulhunters_masaraki");
}


// 9. Charge Fan: Knockback en area
function chargeFanAbility(center, source, tier = 1) {
  const baseRadius = 4;
  const baseKnockback = 1.5;
  
  const radius = baseRadius + (tier - 1) * 2.5; // 4, 6.5, 9, 11.5
  const knockbackStrength = baseKnockback + (tier - 1) * 1.5; // 1.5, 3.0, 4.5, 6.0

  for (const entity of source.dimension.getEntities({
    excludeTypes: ["player"],
    location: center,
    maxDistance: radius
  })) {
    // Skip interaction handler entities (altars, companions)
    if (isInteractionHandlerEntity(entity.typeId)) continue;
    
    const direction = {
      x: entity.location.x - source.location.x,
      y: 0.4,
      z: entity.location.z - source.location.z
    };

    // Normalizar dirección
    const length = Math.sqrt(direction.x ** 2 + direction.z ** 2) || 1;
    direction.x = (direction.x / length) * knockbackStrength;
    direction.z = (direction.z / length) * knockbackStrength;

    entity.applyImpulse(direction);
  }

  source.playSound("entity.ender_dragon.flap"); // sonido de viento fuerte
  // Play custom weapon sound
  source.playSound("aft_soulhunters_charge_fan");
}
// 10. Multi Kunai Knife: Dispara 3 kunais en ángulos
function multiKunaiKnifeAbility(source, tier = 1) {
  const view = source.getViewDirection();
  const origin = {
    x: source.location.x,
    y: source.location.y + 1.5,
    z: source.location.z
  };

  const baseAngles = [-15, 0, 15]; // fan spread
  const baseSpeed = 0.9;
  const baseLifetime = 100;
  const baseDamage = 6;
  
  // Scale projectile count based on tier
  const projectileCount = 3 + Math.floor((tier - 1) / 1.3); // 3, 3, 4, 5
  const angles = [];
  if (projectileCount === 3) {
    angles.push(...baseAngles);
  } else if (projectileCount === 4) {
    angles.push(-20, -7, 7, 20); // wider spread for tier 3
  } else {
    angles.push(-25, -12, 0, 12, 25); // even wider spread for tier 4
  }
  
  const speed = baseSpeed + (tier - 1) * 0.3; // 0.9, 1.2, 1.5, 1.8
  const lifetime = baseLifetime + (tier - 1) * 30; // 100, 130, 160, 190
  const damage = baseDamage + (tier - 1) * 5; // 6, 11, 16, 21 - high damage scaling

  // Determine which kunai projectile to use based on tier
  let kunaiProjectileId = "aft_soulhunters:kunai_projectile"; // default/tier 1
  if (tier >= 4) {
    kunaiProjectileId = "aft_soulhunters:kunai_4_projectile";
  } else if (tier >= 3) {
    kunaiProjectileId = "aft_soulhunters:kunai_3_projectile";
  } else if (tier >= 2) {
    kunaiProjectileId = "aft_soulhunters:kunai_2_projectile";
  }

  for (const angle of angles.slice(0, projectileCount)) {
    const radians = (angle * Math.PI) / 180;

    const dirX = view.x * Math.cos(radians) - view.z * Math.sin(radians);
    const dirZ = view.x * Math.sin(radians) + view.z * Math.cos(radians);
    const direction = {
      x: dirX,
      y: view.y,
      z: dirZ
    };

    const kunai = source.dimension.spawnEntity(kunaiProjectileId, origin);
    if (!kunai) continue;

    let ticks = 0;

    const move = system.runInterval(() => {
      if (!kunai || !kunai.isValid()) {
        system.clearRun(move);
        return;
      }

      ticks++;
      if (ticks > lifetime) {
        kunai.triggerEvent("aft_soulhunters:despawn");
        system.clearRun(move);
        return;
      }

      const newPos = {
        x: kunai.location.x + direction.x * speed,
        y: kunai.location.y + direction.y * speed,
        z: kunai.location.z + direction.z * speed,
      };

      // Check collision with blocks
      const block = kunai.dimension.getBlock({
        x: Math.floor(newPos.x),
        y: Math.floor(newPos.y),
        z: Math.floor(newPos.z)
      });

      if (block && block.typeId !== "minecraft:air" && block.typeId !== "minecraft:water" && block.typeId !== "minecraft:flowing_water") {
        kunai.triggerEvent("aft_soulhunters:despawn");
        system.clearRun(move);
        return;
      }

      // Check for entity hit - exclude the specific tier projectiles
      const hitEntity = kunai.dimension.getEntities({
        location: newPos,
        maxDistance: 1,
        excludeTypes: ["player", "aft_soulhunters:kunai_projectile", "aft_soulhunters:kunai_2_projectile", "aft_soulhunters:kunai_3_projectile", "aft_soulhunters:kunai_4_projectile"],
      })[0];

      if (hitEntity) {
        // Skip interaction handler entities (altars, companions)
        if (isInteractionHandlerEntity(hitEntity.typeId)) {
          // Continue projectile movement without hitting interaction entities
          kunai.teleport(newPos, { facingLocation: newPos });
          return;
        }
        
        hitEntity.applyDamage(damage, { cause: EntityDamageCause.entityAttack, damagingEntity: source });
        kunai.triggerEvent("aft_soulhunters:despawn");
        system.clearRun(move);
        return;
      }

      kunai.teleport(newPos, { facingLocation: newPos });
    }, 1); // update every tick
  }

  source.playSound("random.bow");
  // Play custom weapon sound
  source.playSound("aft_soulhunters_kunai");
}



// Detección de uso del arma
world.afterEvents.itemStopUse.subscribe(event => {
  const { source: player } = event;
  
  // Clear the animation blocking variable on the player
  // We'll use a simpler approach with global state tracking
  
  // Store the player reference globally for animation access
  if (typeof globalThis.currentWeaponUser === 'undefined') {
    globalThis.currentWeaponUser = null;
  }
  globalThis.currentWeaponUser = player;
  
  if (!player || !player.isValid() || player.isSneaking) {
    return;
  }

  const item = player.getComponent("minecraft:equippable")?.getEquipment(EquipmentSlot.Mainhand);
  if (!item) {
    return;
  }


  // Extract weapon type and tier from item ID
  const itemId = item.typeId;
  const weaponMatch = itemId.match(/^aft_soulhunters:(\w+)_(\d+)$/);
  
  if (!weaponMatch) {
    return;
  }
  
  const weaponType = weaponMatch[1];
  const tier = parseInt(weaponMatch[2]);

  // Only weapons tier 2 and above have special abilities
  if (tier < 2) {
    return;
  }

  // Check weapon cooldown
  if (isWeaponOnCooldown(player)) {
    return;
  }

  // Check if player is looking at an entity handled by interaction_handler - if so, don't trigger ability
  try {
    // Use the official API method to get entities in view direction
    const entityHits = player.getEntitiesFromViewDirection({
      maxDistance: 6
    });
    
    // Set a temporary variable for animation controller to read
    let isLookingAtInteractionEntity = false;
    
    for (const hit of entityHits) {
      const entity = hit.entity;
      if (!entity || entity.id === player.id) continue;
      
      const entityTypeId = entity.typeId;
      
      // Check if this entity is handled by interaction_handler
      if (isInteractionHandlerEntity(entityTypeId)) {
        isLookingAtInteractionEntity = true;
        break;
      }
    }
    
    // Block animation by storing state in the world for Molang access
    try {
      if (isLookingAtInteractionEntity) {
        player.removeTag("weapon_animation_blocked");
        player.addTag("weapon_animation_blocked");
        // Store in dynamic property as backup
        player.setDynamicProperty("weapon_blocked", 1);
      } else {
        player.removeTag("weapon_animation_blocked");
        player.setDynamicProperty("weapon_blocked", 0);
      }
    } catch (e) {
      // debug log removed
    }
    
    if (isLookingAtInteractionEntity) {
      return;
    }
    
  } catch (error) {
    // If there's an error checking view direction, continue with ability (fail-safe)
  }

  // Set weapon cooldown
  setWeaponCooldown(player);

  // Add camera shake and weapon trail effects
  visualEffects.createWeaponTrail(player, weaponType);

  switch (weaponType) {
    case "fire_katana":
      flameKatanaAbility(player.location, player, tier);
      break;
    case "wind_naginata":
      windNaginataAbility(player.location, player, tier);
      break;
    case "hurricane_sai":
      hurricaneSaiAbility(player, tier);
      break;
    case "speed_yari":
      speedYariAbility(player, tier);
      break;
    case "rumbling_hammer":
      visualEffects.triggerCameraShake(player, "high"); // Extra shake for hammer
      rumblingHammerAbility(player.location, player, tier);
      break;
    case "thunder_long_bow":
      thunderLongBowAbility(player, null, tier);
      break;
    case "flame_tanto":
      flameTantoAbility(player, tier);
      break;
    case "spirit_masakari":
      spiritMasakariAbility(player, tier);
      break;
    case "charge_fan":
      chargeFanAbility(player.location, player, tier);
      break;
    case "kunai_knife":
      multiKunaiKnifeAbility(player, tier);
      break;
    default:
      // Unknown weapon type - no action needed
      break;
  }
  
});

// Continuously check if players are looking at interaction entities for animation blocking
system.runInterval(() => {
  for (const player of world.getAllPlayers()) {
    if (!player || !player.isValid()) continue;
    
    // Check if player has a mod weapon in hand
    const item = player.getComponent("minecraft:equippable")?.getEquipment(EquipmentSlot.Mainhand);
    if (!item || !item.typeId.startsWith("aft_soulhunters:")) continue;
    
    // Check if weapon has abilities (tier 2+)
    const weaponMatch = item.typeId.match(/^aft_soulhunters:(\w+)_(\d+)$/);
    if (!weaponMatch || parseInt(weaponMatch[2]) < 2) {
      // Clear the property if no valid weapon
      try {
        player.setDynamicProperty("aft_soulhunters:looking_at_interaction_entity", false);
      } catch (e) {}
      continue;
    }
    
    let isLookingAtInteractionEntity = false;
    
    try {
      // Use the official API method to get entities in view direction
      const entityHits = player.getEntitiesFromViewDirection({
        maxDistance: 6
      });
      
      for (const hit of entityHits) {
        const entity = hit.entity;
        if (!entity || entity.id === player.id) continue;
        
        // Check if this entity is handled by interaction_handler
        if (isInteractionHandlerEntity(entity.typeId)) {
          isLookingAtInteractionEntity = true;
          break;
        }
      }
    } catch (error) {
      // If there's an error, assume not looking at interaction entity
      isLookingAtInteractionEntity = false;
    }
    
    // Set the dynamic property for animation controller
    try {
      player.setDynamicProperty("aft_soulhunters:looking_at_interaction_entity", isLookingAtInteractionEntity);
    } catch (e) {
      // Silently fail if property can't be set
    }
  }
}, 5); // Check every 5 ticks (4 times per second)
