import { BlockVolume, ItemStack, system, world } from "@minecraft/server";
import { ArenaMap, loadLocation } from "../ui/portal";
import { getRandomBetween } from "../utils/utils";

export const Bosses = new Map([
    [
        "pixell_bbo:ares",
        {
            experience: 3000,
            drops: [
                {
                    typeId: "pixell_bbo:core_ares",
                    amount: {
                        min: 2,
                        max: 3,
                    },
                },
                {
                    typeId: "pixell_bbo:souls",
                    amount: {
                        min: 42,
                        max: 50,
                    },
                },
            ],
        },
    ],
    [
        "pixell_bbo:hades",
        {
            experience: 9000,
            drops: [
                {
                    typeId: "pixell_bbo:core_hades",
                    amount: {
                        min: 2,
                        max: 3,
                    },
                },
                {
                    typeId: "pixell_bbo:souls",
                    amount: {
                        min: 42,
                        max: 50,
                    },
                },
            ],
        },
    ],
    [
        "pixell_bbo:unknown",
        {
            experience: 1400,
            drops: [
                {
                    typeId: "pixell_bbo:core_unknown",
                    amount: {
                        min: 2,
                        max: 3,
                    },
                },
                {
                    typeId: "pixell_bbo:souls",
                    amount: {
                        min: 42,
                        max: 50,
                    },
                },
            ],
        },
    ],
    [
        "pixell_bbo:burazazu",
        {
            experience: 1400,
            drops: [
                {
                    typeId: "pixell_bbo:core_burazazu",
                    amount: {
                        min: 2,
                        max: 3,
                    },
                },
                {
                    typeId: "pixell_bbo:souls",
                    amount: {
                        min: 42,
                        max: 50,
                    },
                },
            ],
        },
    ],
    [
        "pixell_bbo:craterus",
        {
            experience: 5000,
            drops: [
                {
                    typeId: "pixell_bbo:core_craterus",
                    amount: {
                        min: 2,
                        max: 3,
                    },
                },
                {
                    typeId: "pixell_bbo:souls",
                    amount: {
                        min: 42,
                        max: 50,
                    },
                },
            ],
        },
    ],
    [
        "pixell_bbo:sweetgabriel",
        {
            experience: 3000,
            drops: [
                {
                    typeId: "pixell_bbo:core_gabriel",
                    amount: {
                        min: 2,
                        max: 3,
                    },
                },
                {
                    typeId: "pixell_bbo:souls",
                    amount: {
                        min: 42,
                        max: 50,
                    },
                },
            ],
        },
    ],
]);

world.beforeEvents.entityRemove.subscribe((event) => {
    try {
        const { removedEntity } = event;

        const location = removedEntity.location;
        const dimension = removedEntity.dimension;
        const hasBossTag = removedEntity.hasTag("pixell_bbo:boss");

        const areaSize = 16;

        const bossData = Bosses.get(removedEntity.typeId);

        if (!bossData) return;

        if (!removedEntity.hasTag("pixell_bbo:boss")) return;

        system
            .waitTicks(1 * 20)
            .then(() => {
                loadLocation(
                    dimension,
                    "pixell_bbo:boss_health_handler",
                    new BlockVolume(
                        {
                            x: location.x - areaSize / 2,
                            y: location.y - areaSize / 2,
                            z: location.z - areaSize / 2,
                        },
                        {
                            x: location.x + areaSize / 2,
                            y: location.y + areaSize / 2,
                            z: location.z + areaSize / 2,
                        }
                    ),
                    10
                );
            })
            .then(() => {
                if (!hasBossTag) return;

                const arenaData = ArenaMap.get(removedEntity.typeId + "_portal");

                if (!arenaData) return;

                const { offsetX, height, portalSpawnOffset, structureId, bossId, bossName } =
                    arenaData;

                if (!structureId || structureId == "") return;

                const arenaSize = world.structureManager.get(structureId).size;

                const arenaCenter = {
                    x: offsetX + arenaSize.x / 2,
                    y: height,
                    z: offsetX + arenaSize.z / 2,
                };

                const portalSpawnLoc = {
                    x: arenaCenter.x + portalSpawnOffset.x,
                    y: arenaCenter.y + portalSpawnOffset.y,
                    z: arenaCenter.z + portalSpawnOffset.z,
                };

                const portal = dimension.spawnEntity("pixell_bbo:portal", portalSpawnLoc);

                portal.setDynamicProperty("target", bossId + "_portal");

                portal.setDynamicProperty("pixell_bbo:return_portal", true);

                portal.setProperty("self:portal_type", bossName.toLowerCase().replaceAll(" ", ""));
            });

        const experience = bossData.experience;

        if (!experience) return;

        for (let i = 0; i < experience; i++) {
            system.runTimeout(() => {
                const expLocation = {
                    x: location?.x + getRandomBetween(-1, 1),
                    y: location?.y + getRandomBetween(0, 1),
                    z: location?.z + getRandomBetween(-1, 1),
                };

                dimension.spawnEntity("minecraft:xp_orb", expLocation);
            }, i * 0.0015 * 20);
        }

        const drops = bossData.drops;

        for (let drop of drops) {
            const {
                typeId,
                amount: { min, max },
            } = drop;

            system.run(() => {
                const item = new ItemStack(typeId, getRandomBetween(min, max));

                dimension.spawnItem(item, location);
            });
        }
    } catch (error) {
        // console.warn(error);
    }
});
