import { world, system } from "@minecraft/server";
import { fo } from './utilities/fo_constants.js';









export function initVoidChapter() {

    
    const
        FOREBODINGCHECK7 = -6002, 
        ITRadius = 23, 
        pumpkinHelmet = "carved_pumpkin",
        INTERVAL = 1203; 


    let intervalVariance = 0; 


    
    system.runTimeout(() => {
        fo.overworld.runCommand(`kill @e[type=zombie,name=Foredoom]`);
        fo.nether.runCommand(`kill @e[type=zombie,name=Foredoom]`);
        fo.theEnd.runCommand(`kill @e[type=zombie,name=Foredoom]`);

    }, 12)


    
    function getDistance(pos1, pos2) {
        if (!pos1 || !pos2) {
            return Infinity; 
        }
        return Math.sqrt(
            Math.pow(pos1.x - pos2.x, 2) +
            Math.pow(pos1.z - pos2.z, 2)
        );
    }

    
    function getPositionAround(center, radius, dimension) {

        const randomY = center.y + 3 + Math.floor(Math.random() * 7);
        const clampedY = Math.min(Math.max(randomY, dimension.heightRange.min), dimension.heightRange.max - 3);

        const angle = Math.random() * Math.PI * 2;
        const distance = radius;
        return {
            x: center.x + Math.cos(angle) * distance,
            y: clampedY,
            z: center.z + Math.sin(angle) * distance,
        };
    }

    
    function spawnScaryArmorStand(spawnPos, playerDimension, player) {
        const dimensionId = world.getDimension(playerDimension);

        try {
            const IT = dimensionId.spawnEntity("minecraft:zombie", spawnPos);
            IT.addEffect("invisibility", 99999);
            IT.nameTag = "Foredoom";

            const tpInterval = system.runInterval(() => {
                dimensionId.runCommand(`tp @e[type=zombie,name=Foredoom] ${spawnPos.x} ${spawnPos.y} ${spawnPos.z} facing ${player.name}`);
            }, 1)

            
            system.runTimeout(() => { dimensionId.playSound("ambient.cave", spawnPos, { volume: 2, }) }, 15)

            dimensionId.runCommand(`replaceitem entity @e[type=zombie,name=Foredoom] slot.armor.head 0 ${pumpkinHelmet}`);

            

            system.runTimeout(() => {
                
                system.clearRun(tpInterval);

                let spawnPosY = spawnPos.y + 0.3
                let tpCount = 0;

                const tpIntervalExit = system.runInterval(() => { 
                    spawnPosY = spawnPosY + 0.4

                    if (spawnPosY > 310 || tpCount >= 60) {
                        try {
                            IT.remove(); 
                            system.clearRun(tpIntervalExit);
                        } catch (error) {
                            
                            system.clearRun(tpIntervalExit);
                        }
                    }

                    dimensionId.runCommand(`tp @e[type=zombie,name=Foredoom] ${spawnPos.x} ${spawnPosY} ${spawnPos.z} facing @p`);
                    tpCount++

                }, 1)


            }, 61)
        } catch (error) {
            console.error("Error spawning armor stand:", error);
        }

    };

    system.runInterval(() => {
        const forebodingScore = fo.forebodingScore;

        if (forebodingScore <= FOREBODINGCHECK7) {

            const players = world.getAllPlayers();

            if (players.length === 0) return;

            intervalVariance = Math.floor(Math.random() * 300);

            const player = players[Math.floor(Math.random() * players.length)]; 
            const playerDimension = player.dimension.id

            

            
            player.runCommand(`kill @e[type=zombie,name=Foredoom]`);

            let
                validblock = false,
                attempt = 0;

            while (!validblock && attempt < 40) {
                attempt++;

                const spawnPos = getPositionAround(player.location, ITRadius, player.dimension);
                const dimensionId = world.getDimension(playerDimension);

                const playersNearby = dimensionId.getPlayers({ 
                    location: spawnPos,
                    maxDistance: Math.max(ITRadius - 8, 15),
                });

                if (playersNearby.length === 0) {

                    const blockPosAbove = {
                        x: spawnPos.x,
                        y: spawnPos.y + 1,
                        z: spawnPos.z,
                    };

                    const blockPosAbove2 = {
                        x: spawnPos.x,
                        y: spawnPos.y + 2,
                        z: spawnPos.z,
                    };

                    const block = dimensionId.getBlock(spawnPos),
                        blockAbove = dimensionId.getBlock(blockPosAbove),
                        blockAbove2 = dimensionId.getBlock(blockPosAbove2);

                    if (block && block.isAir && blockAbove.isAir && blockAbove2.isAir) {

                        
                        const playerHeadPos = {
                            x: player.location.x,
                            y: Math.floor(player.location.y) + 1.6,
                            z: player.location.z
                        };

                        
                        const checkPos = {
                            x: blockAbove2.location.x + 0.5, 
                            y: blockAbove2.location.y + 0.5,
                            z: blockAbove2.location.z + 0.5
                        };

                        
                        const dx = playerHeadPos.x - checkPos.x;
                        const dy = playerHeadPos.y - checkPos.y;
                        const dz = playerHeadPos.z - checkPos.z;

                        
                        const distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
                        const steps = Math.ceil(distance); 

                        let hasClearView = true;

                        
                        for (let i = 0; i <= steps && hasClearView; i++) {
                            const t = i / steps;
                            const checkX = checkPos.x + dx * t;
                            const checkY = checkPos.y + dy * t;
                            const checkZ = checkPos.z + dz * t;

                            if (checkY > player.dimension.heightRange.max || checkY < player.dimension.heightRange.min) return;

                            
                            const viewBlock = dimensionId.getBlock({ x: Math.floor(checkX), y: Math.floor(checkY), z: Math.floor(checkZ) });

                            
                            if (!viewBlock.isAir) {
                                hasClearView = false;
                            }
                        }

                        if (hasClearView) {
                            validblock = true;

                            spawnScaryArmorStand(spawnPos, playerDimension, player);
                        }


                    }


                }

            }

        }


    }, INTERVAL + intervalVariance)

};
