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





export function initTheFinal01() {

    
    const
        FOREBODINGCHECK7 = fo.scoreChapter7, 
        pumpkinHelmet = "carved_pumpkin",
        foreboding = fo.forebodingObjective,
        mark = world.scoreboard.getObjective("Random"),

        MONOLITH_CENTER = { x: 25992, y: 260, z: 25416 },
        CIRCLE_RADIUS = 18; 


    let
        eventFlag01 = false,
        ritual01flag01 = false, 
        ritual01flag02 = false, 
        ritual01flag03 = false, 
        ritual02flag01 = false, 
        itKnockbackFlag = false; 


    

    
    function getMarkScore(player) {
        return mark?.getScore(player) || 0;
    };


    
    function spawnScaryArmorStand(spawnPos, player) {
        const dimensionId = player.dimension;

        try {
            const IT = dimensionId.spawnEntity("fo:forebearer", spawnPos);
            IT.addEffect("invisibility", 99999);
            IT.addEffect("resistance", 999999, { amplifier: 255, showParticles: false });
            IT.nameTag = "Foredoom";

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

            ritual01flag02 = true; 
            if (IT) {
                maintainITPosition(player);
                thunderAroundIT(dimensionId);
            };
        } catch (error) {
            system.runTimeout(() => { spawnScaryArmorStand(spawnPos, player) }, 40)
            console.error("Error spawning Foredoom:", error);
        }
    };

    
    function generateCirclePositions(playerCount, radius, center) {
        const positions = [];

        for (let i = 0; i < playerCount; i++) {
            const angle = (2 * Math.PI / playerCount) * i;
            const x = center.x + radius * Math.cos(angle);
            const z = center.z + radius * Math.sin(angle);
            positions.push({ x, y: center.y, z });
        }

        return positions;
    }


    
    function maintainITPosition(player) {
        let maintainInterval = system.runInterval(() => {
            const dimension = player.dimension;
            const it = dimension.getEntities({ type: "fo:forebearer", name: "Foredoom" })[0];

            if (!ritual01flag02 || ritual02flag01 || itKnockbackFlag) {
                
                if (itKnockbackFlag) {
                    const distance = 30; 
                    const knockbackPos = {
                        x: -distance,
                        z: 0,
                    };

                    
                    it.applyKnockback({ x: knockbackPos.x, z: knockbackPos.z }, 0);
                    
                }
                system.runTimeout(() => {
                    it.remove();
                }, 10)
                system.clearRun(maintainInterval);
                return;
            }

            if (ritual01flag02 && it) {
                
                dimension.runCommand(`tp @e[type=fo:forebearer,name=Foredoom] ${it.location.x} 310.5 ${it.location.z} facing ${player.name}`);

            } else {
                console.warn("IT entity not found");
                spawnScaryArmorStand({ x: MONOLITH_CENTER.x - 7, y: 310.5, z: MONOLITH_CENTER.z }, player);
            }

        }, 1);
    }


    
    function thunderAroundIT(dimension) {

        const thunderRadius = CIRCLE_RADIUS + 10;

        const lighting = system.runInterval(() => {

            if (ritual02flag01) {
                system.clearRun(lighting);
                return;
            }

            const thunderPos = getPositionAround(MONOLITH_CENTER, thunderRadius);

            try {
                const thunderblock = dimension.getTopmostBlock(thunderPos, 260)

                dimension.spawnEntity("minecraft:lightning_bolt", thunderblock.above(1).location);

            } catch (error) {
                console.error("Error spawning lighting:", error);
            }

        }, 240); 
    };


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


    
    function givePumpkinHelmet(player) {

        const equipComponent = player.getComponent("minecraft:equippable");
        const cursedPumpkin = new ItemStack(pumpkinHelmet, 1);
        cursedPumpkin.setLore([
            `§5§lᛃᚨᛉ`,
        ]);
        const enchantComponent = cursedPumpkin.getComponent("minecraft:enchantable")
        enchantComponent.addEnchantments([
            { level: 1, type: new EnchantmentType("binding"), },
            { level: 1, type: new EnchantmentType("vanishing"), }
        ]);

        
        const currentHelmet = equipComponent.getEquipment(EquipmentSlot.Head);
        if (currentHelmet) {
            player.getComponent("minecraft:inventory").container.addItem(currentHelmet);

        };

        
        equipComponent.setEquipment(EquipmentSlot.Head, cursedPumpkin);

        if (player.getDynamicProperty("PumpkinCurse") === undefined) {
            player.setDynamicProperty("PumpkinCurse", true); 
        }

    };


    
    system.runInterval(() => {
        const players = fo.overworld.getPlayers()
        if (players.length === 0) return;

        const forebodingScore = fo.forebodingScore;


        if (!eventFlag01 && forebodingScore === FOREBODINGCHECK7) {
            eventFlag01 = true;
            world.gameRules.fallDamage = false; 
            startMainEnding(players);

        };



    }, 45)



    function startMainEnding(players) {

        let
            teleportedPlayers = [],
            positionIndex = 0,
            markedPlayerName = null,
            playerCount = players.length;


        const circlePositions = generateCirclePositions(playerCount - 1, CIRCLE_RADIUS, MONOLITH_CENTER);
        
        for (const p of players) {
            if (getMarkScore(p) > 9) {
                markedPlayerName = p.name;
                break;
            }
        }
        
        if (!markedPlayerName && players.length > 0) {
            markedPlayerName = players[0].name;
        }

        


        
        let y300checkInterval = system.runInterval(() => {
            if (!ritual01flag01) {
                const playersAtY300 = players.filter(p => p.location.y >= 299);
                if (playersAtY300.length === players.length) ritual01flag01 = true;

            } else system.clearRun(y300checkInterval);
        }, 20);

        
        for (const player of players) {
            player.playSound("ambient.cave", { location: player.location, pitch: 1, volume: 0.8 });
            player.stopMusic();
            system.runTimeout(() => {
                player.playMusic("phurpa", {
                    fade: 10,
                    loop: true,
                    volume: 0.1,
                });
            }, 1);


            player.inputPermissions.setPermissionCategory(2, false) 
            player.inputPermissions.setPermissionCategory(9, false) 
            player.inputPermissions.setPermissionCategory(10, false) 
            player.inputPermissions.setPermissionCategory(11, false) 
            player.inputPermissions.setPermissionCategory(12, false) 

            
            const levitate01 = system.runInterval(() => {
                const playerLoc = {
                    x: player.location.x,
                    y: player.location.y + 0.15,
                    z: player.location.z,
                };

                healthMonitor(player);

                player.teleport(playerLoc);

                
                if (playerLoc.y >= 160 && playerLoc.y <= 160.4) {
                    system.runTimeout(() => {
                        player.playMusic("phurpa", {
                            fade: 1,
                            loop: true,
                            volume: 0.3,
                        });
                    }, 1);
                }

                
                if (playerLoc.y >= 260 && !teleportedPlayers.includes(player.name)) {
                    teleportedPlayers.push(player.name);

                    if (player.name === markedPlayerName) {
                        
                        player.teleport(MONOLITH_CENTER);

                        system.runTimeout(() => {
                            
                            spawnScaryArmorStand({ x: MONOLITH_CENTER.x - 7, y: 290.5, z: MONOLITH_CENTER.z }, player);

                        }, 100)


                    } else {
                        const pos = circlePositions[positionIndex];
                        if (pos) {
                            player.teleport(pos);
                            positionIndex++;
                        }
                    }

                };

                if (playerLoc.y >= 300.2) {
                    ritual01(player, markedPlayerName, players);
                    
                    system.clearRun(levitate01);
                }

            }, 1)

        }


    };

    
    function healthMonitor(player) {
        const health = player.getComponent("health");
        if (health && health.currentValue < 10) health.setCurrentValue(10);

    };

    
    function ritual01(player, markedPlayerName, players) {

        

        
        let levitate02 = system.runInterval(() => {
            let playerLoc2 = {
                x: player.location.x,
                y: 300,
                z: player.location.z,
            };

            
            if (ritual01flag01 && player.name === markedPlayerName && player.location.y < 310) {
                if (!ritual01flag03) {
                    system.runTimeout(() => {
                        world.playMusic("phurpa", { fade: 1, volume: 0.9, loop: true }); 
                    }, 1);
                    ritual01flag03 = true; 
                }

                
                playerLoc2.y = player.location.y + 0.01
                if (player.location.y >= 309.8) {
                    
                    ritual02(player, players);
                    system.clearRun(levitate02);
                }

            }

            player.teleport(playerLoc2, { facingLocation: { x: MONOLITH_CENTER.x - 7, y: 310, z: MONOLITH_CENTER.z } });
            


            if (ritual02flag01) {
                

                
                player.inputPermissions.setPermissionCategory(2, true); 
                player.inputPermissions.setPermissionCategory(9, true); 
                player.inputPermissions.setPermissionCategory(10, true); 
                player.inputPermissions.setPermissionCategory(11, true); 
                player.inputPermissions.setPermissionCategory(12, true); 

                system.clearRun(levitate02);
                return;
            }

        }, 1)

    };

    
    function ritual02(player, players) {
        let timer = 0;

        

        let levitate03 = system.runInterval(() => {
            const playerLoc3 = {
                x: player.location.x,
                y: 310,
                z: player.location.z,
            };

            player.teleport(playerLoc3, { facingLocation: { x: MONOLITH_CENTER.x - 7, y: 310, z: MONOLITH_CENTER.z } });

            
            timer++;



            
            if (timer === 160) {
                givePumpkinHelmet(player); 

                
                for (const p of players) {
                    p.camera.fade({
                        fadeColor:
                        {
                            red: 1,
                            green: 1,
                            blue: 1,
                        },
                        fadeTime:
                        {
                            fadeInTime: 0.01,
                            fadeOutTime: 0.05,
                            holdTime: 0.01,
                        }, 
                    });
                };
            }

            
            if (timer === 240) {
                itKnockbackFlag = true; 
                
                world.stopMusic();

            }
            
            if (timer === 260) { 
                ritual02flag01 = true; 
                player.inputPermissions.setPermissionCategory(2, true); 
                player.inputPermissions.setPermissionCategory(9, true); 
                player.inputPermissions.setPermissionCategory(10, true); 
                player.inputPermissions.setPermissionCategory(11, true); 
                player.inputPermissions.setPermissionCategory(12, true); 


                mark?.removeParticipant(player); 

                system.runTimeout(() => {
                    world.gameRules.fallDamage = true; 
                    foreboding.setScore("Counter ", -1); 
                    fo.overworld.runCommand(`function Fo/FoL5`) 
                }, 200); 

                
                ritual01flag02 = false; 

                system.clearRun(levitate03);

            }

        }, 1);

    };

};




world.afterEvents.playerSpawn.subscribe((eventData) => {
    const player = eventData.player;

    const canMove = player.inputPermissions.isPermissionCategoryEnabled(2); 
    if (!canMove) {
        player.inputPermissions.setPermissionCategory(2, true); 
        player.inputPermissions.setPermissionCategory(9, true); 
        player.inputPermissions.setPermissionCategory(10, true); 
        player.inputPermissions.setPermissionCategory(11, true); 
        player.inputPermissions.setPermissionCategory(12, true); 

        system.runTimeout(() => {
            
            player.runCommand(`kill @e[type=fo:forebearer,name=Foredoom]`);
        }, 20); 

    }

});
