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

const DURACAO_BARRIER = 20; // 1 segundo (20 ticks)

const barriersAtivos = new Map(); 
const jogadoresAtivos = new Set();
const playersEstado = new Map();

function getPlayerId(player) {
  try {
    return player.scoreboardIdentity || player.name;
  } catch {
    return player.name;
  }
}

function posToString(pos) {
  return `${pos.x},${pos.y},${pos.z}`;
}

// ----------------------
// Funções utilitárias
// ----------------------
function getScore(player, objective) {
  try {
    const obj = world.scoreboard.getObjective(objective);
    if (!obj) return 0;
    return obj.getScore(player.scoreboardIdentity);
  } catch {
    return 0;
  }
}

function setScore(player, objective, value) {
  try {
    let obj = world.scoreboard.getObjective(objective);
    if (!obj) {
      world.scoreboard.addObjective(objective, objective);
      obj = world.scoreboard.getObjective(objective);
    }
    obj.setScore(player.scoreboardIdentity, value);
  } catch {}
}

function getProp(player, prop) {
  try {
    return player.getDynamicProperty(prop) ?? 0;
  } catch {
    return 0;
  }
}

function setProp(player, prop, value) {
  try {
    player.setDynamicProperty(prop, value);
  } catch {}
}

// ----------------------
// HABILIDADE ÁGUA
// ----------------------
function ativarHabilidade(player) {
  if (!player.hasTag("agua")) return;
  jogadoresAtivos.add(getPlayerId(player));
  player.sendMessage("§aHabilidade de andar sobre a água ativada!");
}

function desativarHabilidade(player) {
  const id = getPlayerId(player);
  jogadoresAtivos.delete(id);
  player.sendMessage("§cHabilidade de andar sobre a água desativada!");

  const dimension = player.dimension;
  for (const [key, meta] of Array.from(barriersAtivos.entries())) {
    if (meta.ownerId === id) {
      const [x, y, z] = key.split(",").map(Number);
      try {
        const b = dimension.getBlock({ x, y, z });
        if (b) b.setType(meta.original);
      } catch {}
      barriersAtivos.delete(key);
    }
  }
}

function alternarHabilidade(player) {
  const id = getPlayerId(player);
  if (!player.hasTag("agua")) return;

  if (jogadoresAtivos.has(id)) desativarHabilidade(player);
  else ativarHabilidade(player);
}

// ----------------------
// DETECTAR PULO + AGACHAR
// ----------------------
system.runInterval(() => {
  for (const player of world.getPlayers()) {
    const id = getPlayerId(player);
    const estadoAnterior = playersEstado.get(id) || {
      y: player.location.y,
      noChao: false,
      agachando: false,
      pulando: false,
    };

    const posAtual = player.location;
    const estaNoChao = player.isOnGround;
    const estaAgachado = player.isSneaking;
    const deltaY = posAtual.y - estadoAnterior.y;

    let pulando = estadoAnterior.pulando;

    if (deltaY > 0.1 && !estaNoChao) pulando = true;

    if (estaNoChao && pulando) {
      if (estaAgachado) alternarHabilidade(player);
      pulando = false;
    }

    playersEstado.set(id, {
      y: posAtual.y,
      noChao: estaNoChao,
      agachando: estaAgachado,
      pulando: pulando,
    });
  }
}, 5);

// ----------------------
// SISTEMA DAS BARRIERS
// ----------------------
system.runInterval(() => {
  for (const player of world.getPlayers()) {
    const id = getPlayerId(player);
    if (!jogadoresAtivos.has(id)) continue;

    if (!player.hasTag("agua")) {
      desativarHabilidade(player);
      continue;
    }

    const loc = player.location;
    const dimension = player.dimension;

    const px = Math.floor(loc.x);
    const py = Math.floor(loc.y);
    const pz = Math.floor(loc.z);
    const y = py - 1;

    let colocouBarrier = false;

    // gera 3x3 blocos sob o player (inclui centro)
    for (let dx = -1; dx <= 1; dx++) {
      for (let dz = -1; dz <= 1; dz++) {
        const pos = { x: px + dx, y, z: pz + dz };
        let block;
        try {
          block = dimension.getBlock(pos);
        } catch {
          continue;
        }

        if (block && block.typeId === "minecraft:water") {
          try {
            const depth = block.permutation.getState("liquid_depth");
            if (depth === 0) {
              const key = posToString(pos);

              if (!barriersAtivos.has(key)) {
                barriersAtivos.set(key, {
                  ticks: DURACAO_BARRIER,
                  ownerId: id,
                  original: block.typeId
                });
                block.setType("minecraft:barrier");
                colocouBarrier = true;
              } else {
                const meta = barriersAtivos.get(key);
                meta.ticks = DURACAO_BARRIER;
                if (!meta.ownerId) meta.ownerId = id;
              }
            }
          } catch {}
        }
      }
    }

    if (colocouBarrier) {
      try {
        player.addEffect("slow_falling", 10, { amplifier: 1, showParticles: false });
      } catch {}
    }

    // diminuir ticks das barriers
    for (const [key, meta] of Array.from(barriersAtivos.entries())) {
      if (meta.ticks <= 0) {
        const [bx, by, bz] = key.split(",").map(Number);
        try {
          const b = dimension.getBlock({ x: bx, y: by, z: bz });
          if (b) b.setType(meta.original);
        } catch {}
        barriersAtivos.delete(key);
      } else {
        meta.ticks -= 1;
      }
    }
  }
}, 1);

// ----------------------
// Consumo de Chakra/Stamina a cada segundo
// ----------------------
system.runInterval(() => {
  for (const player of world.getPlayers()) {
    const id = getPlayerId(player);
    if (!jogadoresAtivos.has(id)) continue;
    if (!player.hasTag("agua")) {
      desativarHabilidade(player);
      continue;
    }

    let chakra = getProp(player, "chakraCarga");   // chakra via prop
    let stamina = getScore(player, "Stamina");     // stamina via scoreboard

    if (chakra < 2 || stamina < 4) {
      player.sendMessage("§cVocê ficou sem energia para manter a habilidade!");
      desativarHabilidade(player);
      continue;
    }

    setProp(player, "chakraCarga", chakra - 2);
    setScore(player, "Stamina", stamina - 4);
  }
}, 20); // 20 ticks = 1 segundo