import { system, world } from "@minecraft/server";
import { Bosses } from "../data/bosses";
import { EntitiesArray } from "../data/entities";
import { getRandomBetween, isBoss, isEntityLoaded, isNightTime } from "../utils/utils";

const lastBloodMoon = world.getDynamicProperty("lastBloodMoon");
const nextBloodMoon = world.getDynamicProperty("nextBloodMoon");
const isBloodMoon = world.getDynamicProperty("isBloodMoon");

const currentDay = world.getDay();

if (isBloodMoon == undefined) {
    world.setDynamicProperty("isBloodMoon", false);
}
if (lastBloodMoon == undefined) {
    world.setDynamicProperty("lastBloodMoon", 0);
}
if (nextBloodMoon == undefined) {
    world.setDynamicProperty("nextBloodMoon", 15);
}

const BLOODMOON_HANDLER = system.runInterval(() => {
    const isBloodMoon = world.getDynamicProperty("isBloodMoon");
   // console.warn(world.getDynamicProperty("nextBloodMoon"));
    if (isNightTime()) {
        if (isBloodMoon == true) {
            const players = world.getAllPlayers();

            for (let player of players) {
                const topBlock =
                    player?.dimension.getTopmostBlock({
                        x: player.location.x,
                        z: player.location.z,
                    }) ?? player?.dimension.getBlock(player.location);

                player?.dimension.spawnParticle("px_hc:nebline_efx", topBlock.location);
            }
        }
    }
}, 1 * 20);

const monsters = EntitiesArray.reduce((acc, curr) => {
    if (!isBoss(curr[1].typeId, Bosses)) acc.push(curr[1].typeId);

    return acc;
}, []);

const daysBetweenBloodMoon = 15;

world.afterEvents.entitySpawn.subscribe((event) => {
    const { entity } = event;

    const currentDay = world.getDay();

    const isNight = isNightTime();
    const lastBloodMoon = world.getDynamicProperty("lastBloodMoon");
    const nextBloodMoon = world.getDynamicProperty("nextBloodMoon");
    const isBloodMoon = world.getDynamicProperty("isBloodMoon");

    if (isNight) {
        if (lastBloodMoon == currentDay) {
            setNextBloodMoon(currentDay + daysBetweenBloodMoon);
        }
        if (nextBloodMoon < currentDay) {
            setNextBloodMoon(currentDay + daysBetweenBloodMoon);
        }
        if (nextBloodMoon == currentDay) {
            system.runTimeout(() => {
                world.sendMessage("§4Blood Moon§r §eis in the sky, there will be more monsters!§r");
            }, 0.1 * 20);

            setBloodMoon(true);
            setLastBloodMoon(currentDay);
        }

        if (isBloodMoon) {
            system.runTimeout(() => {
                if (isEntityLoaded(entity)) {
                    if (
                        entity.matches({ families: ["monster"] }) &&
                        !monsters.includes(entity.typeId)
                    ) {
                        const isClone = entity?.getDynamicProperty("clone") ?? false;

                        const chance = Math.round(Math.random() * 100);

                        if (!isClone) {
                            const clone = entity.dimension.spawnEntity(
                                entity.typeId,
                                entity.location
                            );

                            if (chance > 50) {
                                const monster = entity.dimension.spawnEntity(
                                    monsters[getRandomBetween(0, monsters.length - 1)],
                                    entity.location
                                );
                            }

                            clone.setDynamicProperty("clone", true);
                        }
                    }
                }
            }, 1 * 20);
        }
    } else if (isNight == false) {
        if (nextBloodMoon > currentDay) {
            setBloodMoon(false);
        }
    }
});

/**
 *
 * @param {Number} day
 */
function setNextBloodMoon(day) {
    world.setDynamicProperty("nextBloodMoon", day);
}
/**
 *
 * @param {Number} day
 */
function setLastBloodMoon(day) {
    world.setDynamicProperty("lastBloodMoon", day);
}

/**
 *
 * @param {Boolean} bool
 */
function setBloodMoon(bool) {
    world.setDynamicProperty("isBloodMoon", bool);
}

world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
    const { block, player } = event;

    if (block.typeId == "minecraft:bed") {
        const isNight = isNightTime();
        const isBloodMoon = world.getDynamicProperty("isBloodMoon");

        if (isNight && !isBloodMoon) {
            world.sendMessage("players can't sleep during the §4Blood Moon!§r");
            event.cancel = true;
        }
    }
});
