const ICON = 'icons/magic/symbols/circle-ouroboros.webp';
const ACTORFOLDER = "Summon Ally";

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[0]);
} else {
    ui.notifications.error("Please select or target a token");
}

async function main(token) {
    let tokenList = token.name;
    let folder = game.folders.find(f => f.data.type == 'Actor' && f.data.name == ACTORFOLDER)
    let menuOptions = {
        title: "Summon Ally",
        defaultButton: "cancel",
        options: {}
    }
    let menuData = {
        inputs: [
            { type: 'header', label: 'Summon Ally' },
            { type: 'info', label: `${tokenList} is summoning an ally` },
            {
                type: 'info',
                label: `<table><thead>
                <tr><th>Rank</th><th>Cost</th><th>Servant</th></tr>
                </thead><tbody>
                <tr><td>Novice</td><td>2</td><td>Attendant</td></tr>
                <tr><td>Seasoned</td><td>4</td><td>Bodyguard</td></tr>
                <tr><td>Veteran</td><td>6*</td><td>Mirror Self*</td></tr>
                <tr><td>Heroic</td><td>8</td><td>Sentinel</td></tr>
                </tbody></table> 
                `
            },
            {
                type: 'select',
                label: "Ally to summon",
                options: folder.contents.map(a => a.data.name)
            },
            {
                type: 'number',
                label: 'Number to spawn (+half total cost per addtl.)',
                options: 1
            },
            { type: 'checkbox', label: 'Bite/Claw (+1)', options: false }
        ],
        buttons: [
            { label: "Apply", value: "apply" },
            { label: "Apply with Raise", value: "raise" },
            { label: "Cancel", value: "cancel" }
        ]
    }

    let {buttons, inputs} = await warpgate.menu(menuData, menuOptions);
    let summonData = {
        raise: (buttons == "raise"),   
        actorName: (inputs[3]),
        number: inputs[4],
        addBiteClaw: inputs[5],
    }
    summonData.actor = folder.contents.find(a => a.data.name == summonData.actorName);
    summonData.icon = summonData.actor.data.token.img;
    if (buttons && buttons != 'cancel') {
        doWork(summonData, token);
    }
}

async function doWork(summonData, token) {
    console.log("Summon Ally", token, summonData);
    let effectData = {
        icon: ICON,
        id: "summonally",
        label: "Summoned Ally",
        duration: { rounds: 5 },
        flags: {
            swade: {
                expiration: 3,
                loseTurnOnHold: true
            }
        },
        changes: [],
    };
    let mutateOptions = {
        comparisonKeys: { 'ActiveEffect': 'label' },
        name: "Summoned Ally",
        permanent: true,
        description: "Summoned Ally",
    }
    let mutate = {
        embedded: {
            ActiveEffect: {
                "Summoned Ally": effectData,
            }
        }
    };
    await warpgate.mutate(token.document, mutate, {}, mutateOptions);
    let spawnOptions = {
        controllingActor: token.actor,
        duplicates: summonData.number,
        comparisonKeys: {'ActiveEffect': 'label'},
        crosshairs: {
            size: 1,
            icon: summonData.icon,
            label: `Summon ${summonData.actorName}`,
            drawOutline: false,
            rememberControlled: true
        }
    }
    let mutateData = {
        token: {
            actorLink: false,
            name: `${token.name}'s ${summonData.actor.data.token.name}`,
        },
        embedded: {
            Item: {}
        }
    }
    if (summonData.raise) {
        mutateData.embedded.Item.Resilient = {
            "name": "Resilient",
            "type": "ability",
            "img": "systems/swade/assets/icons/ability.svg",
            "data": {
                "description": "<div class=\"swpf-core\">\n<p>Some creatures, such as ogres or dire versions of common animals on Golarion, are tough to put down.</p>\n<p>Resilient Extras can take one @Compendium[swpf-core-rules.swpf-rules.Wounds]{Wound} before they&rsquo;re @Compendium[swpf-core-rules.swpf-rules.Incapacitation]{Incapacitated}, Very Resilient Extras can take two. @Compendium[swpf-core-rules.swpf-rules.Wild Cards and Extras]{Wild Cards} can&rsquo;t be Resilient or Very Resilient. The abilities exist to bring select Extras a little closer to the heroes and villains who lead them.</p>\n</div>",
                "notes": "",
                "additionalStats": {},
                "subtype": "special",
                "grantsPowers": false
            },
            "effects": {},
            "flags": {
                "core": {
                    "sourceId": "Compendium.swpf-core-rules.swpf-abilities.kiu5yk2aQkUGwlHN"
                },
            }
        }
    }
   
    if (summonData.addBiteClaw) {
        mutateData.embedded.Item["Bite/Claw"] = {
            "name": "Bite/Claw",
            "type": "weapon",
            "img": "icons/creatures/claws/claw-hooked-curved.webp",
            "data": {
                "description": "",
                "notes": "",
                "additionalStats": {},
                "quantity": 1,
                "weight": 0,
                "price": 0,
                "equippable": true,
                "equipped": true,
                "isVehicular": false,
                "actions": {
                    "skill": "Fighting",
                    "skillMod": "",
                    "dmgMod": "",
                    "additional": {}
                },
                "bonusDamageDie": 6,
                "damage": "@str+d6",
                "range": "",
                "rof": "1",
                "ap": 0,
                "parry": 0,
                "minStr": "",
                "shots": 0,
                "currentShots": 0,
                "ammo": "",
                "autoReload": false
            },
            "effects": {},
        }
    }
    await warpgate.spawn(summonData.actorName, mutateData, {}, spawnOptions)
}