const CROPTOPIA_COOKING_POT = 'croptopia:cooking_pot'

const CROPTOPIA_COOKING_POT_OVERRIDES = {
    'croptopia:beetroot_salad': {
        result: 'croptopia:beetroot_salad',
        container: { item: 'minecraft:bowl' },
        ingredients: [
            { item: 'minecraft:beetroot' },
            { item: 'minecraft:beetroot' },
            { item: 'minecraft:beetroot' },
            { tag: 'forge:lettuce' },
            { tag: 'forge:cheeses' },
            { tag: 'forge:lemons' }
        ]
    },
    'croptopia:borscht': {
        result: 'croptopia:borscht',
        container: { item: 'minecraft:bowl' },
        ingredients: [
            { item: 'minecraft:beetroot' },
            { item: 'minecraft:carrot' },
            { item: 'minecraft:potato' },
            { tag: 'forge:onions' },
            { tag: 'forge:cabbage' },
            { tag: 'forge:garlic' }
        ]
    },
    'croptopia:chocolate_ice_cream': {
        result: 'croptopia:chocolate_ice_cream',
        container: { item: 'minecraft:bowl' },
        ingredients: [
            { tag: 'forge:chocolates' },
            { tag: 'forge:milk_bottles' },
            { item: 'minecraft:sugar' },
            { item: 'minecraft:egg' },
            { item: 'minecraft:snowball' }
        ]
    },
    'croptopia:pumpkin_soup': {
        result: 'croptopia:pumpkin_soup',
        container: { item: 'minecraft:bowl' },
        ingredients: [
            { item: 'farmersdelight:pumpkin_slice' },
            { tag: 'forge:garlic' },
            { item: 'croptopia:pepper' },
            { tag: 'forge:onions' },
            { tag: 'forge:salts' }
        ]
    },
    'croptopia:steamed_crab': {
        result: 'croptopia:steamed_crab',
        ingredients: [
            { tag: 'forge:crabs' }
        ]
    }
}

const CROPTOPIA_COOKING_CONTAINERS = {
    'croptopia:beetroot_salad': { item: 'minecraft:bowl' },
    'croptopia:borscht': { item: 'minecraft:bowl' },
    'croptopia:chicken_and_dumplings': { item: 'minecraft:bowl' },
    'croptopia:chicken_and_noodles': { item: 'minecraft:bowl' },
    'croptopia:chocolate_ice_cream': { item: 'minecraft:bowl' },
    'croptopia:mango_ice_cream': { item: 'minecraft:bowl' },
    'croptopia:pecan_ice_cream': { item: 'minecraft:bowl' },
    'croptopia:pumpkin_soup': { item: 'minecraft:bowl' },
    'croptopia:rum_raisin_ice_cream': { item: 'minecraft:bowl' },
    'croptopia:steamed_rice': { item: 'minecraft:bowl' },
    'croptopia:strawberry_ice_cream': { item: 'minecraft:bowl' },
    'croptopia:tofu_and_dumplings': { item: 'minecraft:bowl' },
    'croptopia:vanilla_ice_cream': { item: 'minecraft:bowl' }
}

function getCroptopiaCookingPotIngredients(json) {
    if (json.ingredients) return json.ingredients

    if (json.pattern && json.key) {
        const ingredients = []

        for (const row of json.pattern) {
            for (const symbol of row.split('')) {
                if (symbol === ' ') continue
                const ingredient = json.key[symbol]
                if (ingredient) ingredients.push(ingredient)
            }
        }

        return ingredients
    }

    return []
}

function getCroptopiaCookingContainer(resultItem) {
    if (resultItem.endsWith('_jam')) return { item: 'minecraft:glass_bottle' }
    return CROPTOPIA_COOKING_CONTAINERS[resultItem]
}

function isWaterIngredient(ingredient) {
    return ingredient?.item === 'minecraft:water_bucket'
        || ingredient?.item === 'minecraft:potion'
        || ingredient?.item === 'croptopia:water_bottle'
        || ingredient?.tag === 'forge:water_bottles'
        || ingredient?.tag === 'croptopiadelight:water_bottles'
}

function addCookingContainerIngredient(ingredients, container) {
    if (!container) return ingredients

    const item = container.item ?? container.id ?? container.containerId
    if (!item) return ingredients

    return ingredients.concat([{ item: item }])
}

function addCroptopiaCookingPotRecipe(event, recipeId, resultItem, ingredients, container, count) {
    const result = {
        item: resultItem,
        count: Math.max(1, count ?? 1)
    }
    const customRecipe = {
        type: 'farmersdelight:cooking',
        cookingtime: 200,
        experience: 0.35,
        ingredients: ingredients,
        recipe_book_tab: 'meals',
        result: result
    }

    if (container) customRecipe.container = container

    event.custom(customRecipe).id(`kubejs:fd_pot/${recipeId.replace(':', '_')}`)
    event.custom({
        type: 'create:mixing',
        heatRequirement: 'heated',
        ingredients: addCookingContainerIngredient(ingredients, container),
        results: [
            result
        ],
        processingTime: 200
    }).id(`kubejs:mixing/farmersdelight_pot/${recipeId.replace(':', '/')}`)
}

ServerEvents.recipes(event => {
    for (const recipeId in CROPTOPIA_COOKING_POT_OVERRIDES) {
        let override = CROPTOPIA_COOKING_POT_OVERRIDES[recipeId]

        event.remove({ id: recipeId })
        event.remove({ output: override.result, input: CROPTOPIA_COOKING_POT })
        addCroptopiaCookingPotRecipe(event, recipeId, override.result, override.ingredients, override.container, override.count)
    }

    event.forEachRecipe({ mod: 'croptopia' }, recipe => {
        const recipeId = recipe.getId().toString()
        if (CROPTOPIA_COOKING_POT_OVERRIDES[recipeId]) return

        const json = JSON.parse(recipe.json.toString())
        const resultItem = json.result?.item ?? json.result

        if (typeof resultItem !== 'string') return

        const originalIngredients = getCroptopiaCookingPotIngredients(json)
        const usesCookingPot = originalIngredients.some(ingredient => ingredient?.item === CROPTOPIA_COOKING_POT)
        if (!usesCookingPot) return

        const ingredients = originalIngredients
            .filter(ingredient => ingredient?.item !== CROPTOPIA_COOKING_POT)
            .filter(ingredient => !isWaterIngredient(ingredient))
        const container = getCroptopiaCookingContainer(resultItem)

        event.remove({ id: recipe.getId() })
        addCroptopiaCookingPotRecipe(event, recipeId, resultItem, ingredients, container, json.result?.count)
    })
})
