//Priority: 100
/**
  
  █▀▄▀█ █▀█ █▄░█ █░█ █▀▄▀█ █▀▀ █▄░█ ▀█▀ ▄▀█ █░░   █▀▀ ▀▄▀ █▀█ █▀▀ █▀█ █ █▀▀ █▄░█ █▀▀ █▀▀
  █░▀░█ █▄█ █░▀█ █▄█ █░▀░█ ██▄ █░▀█ ░█░ █▀█ █▄▄   ██▄ █░█ █▀▀ ██▄ █▀▄ █ ██▄ █░▀█ █▄▄ ██▄

  ☻/  * @file Global scripts
  /▌  * @copyright KnightDexx's Modded Minecraft World & ModernGamingWorld
  /▌  * Modified by @Cyn-SolveroftheAbsoluteGremlins on Discord
  /\

//Priority: 100
/**
 * Full AU + AllTheOres Master Unifier (with Dusts, Gears, Ingots, Nuggets, Plates, Rods, Raw Materials, Storage Blocks, and Wires)
 */

ServerEvents.recipes(event => {

    const recipeCounts = {
        dusts: 0,
        gears: 0,
        ingots: 0,
        nuggets: 0,
        plates: 0,
        rods: 0,
        raw_materials: 0,
        storage_blocks: 0,
        wires: 0
    }

    const validItem = (type, material) => !global.itemFromTag(type, material).isEmpty()
    const filterExisting = (tags, type) => tags.filter(material => validItem(type, material))

    const recipeExists = (outputItem) => {
        let exists = false
        event.recipeStream({}).forEach(r => {
            if (r.json?.result) {
                if (Array.isArray(r.json.result)) {
                    r.json.result.forEach(item => {
                        if (outputItem.equalsIgnoringCount(Item.of(item))) exists = true
                    })
                } else {
                    if (outputItem.equalsIgnoringCount(Item.of(r.json.result))) exists = true
                }
            }
        })
        return exists
    }

    //==============================
    // --- DUSTS (Occultism Crushing)
    //==============================
    if (global.loaded.Occult_Loaded) {
        filterExisting(global.auTags.dusts, 'dusts').forEach(material => {
            const dust = global.itemFromTag('dusts', material)
            const ingotTag = Ingredient.of(`#forge:ingots/${material}`)
            const oreTag   = Ingredient.of(`#forge:ores/${material}`)
            const rawTag   = Ingredient.of(`#forge:raw_materials/${material}`)

            let crush = { ingot: false, ore: false, raw: false }

            event.forEachRecipe({ type: "occultism:crushing" }, r => {
                const resItem = Item.of(r.json.result.item, r.json.result.count ?? 1)
                if (dust.equalsIgnoringCount(resItem)) {
                    const input = Ingredient.of(r.json.ingredient)
                    if (ingotTag.test(input)) crush.ingot = true
                    if (oreTag.test(input))   crush.ore = true
                    if (rawTag.test(input))   crush.raw = true
                }
            })

            if (!ingotTag.isEmpty() && !crush.ingot && !recipeExists(dust.withCount(1))) {
                event.custom({
                    type: "occultism:crushing",
                    ingredient: ingotTag.toJson(),
                    result: dust.withCount(1).toJson(),
                    crushing_time: 200,
                    ignore_crushing_multiplier: true
                }).id(`kubejs:occultism/crushing/${material}_dust_from_ingot`)
                recipeCounts.dusts++
            }

            if (!rawTag.isEmpty() && !crush.raw && !recipeExists(dust.withCount(2))) {
                event.custom({
                    type: "occultism:crushing",
                    ingredient: rawTag.toJson(),
                    result: dust.withCount(2).toJson(),
                    crushing_time: 200,
                    ignore_crushing_multiplier: false
                }).id(`kubejs:occultism/crushing/${material}_dust_from_raw`)
                recipeCounts.dusts++
            }

            if (!oreTag.isEmpty() && !crush.ore && !recipeExists(dust.withCount(2))) {
                event.custom({
                    type: "occultism:crushing",
                    ingredient: oreTag.toJson(),
                    result: dust.withCount(2).toJson(),
                    crushing_time: 300,
                    ignore_crushing_multiplier: false
                }).id(`kubejs:occultism/crushing/${material}_dust_from_ore`)
                recipeCounts.dusts++
            }
        })
    }

    //==============================
    // --- GEARS (IE / Thermal)
    //==============================
    if (global.loaded.IE_Loaded || global.loaded.Thermal_Loaded) {
        filterExisting(global.auTags.gears, 'gears').forEach(material => {
            const gear = global.itemFromTag('gears', material)
            const ingotTag = Ingredient.of(`#forge:ingots/${material}`)
            if (ingotTag.isEmpty()) return

            // Immersive Engineering Gear Press
            if (global.loaded.IE_Loaded && !recipeExists(gear)) {
                event.custom({
                    type: "immersiveengineering:metal_press",
                    mold: "immersiveengineering:mold_gear",
                    input: ingotTag.withCount(4).toJson(),
                    result: gear.toJson(),
                    energy: 2400
                }).id(`kubejs:immersiveengineering/gear_${material}`)
                recipeCounts.gears++
            }

            // Thermal Press Gear
            if (global.loaded.Thermal_Loaded && !recipeExists(gear)) {
                event.custom({
                    type: "thermal:press",
                    ingredients: [
                        ingotTag.withCount(4).toJson(),
                        { item: "thermal:press_gear_die" }
                    ],
                    result: [{ item: gear.toJson(), count: 1 }]
                }).id(`kubejs:thermal/gear_${material}`)
                recipeCounts.gears++
            }
        })
    }

    //==============================
    // --- WIRES (IE / Create Additions)
    //==============================
    if (global.auTags.wires.length > 0) {
        filterExisting(global.auTags.wires, 'wires').forEach(material => {
            const wire = global.itemFromTag('wires', material)
            if (wire.isEmpty() || recipeExists(wire)) return

            // --- Create Additions rolling (plate → wire)
            if (global.loaded.CreateAdd_Loaded) {
                const plate = global.itemFromTag('plates', material)
                if (!plate.isEmpty() && !recipeExists(wire)) {
                    event.custom({
                        type: 'createaddition:rolling',
                        input: plate.toJson(),
                        result: wire.withCount(2).toJson()
                    }).id(`kubejs:createaddition/rolling/${material}_plate`)
                }
            }

            // --- IE metal press (ingot → wire)
            if (global.loaded.IE_Loaded) {
                const ingot = global.itemFromTag('ingots', material)
                if (!ingot.isEmpty() && !recipeExists(wire)) {
                    event.custom({
                        type: 'immersiveengineering:metal_press',
                        mold: 'immersiveengineering:mold_wire',
                        input: ingot.toJson(),
                        result: {
                            count: 2,
                            base_ingredient: wire.toJson()
                        },
                        energy: 2400
                    }).id(`kubejs:immersiveengineering/metalpress/wire_${material}`)
                }
            }
        })
    }

    //==============================
    // --- OTHER CATEGORIES (ingots, nuggets, plates, rods, raw materials, storage blocks)
    //==============================
    const categories = [
        { key: 'ingots', type: 'ingots', inputTags: ['ores', 'raw_materials'], method: 'smelting' },
        { key: 'nuggets', type: 'nuggets', inputTags: ['ingots'], method: 'shapeless', count: 9 },
        { key: 'plates', type: 'plates', inputTags: ['ingots'], method: 'press' },
        { key: 'rods', type: 'rods', inputTags: ['ingots'], method: 'shapeless', count: 2 },
        { key: 'raw_materials', type: 'raw_materials', inputTags: ['ores'], method: 'smelting' },
        { key: 'storage_blocks', type: 'storage_blocks', inputTags: ['ingots'], method: 'block' }
    ]

    categories.forEach(cat => {
        filterExisting(global.auTags[cat.key], cat.type).forEach(material => {
            const item = global.itemFromTag(cat.type, material)
            if (!item || recipeExists(item)) return

            switch (cat.method) {
                case 'smelting':
                    cat.inputTags.forEach(input => {
                        const tag = Ingredient.of(`#forge:${input}/${material}`)
                        if (!tag.isEmpty()) {
                            event.smelting(item, tag).id(`kubejs:smelting/${cat.key}_${material}`)
                            recipeCounts[cat.key]++
                        }
                    })
                    break

                case 'shapeless':
                    const inputItem = global.itemFromTag(cat.inputTags[0], material)
                    if (!inputItem.isEmpty()) {
                        event.shapeless(item.withCount(cat.count), [inputItem]).id(`kubejs:shapeless/${cat.key}_${material}`)
                        recipeCounts[cat.key]++
                    }
                    break

                case 'press':
                    if (global.loaded.IE_Loaded) {
                        const ingotTag = Ingredient.of(`#forge:ingots/${material}`)
                        if (!ingotTag.isEmpty()) {
                            event.custom({
                                type: "immersiveengineering:metal_press",
                                mold: "immersiveengineering:mold_plate",
                                input: ingotTag.toJson(),
                                result: item.toJson(),
                                energy: 2400
                            }).id(`kubejs:immersiveengineering/plate_${material}`)
                            recipeCounts.plates++
                        }
                    }
                    break

                case 'block':
                    const ingotTag = global.itemFromTag('ingots', material)
                    if (!ingotTag.isEmpty()) {
                        event.shapeless(item, [ingotTag.withCount(9)]).id(`kubejs:shapeless/block_from_ingot_${material}`)
                        event.shaped(ingotTag.withCount(9), ["###","###","###"], { "#": item }).id(`kubejs:shaped/ingot_from_block_${material}`)
                        recipeCounts.storage_blocks++
                    }
                    break
            }
        })
    })

    const moreMekList = [
        'desh',
        'ostrum',
        'calorite',
        'aluminum',
        'nickel',
        'platinum',
        'zinc',
        'iridium'
    ]
    const mekList = [
        'osmium',
        'tin',
        'uranium'
    ]
    const altMekList = [
        'steel',
        'bronze'
    ]
    const forestryBlock = [
        'tin',
        'bronze'
    ]
    const immHalf = [
        'steel',
        'electrum',
        'silver',
        'lead'
    ]
    const immOther = [
        'electrum',
        'silver',
        'lead'
    ]
    const recipeRemoval = [
        'ironcoals:charcoal_chunk',
        'ironcoals:charcoal',
        'actuallyaddtions:charcoal_to_tiny',
        'actuallyadditions:tiny_to_charcoal',
        'ironcoals:base_coal_chunk',
        'ironcoals:coal',
        'actuallyadditions:coal_to_tiny',
        'actuallyadditions:tiny_to_coal',
        'inventorypets:nugget_coal_alt',
        'inventorypets:nugget_diamond_alt',
        'thermal:storage/bronze_ingot_from_nuggets',
        'forestry:resource_storage_bronze',
        'thermal:storage/bronze_block',
        'eidolon:silver_block',
        'eidolon:lead_ingot',
        'mekanism:processing/lead/storage_blocks/from_ingots',
        'create:crafting/materials/copper_nugget',
        'opolisutilities:copper_ingot_from_nuggets',
        'cyclic:netherite_ingot',
        'createdeco:netherite_nugget_from_netherite_ingot',
        'forestry:ingot_bronze_alloying',
        `strainers:cobbled_deepslate`,
        `strainers:cobblestone`,
        `exdeorum:cobblestone`,
        `exdeorum:cobbled_deepslate`,
        'immersiveengineering:crafting/coal_coke_to_coke',
        'immersiveengineering:crafting/coke_to_coal_coke',
        'createaddition:compat/immersiveengineering/crushing/coke_block',
        'createaddition:compat/immersiveengineering/crushing/coal_coke',
        'moremekanismprocessing:processing/draconium/dust/from_ingot',
        'moremekanismprocessing:processing/draconium/dust/from_ore',
        'moremekanismprocessing:processing/draconium/dust/from_dirty_dust',
        'moremekanismprocessing:processing/dracnoium/ingot/from_dust_smelting',
        'enderio:smelting/moremekanismprocessing/processing/draconium/ingot/from_dust_smelting',
        'thermal:furnace_390750151',
        'moremekanismprocessing:processing/draconium/ingot/from_dust_blasting',
        'moremekanismprocessing:processing/draconium/ingot/from_dust_smelting',
        'moremekanismprocessing:processing/draconium/ingot/from_nugget',
        'moremekanismprocessing:processing/draconium/nugget/from_ingot',
        'bygonenether:pressing/netherite_scrap_ingot',
        'forestry:gear_tin',
        'enderio:iron_gear',
        'thermal:parts/copper_gear',
        'inventorypets:nugget_emerald_alt',
        'inventorypets:nugget_obsidian_alt',
        'inventorypets:nugget_ender_alt',
        'forbidden_arcanus:ender_pearl',
        'forbidden_arcanus:ender_pearl_fragment',
        'opolisutilities:ender_pearl_fragments_from_ender_pearl',
        'opolisutilities:ender_pearl_from_ender_pearl_fragments',
        'compressedcreativity:mixing/memory_essence'
    ]
    const xp = [
        'create_enchantment_industry:experience', 
        'cyclic:xpjuice', 
        'enderio:xp_juice', 
        'reliquary:xp_juice_still', 
        'sophisticatedcore:xp_still',
        'industrialforegoing:essence',
        'pneumaticcraft:memory_essence',
        'cofh_core:experience'
    ]
    moreMekList.forEach((material => {
        event.remove({id: `moremekanismprocessing:processing/${material}/nugget/from_ingot`})
        event.remove({id: `moremekanismprocessing:processing/${material}/ingot/from_nugget`})
    }))
    mekList.forEach((material => {
        event.remove({id: `mekanism:processing/${material}/nugget/from_ingot`})
        event.remove({id: `mekanism:processing/${material}/ingot/from_nuggets`})
        event.remove({id: `mekanism:processing/${material}/ingot/from_block`})
        event.remove({id: `mekanism:processing/${material}/storage_blocks/from_ingots`})
    }))
    altMekList.forEach((material => {
        event.remove({id: `mekanism:nuggets/${material}`})
        event.remove({id: `mekanism:storage_blocks/${material}`})
        event.remove({id: `mekanism:processing/${material}/ingot/from_block`})
        event.remove({id: `mekanism:processing/${material}/ingot/from_nuggets`})
    }))
    forestryBlock.forEach((material => {
        event.remove({id: `forestry:resource_storage_${material}`})
    }))
    immHalf.forEach((material => {
        event.remove({id: `immersiveengineering:crafting/nugget_${material}_to_ingot_${material}`})
        event.remove({id: `immersiveengineering:crafting/ingot_${material}_to_storage_${material}`})
    }))
    immOther.forEach((material => {
        event.remove({id: `immersiveengineering:crafting/ingot_${material}_to_nugget_${material}`})
        event.remove({id: `immersiveengineering:crafting/storage_${material}_to_ingot_${material}`})
    }))
    xp.forEach((liq => {
        event.replaceInput(
        {input: liq},
        liq,
        '#forge:experience'
    )
    }))
    recipeRemoval.forEach((rec => {
        event.remove({id: rec})
    }))

    event.replaceInput({input: 'immersiveengineering:coal_coke'},
        'immersiveengineering:coal_coke',
        '#forge:coal_coke'
    )
    event.replaceOutput({output: 'immersiveengineering:coal_coke'},
        'immersiveengineering:coal_coke',
        '#forge:coal_coke'
    )
    event.replaceInput({input: 'opolisutilities:ender_pearl_fragment'},
        'opolisutilities:ender_pearl_fragment',
        '#forge:nuggets/ender_pearl'
    )
    event.replaceOutput({output: 'opolisutilities:ender_pearl_fragment'},
        'opolisutilities:ender_pearl_fragment',
        'inventorypets:nugget_ender'
    )
    event.replaceInput({input: 'forbidden_arcanus:ender_pearl_fragment'},
        'forbidden_arcanus:ender_pearl_fragment',
        '#forge:nuggets/ender_pearl'
    )
    event.replaceOutput({output: 'forbidden_arcanus:ender_pearl_fragment'},
        'forbidden_arcanus:ender_pearl_fragment',
        'inventorypets:nugget_ender'
    )
    event.replaceInput({input: 'inventorypets:nugget_ender'},
        'inventorypets:nugget_ender',
        '#forge:nuggets/ender_pearl'
    )
    pebble.forEach((peb) => {
        if (peb == 'stone' || peb == 'deepslate') {
        event.replaceInput(
            {input: `strainers:${peb}_pebble`},
            `strainers:${peb}_pebble`,
            `havenpebbles:${peb}_pebble`
        )
        event.replaceOutput(
            {output: `strainers:${peb}_pebble`},
            `strainers:${peb}_pebble`,
            `havenpebbles:${peb}_pebble`
        )
        event.replaceInput(
        {input: `exdeorum:${peb}_pebble`},
        `exdeorum:${peb}_pebble`,
        `havenpebbles:${peb}_pebble`
        )
        } else {
        event.replaceInput(
            {input: `exdeorum:${peb}_pebble`},
            `exdeorum:${peb}_pebble`,
            `havenpebbles:${peb}_pebble`
        )
        event.remove(`exdeorum:${peb}`)
        }
    })
    event.custom({
        "type": "mekanism:crushing",
        "input": {
        "ingredient": {
            "tag":"forge:ingots/draconium"
        }
        },
        "output": {
        "item": "draconicevolution:draconium_dust"
        }
    }).id('kubejs:processing/draconium/dust/from_ingot')
    event.custom({
        "type":"mekanism:enriching",
        "input": {
        "ingredient": {
            "tag":"forge:ores/draconium"
        }
        },
        "output": {
        "count": 2,
        "item": "draconicevolution:draconium_dust"
        }
    }).id('kubejs:processing/draconium/dust/from_ore')
    event.custom({
        "type":"mekanism:enriching",
        "input": {
        "ingredient": {
            "item":"moremekanismprocessing:dirty_dust_draconium"
        }
        },
        "output": {
        "item": "draconicevolution:draconium_dust"
        }
    }).id('kubejs:processing/draconium/dust/from_dirty_dust')
    event.blasting({
        "cookingtime": 100,
        "experience": 0.3,
        "ingredient": {
        "tag": "forge:dusts/draconium"
        },
        "result": {
        "item": "draconicevolution:draconium_ingot"
        }
    }).id('kubejs:processing/draconium/ingot/from_dust_blasting')

    if (global.devLogging) {
        console.log("Reload-Safe AU + AllTheOres Unifier applied:", recipeCounts)
    }

})
