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





export function initHostileMob() {

    
    const
        mobIdsToRemove = [
            "minecraft:blaze",
            "minecraft:bogged",
            "minecraft:creeper",
            "minecraft:evocation_illager",
            "minecraft:ghast",
            "minecraft:hoglin",
            "minecraft:husk",
            "minecraft:magma_cube",
            "minecraft:phantom",
            "minecraft:piglin_brute",
            "minecraft:pillager",
            "minecraft:ravager",
            "minecraft:skeleton",
            "minecraft:slime",
            "minecraft:stray",
            "minecraft:vindicator",
            "minecraft:witch",
            "minecraft:wither_skeleton",
            "minecraft:zoglin",
            "minecraft:zombie",
            "minecraft:zombie_villager_v2",
            "minecraft:drowned",
            "minecraft:enderman",
            "minecraft:piglin",
            "minecraft:spider",
            "minecraft:zombie_pigman",
            "minecraft:parched"
        ],

        effectsPool = [
            { effect: "speed", weight: 4 },
            { effect: "strength", weight: 2 },
            { effect: "regeneration", weight: 2 },
            { effect: "invisibility", weight: 2 },
        ]



    const

        villagesDoorsChance = 1 / 45, 

        FOREBODINGCHECK3 = fo.scoreChapter3, 
        FOREBODINGCHECK4 = fo.scoreChapter4, 
        FOREBODINGCHECK5 = fo.scoreChapter5; 


    let
        forebodingScore = fo.forebodingScore, 
        probabilityModifier = 1, 
        villageDoorsFlag = world.getDynamicProperty("areVillagersGone") === undefined ? false : world.getDynamicProperty("areVillagersGone"), 
        villageDoorsKillCount = 0; 


    
    system.runInterval(() => {
        forebodingScore = fo.forebodingScore; 
        probabilityModifier = fo.netProbabilityModifier;
    }, 604);

    
    function safeRemoveEntity(entity, retries = 5, delayTicks = 1) {
        try {
            
            entity.remove();
            
        } catch (error) {
            
            if (retries > 0) {
                
                system.runTimeout(() => safeRemoveEntity(entity, retries - 1, delayTicks), delayTicks);
            } else {
                
                
            }
        }
    };

    
    function getRandomWeightedEffect() {
        
        const totalWeight = effectsPool.reduce((sum, item) => sum + item.weight, 0);

        
        const random = Math.random() * totalWeight;

        
        let currentWeight = 0;
        for (const item of effectsPool) {
            currentWeight += item.weight;
            if (random <= currentWeight) {
                return item.effect;
            }
        }

        
        return effectsPool[0].effect;
    }

    
    function addEffectToEntity(entity, retries = 5, delayTicks = 1) {
        try {
            
            entity.addEffect("resistance", 360000, { amplifier: 1, showParticles: false })
            
        } catch (error) {
            
            if (retries > 0) {
                
                system.runTimeout(() => addEffectToEntity(entity, retries - 1, delayTicks), delayTicks);
            } else {
                
                
            }
        }
    };

    
    function addEffectToEntity2(entity, retries = 5, delayTicks = 1) {
        try {
            const effect = getRandomWeightedEffect(); 
            
            entity.addEffect(effect, 360000, { amplifier: 0, showParticles: false })
            
        } catch (error) {
            
            if (retries > 0) {
                
                system.runTimeout(() => addEffectToEntity2(entity, retries - 1, delayTicks), delayTicks);
            } else {
                
                
            }
        }
    };

    
    world.afterEvents.entitySpawn.subscribe((event) => {
        const { cause, entity } = event;

        
        if (villageDoorsFlag && forebodingScore >= FOREBODINGCHECK3 && forebodingScore < FOREBODINGCHECK5) {

            
            if ((entity.typeId === "minecraft:villager" || entity.typeId === "minecraft:villager_v2") &&
                cause === "Spawned" 
            ) {

                openNearbyDoors(entity);

            }
        }

        
        if (forebodingScore >= FOREBODINGCHECK3 + (fo.durationChapter3 * 0.3) && forebodingScore < FOREBODINGCHECK5) {
            
            if (mobIdsToRemove.includes(entity.typeId)) {
                
                safeRemoveEntity(entity);
            }
        }

        
        
        if (forebodingScore >= FOREBODINGCHECK5) {
            
            if (mobIdsToRemove.includes(entity.typeId)) {
                
                addEffectToEntity(entity);
            }

            
            if (entity.typeId.includes("minecraft:spider")) {
                
                addEffectToEntity2(entity);
            }

        }

    });



    

    
    const doorTypes = fo.doorIds;

    const doorProcessingQueue = [];
    let isProcessingQueue = false;

    system.runTimeout(() => {

        system.runInterval(() => {
            if (!villageDoorsFlag && forebodingScore >= FOREBODINGCHECK3 && forebodingScore < FOREBODINGCHECK5 && Math.random() <= (villagesDoorsChance * probabilityModifier)) {
                villageDoorsFlag = true;
                world.setDynamicProperty("areVillagersGone", true);

                

            }

        }, 2357) 

    }, 236);

    
    function openNearbyDoors(villager) {
        
        doorProcessingQueue.push(villager);

        if (!isProcessingQueue) {
            processDoorQueue();
        }
    };


    function processDoorQueue() {
        isProcessingQueue = true;
        const batchSize = 1; 
        let processed = 0;

        while (doorProcessingQueue.length > 0 && processed < batchSize) {
            const villager = doorProcessingQueue.shift();
            if (villager?.isValid) {
                actuallyOpenDoors(villager);
                processed++;
            }
        }

        if (doorProcessingQueue.length > 0) {
            system.run(processDoorQueue); 
        } else {
            isProcessingQueue = false;
        }
    };

    
    function actuallyOpenDoors(villager) {
        try {
            const dimension = world.getDimension(villager.dimension.id);
            const location = villager.location;

            
            const minX = Math.floor(location.x - 4);
            const maxX = Math.floor(location.x + 4);
            const minY = Math.max(Math.floor(location.y - 3), -60);
            const maxY = Math.min(Math.floor(location.y + 3), 315);
            const minZ = Math.floor(location.z - 4);
            const maxZ = Math.floor(location.z + 4);

            dimension.runCommand(`/tickingarea add ${minX} ${minY} ${minZ} ${maxX} ${maxY} ${maxZ} foVillageDoors`);

            
            for (let x = minX; x <= maxX; x++) {
                for (let y = minY; y <= maxY; y++) {
                    for (let z = minZ; z <= maxZ; z++) {
                        const block = dimension.getBlock({ x, y, z });

                        
                        if (block && doorTypes.includes(block.typeId)) {
                            const isUpperBlock = block.permutation.getState("upper_block_bit");
                            const isClosed = !block.permutation.getState("open_bit");

                            
                            if (!isUpperBlock && isClosed) {
                                try {
                                    const doorPermutation = block.permutation.withState("open_bit", true);
                                    block.setPermutation(doorPermutation);

                                    
                                    if (block.typeId.includes("copper")) {
                                        dimension.playSound("open_door.copper", block.location, { volume: 2 });
                                    } else {
                                        dimension.playSound("random.door_open", block.location, { volume: 2 });
                                    }
                                } catch (error) {
                                    
                                }
                            }
                        }
                    }
                }
            }

            system.runTimeout(() => {
                dimension.runCommand(`/tickingarea remove foVillageDoors`);
                villager.remove();

                villageDoorsKillCount++

                if (villageDoorsKillCount >= 12) {
                    villageDoorsFlag = false;
                    world.setDynamicProperty("areVillagersGone", false);
                    villageDoorsKillCount = 0; 
                }

            }, 1)
        } catch (error) {
            
        }

    };

};