var generateUUID = (function() {
    "use strict";

    var a = 0, b = [];
    return function() {
        var c = (new Date()).getTime() + 0, d = c === a;
        a = c;
        for (var e = new Array(8), f = 7; 0 <= f; f--) {
            e[f] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(c % 64);
            c = Math.floor(c / 64);
        }
        c = e.join("");
        if (d) {
            for (f = 11; 0 <= f && 63 === b[f]; f--) {
                b[f] = 0;
            }
            b[f]++;
        } else {
            for (f = 0; 12 > f; f++) {
                b[f] = Math.floor(64 * Math.random());
            }
        }
        for (f = 0; 12 > f; f++){
            c += "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]);
        }
        return c;
    };
}()),

generateRowID = function () {
    "use strict";
    return generateUUID().replace(/_/g, "Z");
};

var addAttr = function(char_id, name, value, max) {
    let obj = {
        name: name,
        current: value,
        characterid: char_id
    };

    if(max) {
        obj.max = max;
    }
    
    return createObj("attribute", obj);
};

on("chat:message", function(msg) {
    if(msg.type == "api" && msg.content.indexOf("!acksimport ") !== -1) {
        var default_token_images = {
            "arcane": "",
            "divine": "https://s3.amazonaws.com/files.d20.io/images/137282084/8KCYW2UxnjP83Frhl0rLyg/thumb.png?1590201189",
            "physical": ""
        };
        
        var data = msg.content.replace("!acksimport ", "");
        
        var npcs = JSON.parse(data);
        for(let c of npcs) {
            sendChat(msg.who, "Creating NPC: " + c.name);
            
            // Create the character sheet for this NPC
            let sheet = createObj("character", {
                name: c.name
            });
            sheet.set('bio', "A generated npc character.");
            sheet.set('gmnotes', "Generated by Atr0phyACKS");

            // Add all of their attributes and mods
            addAttr(sheet.id, "str", c.attributes.str, null);
            addAttr(sheet.id, "int", c.attributes.int, null);
            addAttr(sheet.id, "wis", c.attributes.wis, null);
            addAttr(sheet.id, "dex", c.attributes.dex, null);
            addAttr(sheet.id, "con", c.attributes.con, null);
            addAttr(sheet.id, "chr", c.attributes.chr, null);
            
            addAttr(sheet.id, "str_mod", c.attribute_mods.str, null);
            addAttr(sheet.id, "int_mod", c.attribute_mods.int, null);
            addAttr(sheet.id, "wis_mod", c.attribute_mods.wis, null);
            addAttr(sheet.id, "dex_mod", c.attribute_mods.dex, null);
            addAttr(sheet.id, "con_mod", c.attribute_mods.con, null);
            addAttr(sheet.id, "chr_mod", c.attribute_mods.chr, null);
            
            // Add their Hit Points
            addAttr(sheet.id, "hp", c.hp, c.hp);
            
            // Set the guild and level
            addAttr(sheet.id, "class", c.guild, null);
            addAttr(sheet.id, "level", c.level, null);
            addAttr(sheet.id, "align", c.alignment, null);

            // Set the AC and attack throw
            addAttr(sheet.id, "ac", c.armour.ac_mod, null);
            addAttr(sheet.id, "attack_throw", c.attack_throw, null);
            addAttr(sheet.id, "attack_throw_vis", c.attack_throw, null);
            
            // Set the saves
            addAttr(sheet.id, "save_pp", c.saves.pp, null);
            addAttr(sheet.id, "save_pd", c.saves.pd, null);
            addAttr(sheet.id, "save_bb", c.saves.bb, null);
            addAttr(sheet.id, "save_sw", c.saves.sw, null);
            addAttr(sheet.id, "save_sp", c.saves.sp, null);
            
            /* Add our Repeating Sections */
            
            // for armour
            let armour_name = "repeating_equipment_" + generateRowID();
            addAttr(sheet.id, armour_name + "_equipment_name", c.armour.name, null);

            // for weapons
            let melee_name = "repeating_attacks_" + generateRowID();
            addAttr(sheet.id, melee_name + "_attack_name", c.melee.name, null);
            addAttr(sheet.id, melee_name + "_attack_throw_mod", c.melee.throw_mod, null);
            addAttr(sheet.id, melee_name + "_attack_dmg", c.melee.damage, null);
            
            // for spells
            if(c.spells) {
                for(spell of c.spells) {
                    let spell_name = "repeating_spells_" + generateRowID();
                    addAttr(sheet.id, spell_name + "_spell_name", spell.name, null);
                    addAttr(sheet.id, spell_name + "_spell_effect", Base64.decode(spell.description), null);
                    addAttr(sheet.id, spell_name + "_spell_range", spell.range, null);
                    addAttr(sheet.id, spell_name + "_spell_roll", spell.roll || 0, null);
                    if(spell.is_arcane) {
                        addAttr(sheet.id, spell_name + "_spell_school", "Arcane", null);
                        addAttr(sheet.id, spell_name + "_spell_level", spell.arcane, null);
                    }
                    if(spell.is_divine) {
                        addAttr(sheet.id, spell_name + "_spell_school", "Divine", null);
                        addAttr(sheet.id, spell_name + "_spell_level", spell.divine, null);
                    }
                }
            }
            
            // populate the default token
            let default_token = createObj("graphic", {
                "imgsrc": default_token_images["divine"], 
                represents: sheet.id, 
                "showname": true,
                "layer": "objects",
                "pageid": Campaign().get('playerpageid')
            });
            setDefaultTokenForCharacter(sheet, default_token); 

        }
    }
    
    if(msg.type == "api" && msg.content.indexOf("!acksdeleteall") !== -1) {
        let characters = findObjs({type: 'character'});

        for(let character of characters) {
            character.get('gmnotes', function(val) {
                if(val === "Generated by Atr0phyACKS") {
                    sendChat(msg.who, "Deleting generated NPC: " + character.get('name'));
                    character.remove();
                }
            });
        }
    }
});
