// priority: 10000

// make priority really really high to prevent affecting custom recipe
// Unification code was written by ZZZank in the High-Altitude Alchemy Discord Server, as such all credits for this file go to them.

ServerEvents.recipes((event) => {
    /** @type {string[]} */
    const materials = [
        "iron",
        "gold",
        "steel",
        "silver",
        "tin",
        "lead",
        "aluminum",
        "nickel",
        "bronze",
        "electrum",
        "constantan",
        "uranium",
		"copper",

        // gems are added here mostly for dust unification
        "quartz",
        "lapis",
        "diamond",
        "emerald",
        "obsidian"
    ];

    /** @type {string[]} */
    const types = [
        "ingot",
        "nugget",
        "plate",
        "dust",
        // "storage_block" // NotEnoughAnnoying
    ];

    /** @type {Special.Mod[]} */
    const modPriorities = [
        "thermal",
        "mekanism",
        "immersiveengineering",
        "malum"
    ];

    /**
     * @param {Internal.ItemStack} a 
     * @param {Internal.ItemStack} b 
     */
    function compareByModPriority(a, b) {
        const modA = a.mod;
        const modB = b.mod;
        for (let mod of modPriorities) {
            if (modA === mod) {
                // A matched before B, so A > B
                return 1;
            } else if (modB === mod) {
                return -1;
            }
        }
        return 0;
    }

    /**
     * @template T
     * @param {T[]} array 
     * @param {(a: T, b: T) => integer} comparator 
     */
    function maxOf(array, comparator) {
        let max = undefined;
        for (let element of array) {
            if (max === undefined || comparator(element, max) > 0) {
                max = element;
            }
        }
        return max;
    }

    for (let type of types) {
        for (let material of materials) {
            let tagString = `#forge:${type}s/${material}`;

            let stacks;
            // @ts-ignore
            let ingredient = Ingredient.of(tagString);
            if (ingredient) {
                stacks = ingredient.getStacks().toArray();
            }

            if (stacks && stacks.length > 1) {
                let replaceWith = maxOf(stacks, (a, b) => compareByModPriority(a, b));
                console.log(`replacing '${tagString}' with '${replaceWith.id}'`);
                event.replaceOutput("*", tagString, replaceWith);
            }
        }
    }
});