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

export const event_raincloud = {
  onTick: ({ block, dimension }) => {
    dimension.spawnParticle("dungeon:rain", {
      x: block.location.x,
      y: block.location.y,
      z: block.location.z,
    });
  },
};

const TARGET_BLOCKS = new Set(["dungeon:darkcloud", "dungeon:cloud"]);
const SCOREBOARD_NAME = "cloudblocks";

const state = new Map(); 
let TICK = 0;

const CHECK_EVERY_TICKS = 30;
const MOVE_EPS = 0;          

system.runInterval(() => { TICK++; }, 1);

function pid(player) {
  return player.id ?? player.name;
}

function cmd(player, s) {
  try { player.runCommand(s); } catch {}
}

function setActive(player, active) {
  if (active) {
    cmd(player, `tag @s add cloudzone`);
    cmd(player, `scoreboard players set @s ${SCOREBOARD_NAME} 1`);
  } else {
    cmd(player, `scoreboard players set @s ${SCOREBOARD_NAME} 0`);
    cmd(player, `tag @s remove cloudzone`);
  }
}

function ensureEntry(id) {
  let st = state.get(id);
  if (!st) {
    st = { active: false, nextTick: 0, lastX: 999999, lastY: 999999, lastZ: 999999 };
    state.set(id, st);
  }
  return st;
}

export function detectCloudBlocks(player) {
  const id = pid(player);
  const st = ensureEntry(id);

  if (TICK < st.nextTick) return;
  st.nextTick = TICK + CHECK_EVERY_TICKS;

  const pos = player.location;

  const bx = Math.floor(pos.x);
  const by = Math.floor(pos.y - 1);
  const bz = Math.floor(pos.z);

  if (
    Math.abs(bx - st.lastX) <= MOVE_EPS &&
    Math.abs(by - st.lastY) <= MOVE_EPS &&
    Math.abs(bz - st.lastZ) <= MOVE_EPS
  ) {
    return;
  }

  st.lastX = bx;
  st.lastY = by;
  st.lastZ = bz;

  const dim = player.dimension;

  let inCloud = false;
  try {
    const block = dim.getBlock({ x: bx, y: by, z: bz });
    inCloud = !!block && TARGET_BLOCKS.has(block.typeId);
  } catch {
    inCloud = false;
  }

  if (inCloud) {
    if (!st.active) {
      st.active = true;
      setActive(player, true);
    }
    cmd(player, `effect @s slow_falling 2 1 true`);
    return;
  }

  if (st.active) {
    st.active = false;
    setActive(player, false);
  }
}

function cleanup() {
  let players = [];
  try { players = world.getPlayers(); } catch { players = []; }
  const alive = new Set(players.map(p => pid(p)));
  for (const k of state.keys()) {
    if (!alive.has(k)) state.delete(k);
  }
}

system.runInterval(() => {
  const players = world.getPlayers();
  if (players.length === 0) return;

  for (const p of players) {
    detectCloudBlocks(p);
  }
}, 10);

system.runInterval(() => {
  cleanup();
}, 200);
