import { world, system } from "@minecraft/server";
import { ActionFormData } from "@minecraft/server-ui";
import { ConfigMenus } from "./config";

const openCooldown = new Map();
const COOLDOWN_MS = 500;

function formatarNome(id) {
  if (!id) return "";
  return id.replace(/^nz:/, "").replace(/^minecraft:/, "");
}

function getScore(player, objective) {
  const obj = world.scoreboard.getObjective(objective);
  if (!obj) return 0;
  try {
    return obj.getScore(player) ?? 0;
  } catch {
    return 0;
  }
}

function gerarIcone(botao) {
  if (botao.requisitos || botao.recompensa || botao.acao) return undefined;
  const rw = botao.ganhar || {};

  if (botao.nome && typeof botao.nome === "string") {
    const nomeLower = botao.nome.toLowerCase();
    if (nomeLower.includes("kurama") && nomeLower.includes("yin")) {
      return "textures/items/pamobile/nz_alma_kurama_yin";
    }
    if (nomeLower.includes("kurama") && nomeLower.includes("yang")) {
      return "textures/items/pamobile/nz_alma_kurama_yang";
    }
  }

  if (rw.item && rw.item.length > 0) {
    const [id] = rw.item[0].split("#");
    if (id === "nz:alma_songoku" || id === "nz:alma_son_goku") {
      return "textures/items/pamobile/nz_alma_son_goku";
    }
    return `textures/items/pamobile/nz_${formatarNome(id)}`;
  }

  if (rw.tag && rw.tag.length > 0) {
    const tag = rw.tag[0];
    if (tag.startsWith("jinchuuriki_")) {
      const nome = tag.replace("jinchuuriki_", "");
      if (nome === "songoku" || nome === "son_goku") {
        return "textures/items/pamobile/nz_alma_son_goku";
      }
      return `textures/items/pamobile/nz_alma_${nome}`;
    }
    if (tag === "isshiki_karma") return "textures/items/pamobile/nz_isshiki_karma_tag";
    if (tag === "momoshiki_karma") return "textures/items/pamobile/nz_momoshiki_karma_tag";
    if (tag === "modo_trovao") return "textures/items/pamobile/nz_jutsu_modo_trovao";
    if (tag === "nz:liberar_gen_lvl1") return "textures/items/pamobile/nz_dragao_de_fogo1";
    if (tag === "nz:liberar_gen_lvl2") return "textures/items/pamobile/nz_dragao_de_fogo2";
    if (tag === "nz:liberar_gen_lvl3") return "textures/items/pamobile/nz_dragao_de_fogo3";
    if (tag.startsWith("nz:")) return `textures/items/pamobile/nz_${formatarNome(tag)}`;
    if (tag.startsWith("modo_")) return `textures/items/pamobile/nz_${tag}`;
    if (tag.startsWith("maldicao_")) return `textures/items/pamobile/nz_${tag}`;
    if (tag.startsWith("sennin_")) return `textures/items/pamobile/nz_${tag}`;
    if (tag === "byakugou") return "textures/items/pamobile/nz_byakugou";
    return `textures/items/pamobile/nz_${tag}`;
  }

  if (rw.summon && rw.summon.length > 0) {
    const entRaw = Array.isArray(rw.summon) ? rw.summon[0] : rw.summon;
    const nome = formatarNome(entRaw);
    return `textures/items/pamobile/nz_${nome}_spawn_egg`;
  }

  if (rw.function) {
    const fn = Array.isArray(rw.function) ? rw.function[0] : rw.function;
    return `textures/items/pamobile/nz_${fn}`;
  }

  return "textures/items/pamobile/nz_default";
}

// Checagem especial de Karma
function podeInteragirComNpc(player, npcId) {
  const karmaAtual = getScore(player, "karma") ?? 0;
  const id = formatarNome(npcId);

  const npcsKarmaAlto = ["jiraya","tsunade","maito_gai_trade","minato_trade"];
  const npcsKarmaBaixo = ["orochimaru","momoshiki","isshiki","uchiha"];

  if (npcsKarmaAlto.includes(id)) return karmaAtual >= 500;
  if (npcsKarmaBaixo.includes(id)) return karmaAtual <= 500; // corrigido
  return true;
}

function podePegarMissao(player, rankNec) {
  const ranks = ["Genin","Chunin","Anbu","Jonin","Hokage","Kazekage","Mizukage","Tsuchikage","Raikage"];
  const idxNec = ranks.indexOf(rankNec);
  const idxPlayer = ranks.findIndex(r => player.hasTag(r));
  return idxPlayer >= idxNec;
}

// Timer
function iniciarTimerMissao(player, tagMissao, rank, ents = []) {
  if (player.hasTag("missao_concluida")) return;

  let tempo = 100;
  if (rank === "Chunin") tempo = 220;
  if (rank === "Anbu" || rank === "Jonin" || rank === "Hokage" || rank === "Kazekage" || rank === "Mizukage" || rank === "Tsuchikage" || rank === "Raikage") tempo = 280;
  if (tagMissao.includes("zoro")) tempo = 220;

  let restante = tempo;
  const intervalo = system.runInterval(() => {
    if (player.hasTag("missao_concluida")) {
      system.clearRun(intervalo);
      return;
    }

    restante -= 1;

    // Mensagem a cada 10 segundos
    if (restante % 10 === 0 && restante > 0) {
      player.sendMessage(`§eTempo restante: ${restante} segundos`);
    }

    if (restante <= 0) {
      player.removeTag(tagMissao);
      player.sendMessage("§cVocê falhou a missão por não concluir no tempo!");

      // Limpa os itens nz:m1 do inventário
      player.runCommandAsync(`clear @s nz:m1`);

      // Teleporta apenas os NPCs da missão
      for (const ent of ents) {
        player.runCommandAsync(`tp @e[type=${ent}] 99999 99999 99999`);
      }

      system.clearRun(intervalo);
    }
  }, 20); // 20 ticks = 1 segundo
}

// Início da missão
async function processarMissao(player, botao) {
  const req = botao.requisitos || {};
  const acao = botao.acao || {};

  if (req.tagMin && !podePegarMissao(player, req.tagMin)) {
    player.sendMessage("§cVocê não tem o rank necessário para esta missão.");
    return;
  }

  const tags = player.getTags();
  const missaoAtiva = tags.find(t => t.startsWith("missao_") && t.endsWith("_ativa"));

  // Se já existe uma missão ativa, tenta concluir consumindo os itens
  if (missaoAtiva) {
    await concluirMissaoTrade(player, botao, missaoAtiva);
    return;
  }

  // Remove tag de missão concluída para iniciar uma nova
  player.removeTag("missao_concluida");

  const tagMissao = `missao_${botao.nome.replace(/\s+/g,"_").toLowerCase()}_ativa`;
  player.addTag(tagMissao);

  // Zoro → até 18 blocos
  if (botao.nome.toLowerCase().includes("zoro")) {
    const dx = Math.floor(Math.random() * 37) - 18;
    const dz = Math.floor(Math.random() * 37) - 18;
    await player.runCommandAsync(`summon nz:zoro_m ~${dx} ~ ~${dz}`);
    player.sendMessage("§eMissão iniciada: Achar o Zoro!");
    iniciarTimerMissao(player, tagMissao, "Zoro", ["nz:zoro_m"]);
    return;
  }

  // Gato → até 4 blocos
  if (botao.nome.toLowerCase().includes("gato")) {
    const dx = Math.floor(Math.random() * 9) - 4;
    const dz = Math.floor(Math.random() * 9) - 4;
    await player.runCommandAsync(`summon nz:cat ~${dx} ~ ~${dz}`);
    player.sendMessage("§eMissão iniciada: Pegar o gato!");
    iniciarTimerMissao(player, tagMissao, "Genin", ["nz:cat"]);
    return;
  }

  // Outros NPCs → até 4 blocos
  if (acao.summon) {
    const ents = Array.isArray(acao.summon) ? acao.summon : [acao.summon];
    for (const ent of ents) {
      const dx = Math.floor(Math.random() * 9) - 4;
      const dz = Math.floor(Math.random() * 9) - 4;
      await player.runCommandAsync(`summon ${ent} ~${dx} ~ ~${dz}`);
    }
    iniciarTimerMissao(player, tagMissao, req.tagMin, ents);
  }

  player.sendMessage(`§eMissão iniciada: ${botao.nome}!`);
}

const ultimoScore = new Map();

function verificarMascara(player) {
  const missoes = getScore(player, "MissoesConcluidas");
  const id = player.id;

  // pega o último valor salvo
  const anterior = ultimoScore.get(id) ?? 0;

  // só dispara se mudou
  if (missoes !== anterior) {
    ultimoScore.set(id, missoes);

    if (!player.hasTag("mascaraanbu1")) {
      if (missoes >= 30) {
        player.addTag("mascaraanbu1");
        player.sendMessage("§bVocê recebeu a máscara Anbu do Kakashi!");
      } else {
        player.sendMessage(`§eFaltam ${30 - missoes} missões para ganhar a máscara Anbu do Kakashi!`);
      }
    } else if (!player.hasTag("mascaraanbu2")) {
      if (missoes >= 50) {
        player.addTag("mascaraanbu2");
        player.sendMessage("§5Você recebeu a máscara Anbu do Itachi!");
      } else {
        player.sendMessage(`§eFaltam ${50 - missoes} missões para ganhar a máscara Anbu do Itachi!`);
      }
    }
  }
}

// roda em intervalo rápido, mas só dispara se mudar
system.runInterval(() => {
  for (const player of world.getPlayers()) {
    verificarMascara(player);
  }
}, 20); // checa a cada segundo, mas só fala se mudou

// Função de concluir missão (sem lógica das máscaras, só incrementa o score)
async function concluirMissaoTrade(player, botao, tagMissao, ents = []) {
  const rw = botao.recompensa || {};
  const acao = botao.acao || {};
  let qtdM1 = acao.summon ? (Array.isArray(acao.summon) ? acao.summon.length : 1) : 0;

  const inv = player.getComponent("inventory")?.container;
  let qtd = 0;
  for (let i = 0; i < inv.size; i++) {
    const it = inv.getItem(i);
    if (it && it.typeId === "nz:m1") qtd += it.amount;
  }

  if (qtd >= qtdM1) {
    await player.runCommandAsync(`clear @s nz:m1 0 ${qtdM1}`);
    player.removeTag(tagMissao);
    player.addTag("missao_concluida");
    player.sendMessage(`§aMissão concluída: ${botao.nome}!`);

    // Recompensas extras
    if (rw.scores) {
      for (const s of rw.scores) {
        const [obj, val] = s.split("#");
        await player.runCommandAsync(`scoreboard players add @s ${obj} ${parseInt(val)}`);
      }
    }

    // Incrementa o contador de missões
    await player.runCommandAsync(`scoreboard players add @s MissoesConcluidas 1`);

    // Aqui não há mais checagem das máscaras
  } else {
    player.sendMessage(`§cVocê precisa de ${qtdM1} itens nz:m1 para concluir esta missão.`);
  }
}

function aplicarNeutralizacao(npc) {
  try {
    npc.runCommandAsync("effect @s weakness 5 5 true");
    npc.runCommandAsync("effect @s slowness 5 5 true");
    npc.runCommandAsync("effect @s blindness 5 1 true");
  } catch {}
}

// Fluxo normal de menus (trade ou missão)
world.afterEvents.entityHitEntity.subscribe(ev => {
  const { hitEntity, damagingEntity } = ev;
  if (!damagingEntity || damagingEntity.typeId !== "minecraft:player") return;

  if (!damagingEntity.isSneaking) {
    damagingEntity.addTag("alvo");
    return;
  }

  const menuConfig = ConfigMenus.find(m => m.entidade === hitEntity.typeId);
  if (!menuConfig) return;

  // Checagem de Karma antes de abrir o menu
  if (!podeInteragirComNpc(damagingEntity, hitEntity.typeId)) {
    damagingEntity.sendMessage("§cSeu nível de Karma não permite interagir com este NPC.");
    return;
  }

  damagingEntity.addTag("em_trade");
  damagingEntity.removeTag("alvo");
  try { hitEntity.runCommandAsync("event entity @s pacify_on"); } catch {}

  const now = Date.now();
  const last = openCooldown.get(damagingEntity.id) || 0;
  if (now - last < COOLDOWN_MS) return;
  openCooldown.set(damagingEntity.id, now);

  const form = new ActionFormData()
    .title(`:zenkai_ui:${menuConfig.nomeMenu}`)
    .body("Escolha uma opção:");
  menuConfig.botoes.forEach(b => {
    const icon = gerarIcone(b);
    form.button(b.nome, icon);
  });

  system.run(() => {
    form.show(damagingEntity).then(res => {
      damagingEntity.removeTag("em_trade");
      damagingEntity.removeTag("alvo");

      aplicarNeutralizacao(hitEntity);

      system.runTimeout(() => {
        try { hitEntity.runCommandAsync("event entity @s pacify_off"); } catch {}
      }, 20);

      if (res.canceled) return;
      const botao = menuConfig.botoes[res.selection];
      if (!botao) return;

      if (botao.requisitos || botao.recompensa || botao.acao) {
        processarMissao(damagingEntity, botao);
      } else {
        processarTransacao(damagingEntity, botao);
      }

    }).catch(() => {
      damagingEntity.removeTag("em_trade");
      damagingEntity.removeTag("alvo");
      aplicarNeutralizacao(hitEntity);
      system.runTimeout(() => {
        try { hitEntity.runCommandAsync("event entity @s pacify_off"); } catch {}
      }, 20);
    });
  });
});

// ==========================
// Sistema de Trade Original
// ==========================
async function processarTransacao(player, botao) {
  const req = botao.trocar || {};
  const rw = botao.ganhar || {};
  const faltam = [];

  if (req.tag) {
    for (const t of req.tag) {
      if (!player.hasTag(t)) faltam.push(`Tag necessária: ${t}`);
    }
  }

  if (req.scores) {
    for (const s of req.scores) {
      const [obj, val] = s.split("#");
      const vNec = parseInt(val);
      const atual = getScore(player, obj);
      if (atual === null) {
        faltam.push(`Scoreboard inexistente: ${obj} (0/${vNec})`);
        continue;
      }
      if (atual < vNec) {
        faltam.push(`${obj}: ${atual}/${vNec} (faltam ${vNec - atual})`);
      }
    }
  }

  if (req.item) {
    const inv = player.getComponent("inventory")?.container;
    if (!inv) {
      faltam.push("Inventário indisponível");
    } else {
      for (const iStr of req.item) {
        const [id, qtdStr] = iStr.split("#");
        const qNec = parseInt(qtdStr);
        let qTem = 0;
        for (let i = 0; i < inv.size; i++) {
          const it = inv.getItem(i);
          if (it && (it.typeId === id || it.typeId === "minecraft:" + id || it.typeId.endsWith(id))) {
            qTem += it.amount;
          }
        }
        if (qTem < qNec) {
          faltam.push(`Item ${formatarNome(id)}: ${qTem}/${qNec} (faltam ${qNec - qTem})`);
        }
      }
    }
  }

  if (faltam.length > 0) {
    player.sendMessage(`§cPara comprar "${botao.nome}" falta: ${faltam.join(", ")}`);
    try { await player.runCommandAsync(`playsound random.orb @s`); } catch {}
    return;
  }

  try {
    if (req.tag) req.tag.forEach(t => player.removeTag(t));

    if (req.scores) {
      for (const s of req.scores) {
        const [obj, val] = s.split("#");
        const vNec = parseInt(val);
        const atual = getScore(player, obj) ?? 0;
        if (atual >= vNec) {
          await player.runCommandAsync(`scoreboard players remove @s ${obj} ${vNec}`);
        } else {
          player.sendMessage(`§cSaldo insuficiente em ${obj}: ${atual}/${vNec}. Transação cancelada.`);
          try { await player.runCommandAsync(`playsound random.orb @s`); } catch {}
          return;
        }
      }
    }

    if (req.item) {
      for (const iStr of req.item) {
        const [id, qtd] = iStr.split("#");
        await player.runCommandAsync(`clear @s ${id} 0 ${qtd}`);
      }
    }

    if (rw.tag) rw.tag.forEach(t => player.addTag(t));

    if (rw.scores) {
      for (const s of rw.scores) {
        const [obj, val] = s.split("#");
        const vAdd = parseInt(val);
        await player.runCommandAsync(`scoreboard players add @s ${obj} ${vAdd}`);
      }
    }

    if (rw.item) {
      for (const iStr of rw.item) {
        const [id, qtd] = iStr.split("#");
        await player.runCommandAsync(`give @s ${id} ${qtd}`);
      }
    }

    if (rw.function) {
      const fns = Array.isArray(rw.function) ? rw.function : [rw.function];
      for (const fn of fns) {
        await player.runCommandAsync(`function ${fn}`);
      }
    }

    if (rw.function) {
      const fns = Array.isArray(rw.function) ? rw.function : [rw.function];
      for (const fn of fns) {
        await player.runCommandAsync(`function ${fn}`);
      }
    }

    if (rw.summon) {
      const ents = Array.isArray(rw.summon) ? rw.summon : [rw.summon];
      for (const ent of ents) {
        await player.runCommandAsync(`summon ${ent} ~ ~ ~`);
      }
    }

    if (rw.tag) {
      player.sendMessage(`§aVocê aprendeu ${botao.nome}!`);
    } else if (rw.summon) {
      player.sendMessage(`§aVocê desafiou ${botao.nome}!`);
    } else if (rw.item) {
      player.sendMessage(`§aVocê obteve ${botao.nome}!`);
    } else if (rw.function) {
      player.sendMessage(`§aMissão concluída: ${botao.nome}!`);
    } else {
      player.sendMessage("§aSucesso!");
    }

    try { await player.runCommandAsync(`playsound random.levelup @s`); } catch {}
  } catch (err) {
    player.sendMessage("§cErro: " + err);
  }
}