import { world, system, EntityDamageCause, Player } from "@minecraft/server";

// ======= CONFIGURAÇÕES =======
const ITEM_ADAGA = "nz:kunai"; 

const SKILLS = {
  corte: {
    dano: 6,
    forcaEmpurrao: 2.5,
    forcaVertical: 0.2,
    cooldown: 30,
  },
  furacao: {
    danoInicial: 4, 
    danoPorTick: 1.5, 
    duracao: 80,
    raio: 6, 
    cooldown: 200,
  }
};

// ======= CONTROLES =======
const cooldownMap = new Map();
const playerSkillMode = new Map(); 
const sneakingTracker = new Map(); 
const playerSkills = new Map(); // Map para armazenar skills desbloqueadas

// ==================== COOLDOWN ====================
function emCooldown(player, skillName) {
  const skill = SKILLS[skillName];
  if (!skill) return false;

  const key = player.name + "_" + skillName;
  const endTick = cooldownMap.get(key);
  const now = system.currentTick;
  
  if (endTick && endTick > now) {
    const restante = ((endTick - now) / 20).toFixed(1);
    player.runCommandAsync(`title @s actionbar §c${skillName.toUpperCase()} em cooldown: ${restante}s`);
    return true;
  }
  
  cooldownMap.set(key, now + skill.cooldown);
  return false;
}

// ==================== DESBLOQUEIO DE SKILLS ====================
function desbloquearSkill(player, skillName) {
  const skills = playerSkills.get(player.name) || [];
  if (!skills.includes(skillName)) {
    skills.push(skillName);
    playerSkills.set(player.name, skills);
    player.runCommandAsync(`title @s actionbar §aSkill ${skillName.toUpperCase()} desbloqueada!`);
  }
}

function hasSkill(player, skillName) {
  const skills = playerSkills.get(player.name) || [];
  return skills.includes(skillName);
}

// ==================== CORTE ====================
function aplicarCorte(player) {
  if (!hasSkill(player, "corte")) {
    player.runCommandAsync(`title @s actionbar §cVocê não possui a skill CORTE!`);
    return;
  }

  if (emCooldown(player, "corte")) return;

  const skill = SKILLS.corte;

  const alvos = player.dimension.getEntities({
    location: player.location,
    maxDistance: 4,
    excludeNames: [player.name],
    excludeTypes: ["minecraft:item"]
  });

  if (alvos.length === 0) {
    player.runCommandAsync(`tellraw @s {"rawtext":[{"text":"§cNenhum alvo próximo!"}]}`);
    return;
  }

  for (const alvo of alvos) {
    alvo.applyDamage(skill.dano, {
      cause: EntityDamageCause.entityAttack,
      damagingEntity: player
    });

    let dx = alvo.location.x - player.location.x;
    let dz = alvo.location.z - player.location.z;
    let dist = Math.hypot(dx, dz) || 1;

    alvo.setVelocity({
      x: (dx / dist) * skill.forcaEmpurrao,
      y: skill.forcaVertical,
      z: (dz / dist) * skill.forcaEmpurrao,
    });
  }

  player.runCommandAsync(`playanimation @s animation.sword.slash`);
  player.runCommandAsync(`particle minecraft:crit_particle ~ ~1 ~`);
  player.runCommandAsync(`title @s actionbar §a§lCORTE ativado!`);
}

// ==================== FURAÇÃO ====================
function iniciarFuracao(player, fixedLocation) {
  const skill = SKILLS.furacao;
  const dim = player.dimension;

  const alvosIniciais = dim.getEntities({
    location: fixedLocation,
    maxDistance: skill.raio,
    excludeNames: [player.name],
    excludeTypes: ["minecraft:item"]
  });

  for (const alvo of alvosIniciais) {
    alvo.applyDamage(skill.danoInicial, {
      cause: EntityDamageCause.entityAttack,
      damagingEntity: player
    });
  }

  let ticks = 0;

  const loop = system.runInterval(() => {
    ticks++;

    if (ticks > skill.duracao) {
      system.clearRun(loop);
      player.runCommandAsync(`title @s actionbar §bFURAÇÃO finalizado`);
      return;
    }

    const alvos = dim.getEntities({
      location: fixedLocation,
      maxDistance: skill.raio,
      excludeNames: [player.name],
      excludeTypes: ["minecraft:item"]
    });

    for (const alvo of alvos) {
      alvo.applyImpulse({ x: 0, y: 0.6, z: 0 }); 
      alvo.applyDamage(skill.danoPorTick, {
        cause: EntityDamageCause.entityAttack,
        damagingEntity: player
      });
    }

    const tick = system.currentTick;
    const fx = fixedLocation.x;
    const fy = fixedLocation.y + 1.5;
    const fz = fixedLocation.z;

    for (let i = 0; i < 8; i++) { 
      const ang = (tick * 10 + i * 45) * Math.PI / 180;
      const raio = 0.5 + i * 0.2;
      const alt = i * 0.4;

      const px = fx + raio * Math.cos(ang);
      const pz = fz + raio * Math.sin(ang);
      const py = fy + alt;

      dim.runCommandAsync(`particle minecraft:smoke_particle ${px} ${py} ${pz}`);
    }

  }, 1);
}

function aplicarFuracao(player) {
  if (!hasSkill(player, "furacao")) {
    player.runCommandAsync(`title @s actionbar §cVocê não possui a skill FURAÇÃO!`);
    return;
  }

  if (emCooldown(player, "furacao")) return;

  const loc = player.location;
  iniciarFuracao(player, loc);

  player.runCommandAsync(`playanimation @s animation.furacao.spin`);
  player.runCommandAsync(`title @s actionbar §b§lFURAÇÃO ativado!`);
}

// ==================== Toggle de modo ====================
system.runInterval(() => {
  for (const player of world.getPlayers()) {
    const name = player.name;
    const sneaking = player.isSneaking;
    const was = sneakingTracker.get(name) ?? false;

    if (was && !sneaking) {
      const mode = playerSkillMode.get(name) ?? false;
      playerSkillMode.set(name, !mode);
    }

    sneakingTracker.set(name, sneaking);

    if (!playerSkillMode.has(name)) playerSkillMode.set(name, false);
  }
}, 1);

// ==================== Evento de ataque ====================
world.afterEvents.itemUse.subscribe(ev => {
  const player = ev.source;
  if (!(player instanceof Player)) return;

  const item = ev.itemStack;
  if (!item || item.typeId !== ITEM_ADAGA) return;

  const modo = playerSkillMode.get(player.name) ?? false;

  if (modo) aplicarFuracao(player);
  else aplicarCorte(player);
});

// ==================== TESTE DE DESBLOQUEIO ====================
// Apenas para teste, pode chamar depois com comandos ou eventos de missão
world.getPlayers().forEach(player => {
  desbloquearSkill(player, "corte");
  desbloquearSkill(player, "furacao");
});