import { world } from "@minecraft/server";
import { ActionFormData, ModalFormData } from "@minecraft/server-ui";

const scoreboardName = "gs_cb_settings";
const settingPlayers = {
    blockParticles: "blockParticles",
    mobVFX: "mobVFX",
    caveFog: "caveFog",
    fireDisasters: "fireDisasters",
    iceDisasters: "iceDisasters"
};

function getSetting(setting) {
    try {
        return world.scoreboard.getObjective(scoreboardName).getScore(setting) === 1;
    } catch {
        return false;
    }
}

function setSetting(setting, value) {
    let objective = world.scoreboard.getObjective(scoreboardName);
    if (!objective) objective = world.scoreboard.addObjective(scoreboardName, scoreboardName);
    objective.setScore(setting, value ? 1 : 0);
    
    if (setting === settingPlayers.mobVFX) {
        updateOrelinVFX(value);
    }
}

function updateOrelinVFX(enabled) {
    const eventName = enabled ? "gs_cb:vfx_on" : "gs_cb:vfx_off";
    const dimension = world.getDimension("overworld");
    const entities = dimension.getEntities();
    
    entities.filter(entity => {
        const entityId = entity.typeId || "";
        const entityName = entity.nameTag || "";
        return entityId.toLowerCase().includes("orelin") || 
               entityName.toLowerCase().includes("orelin");
    }).forEach(entity => {
        entity.triggerEvent(eventName);
    });
}

function showVFXForm(player) {
    const blockParticles = getSetting(settingPlayers.blockParticles);
    const mobVFX = getSetting(settingPlayers.mobVFX);
    const caveFog = getSetting(settingPlayers.caveFog);

    new ModalFormData()
        .title("VFX Settings")
        .toggle("Block Particles", blockParticles)
        .toggle("Orelin VFX", mobVFX)
        .toggle("Cave Fog", caveFog)
        .show(player)
        .then(r => {
            if (r.canceled) return;
            const [newBlock, newAmbient, newcaveFog] = r.formValues;
            if (blockParticles !== newBlock) setSetting(settingPlayers.blockParticles, newBlock);
            if (mobVFX !== newAmbient) setSetting(settingPlayers.mobVFX, newAmbient);
            if (caveFog !== newcaveFog) setSetting(settingPlayers.caveFog, newcaveFog);
        })
        .catch(console.error);
}

function showDisasterForm(player) {
    const fireDisasters = getSetting(settingPlayers.fireDisasters);
    const iceDisasters = getSetting(settingPlayers.iceDisasters);

    new ModalFormData()
        .title("Natural Disasters")
        .toggle("Enable Fire Disasters", fireDisasters)
        .toggle("Enable Ice Disasters", iceDisasters)
        .show(player)
        .then(r => {
            if (r.canceled) return;
            const [newFire, newIce] = r.formValues;
            if (fireDisasters !== newFire) setSetting(settingPlayers.fireDisasters, newFire);
            if (iceDisasters !== newIce) setSetting(settingPlayers.iceDisasters, newIce);
        })
        .catch(console.error);
}

export const Settings = {
    onUse({ source }) {
        const player = source;

        new ActionFormData()
            .title("Cave Biomes Settings")
            .body("Choose a settings category:\n\n")
            .button("VFX Settings", "textures/gs/cb/ui/vfx_icon")
            .button("Natural Disasters", "textures/gs/cb/ui/disasters_icon")
            .show(player)
            .then(r => {
                if (r.canceled) return;
                if (r.selection === 0) showVFXForm(player);
                else if (r.selection === 1) showDisasterForm(player);
            })
            .catch(console.error);
    }
};

world.beforeEvents.worldInitialize.subscribe(e => {
    e.itemComponentRegistry.registerCustomComponent("gs_cb:settings", Settings);
});

world.afterEvents.worldInitialize.subscribe(e => {
    let objective = world.scoreboard.getObjective(scoreboardName);
    if (!objective) {
        objective = world.scoreboard.addObjective(scoreboardName, scoreboardName);
    }
    for (const key of Object.values(settingPlayers)) {
        try {
            objective.getScore(key);
        } catch {
            objective.setScore(key, 1);
        }
    }
})