import { Player, system, world } from "@minecraft/server";
import { setPlayerArenaGamemode } from "../entities/Player";
import "./Junkbox";

export class BossFightArena {
    #bossId = "";
    #structureId = "";
    #sfx = "";
    #offsetX;
    requestedItems = [];

    constructor(bossID, structureId, sfx, offsetX, requests = []) {
        this.#bossId = bossID;
        this.#sfx = sfx;
        this.#structureId = structureId;
        this.#offsetX = offsetX;
        this.requestedItems = requests;
    }

    /** @param {Player} player */
    build(player, innerOffsetX = 0, innerOffsetZ = 0) {
        player.addEffect("slowness", 20 * 32, { amplifier: 255, showParticles: false });
        player.addEffect("slow_falling", 20 * 32, { amplifier: 255, showParticles: false });
        player.addEffect("invisibility", 20 * 32, { amplifier: 255, showParticles: false });
        player.addEffect("darkness", 20 * 32, { amplifier: 255, showParticles: false });

        const location = {
            x: 200000 + (innerOffsetX ?? 0) * 400,
            z: this.#offsetX + (innerOffsetZ ?? 0) * 400,
            y: 160, //default 160
        };

        world.setDynamicProperty("px_bbo:portal_" + innerOffsetX + "_" + innerOffsetZ, location);
        const chunkPosition = {
            x: Math.floor(player.location.x / 8),
            y: Math.floor(player.location.y / 8),
            z: Math.floor(player.location.z / 8),
        };

        const oldLocation = player.location;

        player.teleport(location, {
            dimension: world.getDimension("the_end"),
        });

        setPlayerArenaGamemode(player);

        // setPlayerArenaFog(player, this.#bossId);

        let loop = () => {
            try {
                if (player?.dimension?.id == "minecraft:the_end") {
                    if (!player?.dimension?.getBlock(location)?.isValid()) {
                        system.runTimeout(loop, 25);
                        return;
                    }
                } else {
                    system.runTimeout(loop, 5);
                    return;
                }
            } catch (x) {
                system.runTimeout(loop, 5);
                return;
            }

            {
                const junkboxes = player.dimension.getEntities({
                    type: "pixell_bbo:junkbox",
                    maxDistance: 256,
                    location: location,
                });
                if (junkboxes.length > 0) {
                    player.teleport(junkboxes[0].location);
                    player.addTag("pixell_bbo:idle_player");
                    return;
                }
            }

            const dimension = player.dimension;

            const structure = world.structureManager.get(this.#structureId);

            const origin = {
                x: location.x - structure.size.x / 2,
                z: location.z - structure.size.z / 2,
                y: location.y - structure.size.y / 2,
            };

            let junkbox;

            try {
                junkbox = dimension.spawnEntity("pixell_bbo:junkbox", origin);
            } catch (e) {
                system.runTimeout(loop, 5);
                return;
            }

            junkbox.setDynamicProperty("music", this.#sfx);

            junkbox.setDynamicProperty("source", oldLocation);

            world.structureManager.place(structure, dimension, origin);
            let playerSpawnPosition = location;

            let bossSpawnPosition = location;

            let postLoad = () => {
                for (let x = 0; x < structure.size.x; x++) {
                    for (let z = 0; z < structure.size.z; z++) {
                        for (let y = 0; y < structure.size.y; y++) {
                            const block = structure.getBlockPermutation({ x, y, z });
                            if (!block) continue;
                            const position = { x: origin.x + x, y: origin.y + y, z: origin.z + z };
                            if (block.type.id == "minecraft:bedrock") {
                                dimension.setBlockType(position, "minecraft:air");
                                playerSpawnPosition = position;
                            } else if (block.type.id == "minecraft:end_portal_frame") {
                                dimension.setBlockType(position, "minecraft:air");
                                bossSpawnPosition = position;
                            }
                        }
                    }
                }

                junkbox.setDynamicProperty("spawnBoss", bossSpawnPosition);
                junkbox.setDynamicProperty("boss", this.#bossId);
                junkbox.setDynamicProperty("spawnPlayer", playerSpawnPosition);
                junkbox.setDynamicProperty(
                    "key",
                    "px_bbo:portal_" + innerOffsetX + "_" + innerOffsetZ
                );

                system.runTimeout(() => {
                    dimension.setBlockType(playerSpawnPosition, "minecraft:air");
                    dimension.setBlockType(bossSpawnPosition, "minecraft:air");
                    player.removeEffect("slowness");
                    player.removeEffect("invisibility");
                    player.removeEffect("slow_falling");
                    player.removeEffect("darkness");
                    dimension
                        .spawnEntity(this.#bossId, bossSpawnPosition)
                        .addTag("pixell_bbo:boss");
                    dimension.spawnEntity("pixell_bbo:skybox", bossSpawnPosition);
                    player.teleport(playerSpawnPosition, {
                        facingLocation: bossSpawnPosition,
                    });
                }, 5);
            };

            let runPost = () => {
                system.runTimeout(() => {
                    try {
                        postLoad();
                    } catch (e) {
                        // log("Error on Load", e);
                        runPost();
                    }
                }, 5);
            };
            runPost();
        };
        system.runTimeout(loop, 5);
    }
}
