import {
    system,
    StartupEvent,
    CustomCommand,
    CommandPermissionLevel,
    CustomCommandParamType,
    CustomCommandOrigin,
    CustomCommandResult,
    CustomCommandStatus,
    world
} from "@minecraft/server";

system.beforeEvents.startup.subscribe((init) => {
    const modeEnum = ["normal_mode", "hard_mode", "void_mode"];
    const worldMode = {
        name: "edx:world_mode",
        description: "Change the mode of the world for debugging or having fun",
        permissionLevel: CommandPermissionLevel.GameDirectors,//op
        cheatsRequired: true,
        mandatoryParameters: [
            { type: CustomCommandParamType.Enum, name: "edx:mode" }
        ]
    };
    const playerSoulEnum = ["disable", "can_wear_equipment","can_attack_players"];
    const playerSoul = {
        name: "edx:player_soul",
        description: "Enable/disable player souls on death",
        permissionLevel: CommandPermissionLevel.GameDirectors,//op
        mandatoryParameters: [
            { type: CustomCommandParamType.Enum, name: "edx:player_soul_params" },
            { type: CustomCommandParamType.Boolean, name: "value" }
        ]
    };
    const worldEntityEnum = ["world", "entity"];
    const getWorldDynamicProperty = {
        name: "edx:getdynamicproperty",
        description: "Used to debug, return/set a dynamic property",
        permissionLevel: CommandPermissionLevel.GameDirectors,//op
        mandatoryParameters: [
            { type: CustomCommandParamType.Enum, name: "edx:world_entity" }
        ],
        optionalParameters: [
            { type: CustomCommandParamType.String, name: "dynamicproperty" },
            { type: CustomCommandParamType.EntitySelector, name: "selector" }
        ]
    };
    const setWorldDynamicProperty = {
        name: "edx:setdynamicproperty",
        description: "Used to debug, return/set a dynamic property",
        permissionLevel: CommandPermissionLevel.GameDirectors,//op
        mandatoryParameters: [
            { type: CustomCommandParamType.Enum, name: "edx:world_entity" }
        ],
        optionalParameters: [
            { type: CustomCommandParamType.String, name: "dynamicproperty" },
            { type: CustomCommandParamType.String, name: "value" },
            { type: CustomCommandParamType.EntitySelector, name: "selector" }
        ]
    };
    init.customCommandRegistry.registerEnum("edx:player_soul_params", playerSoulEnum);
    init.customCommandRegistry.registerEnum("edx:mode", modeEnum);
    init.customCommandRegistry.registerEnum("edx:world_entity", worldEntityEnum);
    // registerEnum() must be called before registerCommand()
    init.customCommandRegistry.registerCommand(worldMode, worldModeCommand);
    init.customCommandRegistry.registerCommand(getWorldDynamicProperty, getWorldDynamicPropertyCommand);
    init.customCommandRegistry.registerCommand(setWorldDynamicProperty, setWorldDynamicPropertyCommand);
    init.customCommandRegistry.registerCommand(playerSoul, playerSoulCommand);
});

function worldModeCommand(origin, mode) {
    const player = origin.sourceEntity;
    if (mode == "normal_mode") {
        player.sendMessage({ rawtext: [{ translate: "message.event.NormalModeSet", }] });
        world?.setDynamicProperty('hard_mode', false)
        world?.setDynamicProperty('void_mode', false)
    }
    else if (mode == "hard_mode") {
        player.sendMessage({ rawtext: [{ translate: "message.event.HardModeSet", }] });
        world?.setDynamicProperty('hard_mode', true)
        world?.setDynamicProperty('void_mode', false)
    }
    else if (mode == "void_mode") {
        player.sendMessage({ rawtext: [{ translate: "message.event.VoidModeSet", }] });
        world?.setDynamicProperty('hard_mode', true)
        world?.setDynamicProperty('void_mode', true)
    }
    return {
        status: CustomCommandStatus.Success
    };
}

function playerSoulCommand(origin, param,value) {
    const player = origin.sourceEntity;
    player.sendMessage({ rawtext: [{ translate: "message.event.PlayerSoulSet" }, { text: " " }, { text: value.toString() }] });
    if(param == "disable")
        world?.setDynamicProperty('player_soul', value)
    else if(param=="can_wear_equipment")
        world?.setDynamicProperty('player_soul_equipment', value)
    else if(param == "can_attack_players")
        world?.setDynamicProperty('player_soul_attack', value)
    return {
        status: CustomCommandStatus.Success
    };
}

function getWorldDynamicPropertyCommand(origin, world_entity, dynamicproperty, entities) {
    const player = origin.sourceEntity;
    if (world_entity == "world") {
        if (dynamicproperty != undefined)
            player.sendMessage({ rawtext: [{ text: dynamicproperty }, { text: ": " }, { text: world?.getDynamicProperty(dynamicproperty)?.toString() ?? "undefined" }] });
        else {
            return { status: CustomCommandStatus.Failure }
        }
    }
    else if (world_entity == "entity" && entities != undefined && entities != []) {
        if (dynamicproperty != undefined) {
            for (const entity of entities) {
                player.sendMessage({ rawtext: [{ text: entity.typeId }, { text: " | " }, { text: dynamicproperty }, { text: ": " }, { text: entity?.getDynamicProperty(dynamicproperty)?.toString() ?? "undefined" }] });
            }
        }
        else {
            return { status: CustomCommandStatus.Failure }
        }
    }
    else {
        return { status: CustomCommandStatus.Failure }
    }

    return {
        status: CustomCommandStatus.Success
    };
}

function setWorldDynamicPropertyCommand(origin, world_entity, dynamicproperty,value, entities) {
    if (value == "undefined") {
        value == undefined
    }
    else if (Number(value) != undefined && Number(value) != NaN) {
        value == Number(value)
    }
    const player = origin.sourceEntity;
    if (world_entity == "world" ) {
        world?.setDynamicProperty(dynamicproperty,value)
        player.sendMessage({ rawtext: [{ text: dynamicproperty }, { text: " set to " }, { text: world?.getDynamicProperty(dynamicproperty)?.toString() ?? "undefined" }] });
    }
    else if (world_entity == "entity" && entities != undefined && entities != []) {
        for (const entity of entities) {
            entity?.setDynamicProperty(dynamicproperty,value)
            player.sendMessage({ rawtext: [{ text: entity.typeId }, { text: " | " }, { text: dynamicproperty }, { text: " set to " }, { text: world?.getDynamicProperty(dynamicproperty)?.toString() ?? "undefined" }] });
        }
    }
    else {
        return { status: CustomCommandStatus.Failure }
    }

    return {
        status: CustomCommandStatus.Success
    };
}


