const POWERS = new Map([
    ['Invisibility', {
        icon: 'systems/swade/assets/icons/status/status_invisible.svg',
        duration: {rounds: 5},
        extra: {expiration: 3, loseTurnOnHold: true},
        changes: []
    }],
    ['Intangibility', {
        icon: 'icons/magic/control/debuff-energy-hold-levitate-blue-yellow.webp',
        duration: {rounds: 5},
        extra: {expiration: 3, loseTurnOnHold: true},
        changes: []
    }],
    ['Fly', {
        icon: 'systems/swade/assets/icons/status/status_flying.svg',
        duration: {rounds: 5},
        extra: {expiration: 3, loseTurnOnHold: true},
        changes: []
    }],
    ['Sanctuary', {
        icon: 'icons/magic/defensive/shield-barrier-flaming-diamond-blue-yellow.webp',
        duration: {rounds: 5},
        extra: {expiration: 3, loseTurnOnHold: true},
        changes: []
    }],
    ['Arcane Protection', {
        icon: 'icons/magic/defensive/shield-barrier-deflect-gold.webp',
        duration: {rounds: 5},
        extra: {expiration: 3, loseTurnOnHold: true},
        changes: []
    }],
    ['Environmental Protection', {
        icon: 'icons/magic/defensive/armor-shield-barrier-steel.webp',
        duration: {seconds: 3600},
        extra: {expiration: 3, loseTurnOnHold: true},
        changes: []
    }]
]);
let argEffectName = "";
try {
    if (args !== undefined && POWERS.has(args[0])) {
        argEffectName = args[0];
    }
} catch (error) {}


let tokens = [];
let targets = Array.from(game.user.targets);
if (targets.length > 0) {
    tokens = targets;
} else if (canvas.tokens.controlled.length > 0) {
    tokens = canvas.tokens.controlled;
}
if (tokens.length > 0) {
    main(tokens);
} else {
    ui.notifications.error("Please select or target a token");
}

async function main(tokens) {
    let tokenList = tokens.map(t => t.name).join(", ");
    let powers = [...POWERS].map(p => p[0]).sort();
    if (argEffectName) {
        let dialogOptions = {
            title: argEffectName,
            content: `Apply <em>${argEffectName}</em> to ${tokenList}`,
            default: "cancel",
            buttons: [
                {label: "Apply", value: "apply"},
                {label: "Apply with raise", value: "raise"},
                {label: "Cancel", value: "cancel"}
            ]
        }
        let choice = await warpgate.buttonDialog(dialogOptions);
        if (choice != "cancel") {
            const power = POWERS.get(argEffectName);
            createEffect(tokens, choice, argEffectName, power);
        }
    } else {
        powers.unshift('');
        let menuOptions = {
            title: 'Apply Power',
            defaultButton: "Cancel",
            options: {}
        }
        let menuData = {
            inputs: [
                {type: 'info', label: `<strong>Affected Tokens:</strong> ${tokenList}`},
                {type: 'select', label: 'Power', options: powers},
            ],
            buttons: [
                {label: "Apply", value: "apply"},
                {label: "Apply with raise", value: "raise"},
                {label: "Cancel", value: "cancel"}
            ]
        }
        let {buttons, inputs} = await warpgate.menu(menuData, menuOptions);
        if (buttons != "cancel" && inputs[1] != '') {
            const power = POWERS.get(inputs[1]);
            createEffect(tokens, buttons, inputs[1], power);
        }
    }
}

async function createEffect(tokens, choice, powerName, power) {
    let effectName = powerName;
    let effectId = effectName.toLowerCase().replaceAll(/[^a-z0-9]/ig, '');
    const effectIcon = power.icon;
    let changes = power.changes;
    if (choice == 'raise') {
        effectName = `Major ${effectName}`;
    }
    for (const token of tokens) {
        let effectData = {
            icon: effectIcon,
            id: effectId,
            label: effectName,
            duration: power.duration,
            changes: changes,
        };
        if (power.extra) {
            effectData.flags = {'swade': power.extra};
        }
        let mutate = {
            embedded: {
                ActiveEffect: {
                }
            }
        };
        mutate.embedded.ActiveEffect[effectName] = effectData;
        let mutateOptions = {
            comparisonKeys: {'ActiveEffect': 'label'},
            name: effectName,
            permanent: true,
            description: effectName,
        }
        await warpgate.mutate(token.document, mutate, {}, mutateOptions);
    }
}