// Import Modules
import { DS4Actor } from "./actor/actor";
import { DS4Item } from "./item/item";
import { DS4ItemSheet } from "./item/item-sheet";
import { DS4 } from "./config";
import { DS4Check } from "./rolls/check";
import { DS4CharacterActorSheet } from "./actor/sheets/character-sheet";
import { DS4CreatureActorSheet } from "./actor/sheets/creature-sheet";
import { createCheckRoll } from "./rolls/check-factory";

Hooks.once("init", async function () {
    console.log(`DS4 | Initializing the DS4 Game System\n${DS4.ASCII}`);

    game.ds4 = {
        DS4Actor,
        DS4Item,
        DS4,
        createCheckRoll,
    };

    // Record configuration
    CONFIG.DS4 = DS4;

    // Define custom Entity classes
    CONFIG.Actor.entityClass = DS4Actor as typeof Actor;
    CONFIG.Item.entityClass = DS4Item as typeof Item;

    // Define localized type labels
    CONFIG.Actor.typeLabels = DS4.actorTypes;
    CONFIG.Item.typeLabels = DS4.itemTypes;

    // Configure Dice
    CONFIG.Dice.types = [Die, DS4Check];
    CONFIG.Dice.terms = {
        c: Coin,
        d: Die,
        s: DS4Check,
    };

    // Register sheet application classes
    Actors.unregisterSheet("core", ActorSheet);
    Actors.registerSheet("ds4", DS4CharacterActorSheet, { types: ["character"], makeDefault: true });
    Actors.registerSheet("ds4", DS4CreatureActorSheet, { types: ["creature"], makeDefault: true });
    Items.unregisterSheet("core", ItemSheet);
    Items.registerSheet("ds4", DS4ItemSheet, { makeDefault: true });

    registerHandlebarsPartials();
});

async function registerHandlebarsPartials() {
    const templatePaths = [
        "systems/ds4/templates/item/partials/sheet-header.hbs",
        "systems/ds4/templates/item/partials/description.hbs",
        "systems/ds4/templates/item/partials/details.hbs",
        "systems/ds4/templates/item/partials/effects.hbs",
        "systems/ds4/templates/item/partials/body.hbs",
        "systems/ds4/templates/actor/partials/items-overview.hbs",
        "systems/ds4/templates/actor/partials/talents-abilities-overview.hbs",
        "systems/ds4/templates/actor/partials/spells-overview.hbs",
        "systems/ds4/templates/actor/partials/overview-add-button.hbs",
        "systems/ds4/templates/actor/partials/overview-control-buttons.hbs",
        "systems/ds4/templates/actor/partials/attributes-traits.hbs",
        "systems/ds4/templates/actor/partials/combat-values.hbs",
        "systems/ds4/templates/actor/partials/profile.hbs",
        "systems/ds4/templates/actor/partials/character-progression.hbs",
        "systems/ds4/templates/actor/partials/special-creature-abilites-overview.hbs",
        "systems/ds4/templates/actor/partials/character-inventory.hbs",
        "systems/ds4/templates/actor/partials/creature-inventory.hbs",
    ];
    return loadTemplates(templatePaths);
}

/* -------------------------------------------- */
/*  Foundry VTT Setup                           */
/* -------------------------------------------- */

/**
 * This function runs after game data has been requested and loaded from the servers, so entities exist
 */
Hooks.once("setup", function () {
    // Localize CONFIG objects once up-front
    const toLocalize = [
        "attackTypes",
        "itemAvailabilities",
        "itemTypes",
        "armorTypes",
        "armorTypesAbbr",
        "armorMaterialTypes",
        "armorMaterialTypesAbbr",
        "armorMaterialTypes",
        "spellTypes",
        "spellCategories",
        "attributes",
        "traits",
        "combatValues",
        "characterBaseInfo",
        "characterProgression",
        "characterLanguage",
        "characterProfile",
        "characterCurrency",
        "creatureTypes",
        "creatureSizeCategories",
        "creatureBaseInfo",
        "temporalUnits",
        "temporalUnitsAbbr",
        "distanceUnits",
        "distanceUnitsAbbr",
        "chatVisibilities",
    ];

    // Exclude some from sorting where the default order matters
    const noSort = ["attributes", "traits", "combatValues", "creatureSizeCategories"];

    // Localize and sort CONFIG objects
    for (const o of toLocalize) {
        const localized = Object.entries(CONFIG.DS4[o]).map((e) => {
            return [e[0], game.i18n.localize(e[1] as string)];
        });
        if (!noSort.includes(o)) localized.sort((a, b) => a[1].localeCompare(b[1]));
        CONFIG.DS4[o] = localized.reduce((obj, e) => {
            obj[e[0]] = e[1];
            return obj;
        }, {});
    }
});