import { system, world } from "@minecraft/server";
import { getRandomBetween, isEntityLoaded, isNightTime } from "../utils/utils";
import { Entities } from "../entities/Entities";

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

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

const BLOODMOON_HANDLER = system.runInterval(() => {
    const isBloodMoon = world.getDynamicProperty("isBloodMoon");

    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 = new Map([
    [1, "px_hc:jester_clone"],
    [2, "px_hc:bunny_monster"],
    [3, "px_hc:clown_box"],
]);

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) {
            const random = Math.min(8, Math.round(Math.random() * 8 + 3));
            setNextBloodMoon(currentDay + random);
        }
        if (nextBloodMoon < currentDay) {
            const random = Math.min(8, Math.round(Math.random() * 8 + 3));
            setNextBloodMoon(currentDay + random);
        }
        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"] })) {
                        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.get(getRandomBetween(1, 3)),
                                    entity.location
                                );

                                if (monster.typeId == Entities.jester_clone) {
                                    monster.triggerEvent("clown:persistent");
                                }
                            }

                            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);
}
