import { world, system } from "@minecraft/server";
import BIOMES from "../util/biomes";
import { settingEnabled } from "../settings";
import { sendDeveloperMessage } from "../util/debug";

// Constants
const fogManagerDelayTicks = 20;
const fogSettings = {
    cherry_grove_fog: "squaredreams_realism:cherry_grove_fog",
    cold_fog: "squaredreams_realism:cold_fog",
    cool_fog: "squaredreams_realism:cool_fog",
    default_fog: "squaredreams_realism:default_fog",
    desert_fog: "squaredreams_realism:desert_fog",
    hot_fog: "squaredreams_realism:hot_fog",
    jungle_fog: "squaredreams_realism:jungle_fog",
    ocean_fog: "squaredreams_realism:ocean_fog",
    swamp_fog: "squaredreams_realism:swamp_fog",
    warm_fog: "squaredreams_realism:warm_fog",
};

// Assign fogs to biomes here
const biomeToSequenceName = {
    [BIOMES.lush_caves]: "default_fog",
    [BIOMES.dripstone_caves]: "default_fog",
    [BIOMES.deep_dark]: "default_fog",
    [BIOMES.beach]: "default_fog",
    [BIOMES.forest]: "warm_fog",
    [BIOMES.plains]: "warm_fog",
    [BIOMES.desert]: "desert_fog",
    [BIOMES.jungle]: "jungle_fog",
    [BIOMES.birch]: "default_fog",
    [BIOMES.frozen]: "cold_fog",
    [BIOMES.savanna]: "hot_fog",
    [BIOMES.mesa]: "hot_fog",
    [BIOMES.swamp]: "swamp_fog",
    [BIOMES.taiga]: "cool_fog",
    [BIOMES.mangrove]: "swamp_fog",
    [BIOMES.cherry_grove]: "cherry_grove_fog",
    [BIOMES.cold]: "cold_fog",
    [BIOMES.ocean]: "ocean_fog"
};

// Cache to store the last known biome for each player
const playerBiomeCache = new Map();

// Main loop to check all players at regular intervals
system.runInterval(() => {
    // Grab all players
    const allPlayers = world.getAllPlayers();
    // If no players, return
    if (allPlayers.length === 0) return;

    const customFogEnabled = settingEnabled("custom_fog");

    // Check every player
    allPlayers.forEach(player => {
        const { dimension, location } = player;
        // Floor it and center on block
        const resultLocation = {
            x: Math.floor(location.x) + 0.5,
            y: Math.floor(location.y),
            z: Math.floor(location.z) + 0.5,
        };

        if (!customFogEnabled) {
            // Custom fog setting is disabled, clear fog for this player
            for (let fogName in fogSettings) {
                const fogId = fogSettings[fogName];
                try {
                    player.runCommand(`fog @s remove ${fogId}`);
                } catch (err) {
                    sendDeveloperMessage(player, `§6§l[!]§e§l Realism Debug:§r§7 Failed to remove fog for player ${player.name}: ${err}`);
                }
            }
            return; // Exit early if custom fog is disabled
        }

        // Summon biome tester
        let biomeTester;
        try {
            biomeTester = dimension.spawnEntity("squaredreams_realism:biome_tester", resultLocation);
        } catch (err) {
            sendDeveloperMessage(player, `§6§l[!]§e§l Realism Debug:§r§7 Failed to spawn biome tester for player ${player.name}: ${err}`);
            return;
        }

        if (!biomeTester || !biomeTester.isValid()) {
            sendDeveloperMessage(player, `§6§l[!]§e§l Realism Debug:§r§7 Biome tester is not valid for player ${player.name}`);
            return;
        }

        // Trigger event to query biome
        biomeTester.triggerEvent("squaredreams_realism:query_biome");

        // Handle biome query result after a short delay
        system.runTimeout(() => {
            try {
                // Retrieve biome ID from entity property
                const biomeId = biomeTester.getProperty("squaredreams_realism:biome_query");

                // Get the last known biome for this player
                const lastBiomeId = playerBiomeCache.get(player.id);

                // If the biome is the same as the last one, exit early
                if (biomeId === lastBiomeId) {
                    return;
                }

                // Update the cache with the new biome ID
                playerBiomeCache.set(player.id, biomeId);

                let sequenceName = biomeToSequenceName[biomeId] || "default_fog";
                const fogIdentifier = fogSettings[sequenceName];

                // Apply new fog
                try {
                    player.runCommand(`fog @s push ${fogIdentifier} ${fogIdentifier}`);
                } catch (err) {
                    sendDeveloperMessage(player, `§6§l[!]§e§l Realism Debug:§r§7 Failed to apply fog for player ${player.name}: ${err}`);
                }

                // Remove other fogs after a delay
                system.runTimeout(() => {
                    for (let fogName in fogSettings) {
                        const fogId = fogSettings[fogName];
                        if (fogId !== fogIdentifier) {
                            try {
                                player.runCommand(`fog @s remove ${fogId}`);
                            } catch (err) {
                                sendDeveloperMessage(player, `§6§l[!]§e§l Realism Debug:§r§7 Failed to remove fog ${fogId} for player ${player.name}: ${err}`);
                            }
                        }
                    }
                }, 60);
            } catch (err) {
                sendDeveloperMessage(player, `§6§l[!]§e§l Realism Debug:§r§7 Error handling biome query for player ${player.name}: ${err}`);
            } finally {
                // Despawn the biome tester entity
                biomeTester.triggerEvent("squaredreams_realism:instant_despawn");
            }
        }, 30);
    });
}, fogManagerDelayTicks);