//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 => {

    /* ============================
       COUNTERS
    ============================ */

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

    /* ============================
       SAFETY HELPERS
    ============================ */

    const validItem = (type, material) => {
        const item = global.itemFromTag(type, material)
        return item && !item.isEmpty()
    }

    const filterExisting = (tags, type) =>
        tags.filter(material => validItem(type, material))

    const recipeExists = (outputItem) => {
        if (!outputItem || outputItem.isEmpty()) return false
        let exists = false

        event.recipeStream({}).forEach(r => {
            const res = r.json?.result
            if (!res) return

            if (Array.isArray(res)) {
                res.forEach(e => {
                    if (!e) return
                    const item = Item.of(e)
                    if (item && !item.isEmpty() && outputItem.equalsIgnoringCount(item)) {
                        exists = true
                    }
                })
            } else {
                const item = Item.of(res)
                if (item && !item.isEmpty() && outputItem.equalsIgnoringCount(item)) {
                    exists = true
                }
            }
        })

        return exists
    }

    /* ============================
       DUSTS (Occultism)
    ============================ */

    if (global.loaded.Occult_Loaded) {
        filterExisting(global.auTags.dusts, 'dusts').forEach(material => {
            const dust = global.itemFromTag('dusts', material)
            if (!dust || dust.isEmpty()) return

            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 => {
                if (!r.json?.result) return
                const resItem = Item.of(r.json.result.item, r.json.result.count ?? 1)
                if (!resItem || resItem.isEmpty()) return

                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
                })
                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
                })
                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
                })
                recipeCounts.dusts++
            }
        })
    }

    /* ============================
       GEARS
    ============================ */

    if (global.loaded.IE_Loaded || global.loaded.Thermal_Loaded) {
        filterExisting(global.auTags.gears, 'gears').forEach(material => {
            const gear = global.itemFromTag('gears', material)
            if (!gear || gear.isEmpty()) return

            const ingotTag = Ingredient.of(`#forge:ingots/${material}`)
            if (ingotTag.isEmpty()) return

            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
                })
                recipeCounts.gears++
            }

            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.id, count: 1 }]
                })
                recipeCounts.gears++
            }
        })
    }

    /* ============================
       WIRES
    ============================ */

    filterExisting(global.auTags.wires, 'wires').forEach(material => {
        const wire = global.itemFromTag('wires', material)
        if (!wire || wire.isEmpty() || recipeExists(wire)) return

        if (global.loaded.CreateAdd_Loaded) {
            const plate = global.itemFromTag('plates', material)
            if (plate && !plate.isEmpty()) {
                event.custom({
                    type: 'createaddition:rolling',
                    input: plate.toJson(),
                    result: wire.withCount(2).toJson()
                })
            }
        }

        if (global.loaded.IE_Loaded) {
            const ingot = global.itemFromTag('ingots', material)
            if (ingot && !ingot.isEmpty()) {
                event.custom({
                    type: 'immersiveengineering:metal_press',
                    mold: 'immersiveengineering:mold_wire',
                    input: ingot.toJson(),
                    result: {
                        count: 2,
                        base_ingredient: wire.toJson()
                    },
                    energy: 2400
                })
            }
        }
    })

    /* ============================
       SKY PACK – PEBBLE UNIFICATION
    ============================ */

    const pebble = [
        'stone',
        'deepslate',
        'andesite',
        'diorite',
        'granite',
        'calcite',
        'tuff',
        'basalt'
    ]

    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({ id: `exdeorum:${peb}` })
        }
    })

    /* ============================
       MISC CLEANUP / FIXES
    ============================ */

    event.replaceInput(
        { input: 'create:brass_sheet' },
        'create:brass_sheet',
        '#forge:plates/brass'
    )

    event.shapeless(
        Item.of('minecraft:flint', 9),
        ['#forge:storage_blocks/flint']
    )

    event.remove({ id: 'supplementaries:flint_block' })
    event.remove({ mod: 'allthecompatibility', type: 'create:crushing' })
    event.remove({ id: 'ad_astra:steel_rod' })
    event.remove({ id: 'ad_astra:iron_rod' })
    event.remove({ id: 'buildersaddition:iron_rod' })
    event.remove({ id: 'bigreactors:crafting/raw_yellorium_component_to_storage' })
    event.remove({ id: 'immersiveengineering:crafting/raw_uranium_to_raw_block_uranium' })
    event.remove({ id: 'eidolon:raw_silver_block' })
    event.remove({ id: 'alltheores:raw_osmium_block' })
    event.remove({ id: 'eidolon:raw_lead_block' })
    event.remove({ id: 'forestry:raw_tin_block' })
    event.remove({ id: 'thermal:storage/raw_tin_block' })
    event.remove({ id: 'thermal:enderium_dust_2' })
    event.remove({ id: 'alexcaves:uranium_from_shard' })
    event.remove({ id: 'alexcaves:uranium_shard_from_uranium' })

    if (global.devLogging) {
        console.log("AU + SkyPack Unifier applied safely:", recipeCounts)
    }
})
