CannibalismUtils = require("Cannibalism_Utils")

local function DoesFoodContainHumanOrZombieMeat(item)
    local humanMeatCount = 0
    local zombieMeatCount = 0

    if item:haveExtraItems() then
        for i = 0, item:getExtraItems():size() - 1 do
            local extraItem = item:getExtraItems():get(i)
            if extraItem == "Base.HumanMeat" then
                humanMeatCount = humanMeatCount + 1
            elseif extraItem == "Base.ZombieMeat" then
                zombieMeatCount = zombieMeatCount + 1
            end
        end
    end

    -- Return if contains any meat, and which types
    local containsMeat = humanMeatCount > 0 or zombieMeatCount > 0
    return containsMeat, humanMeatCount, zombieMeatCount
end

local function ApplyDebuffs(item, character, humanMeatCount, zombieMeatCount)
    if isServer() then return end

    local vars = SandboxVars.Cannibalism
    local currentInsanityPoints = CannibalismUtils.getPlayerInsanityPoints(character)
    local newInsanityPoints = currentInsanityPoints

    -- Apply debuffs based on the amount of each meat type
    local isCooked = item:isCooked()
    local evolvedRecipeMultiplier = vars.EvolvedRecipeInsanityPointsMultiplier

    -- Apply zombie meat debuffs
    if zombieMeatCount > 0 then
        local pointsPerMeat = isCooked and vars.CookedZombieMeatInsanityPointsGain or
            vars.RawZombieMeatInsanityPointsGain
        newInsanityPoints = newInsanityPoints + ((pointsPerMeat * evolvedRecipeMultiplier) * zombieMeatCount)
    end

    -- Apply human meat debuffs
    if humanMeatCount > 0 then
        local pointsPerMeat = isCooked and vars.CookedHumanMeatInsanityPointsGain or vars.RawHumanMeatInsanityPointsGain
        newInsanityPoints = newInsanityPoints + ((pointsPerMeat * evolvedRecipeMultiplier) * humanMeatCount)
    end

    -- Apply the changes
    character:getModData().Cannibalism_InsanityPoints = newInsanityPoints
    local insanityStage = CannibalismUtils.getPlayerInsanityStage(character)
    MF.getMoodle("insane", character:getPlayerNum()):setValue(insanityStage)

    character:getModData().Cannibalism_hasCannibalisedToday = true
end

local _ISEatFoodAction_stop = ISEatFoodAction.stop
function ISEatFoodAction:stop()
    --Call the original function
    _ISEatFoodAction_stop(self)

    if self.item then
        local containsMeat, humanCount, zombieCount = DoesFoodContainHumanOrZombieMeat(self.item)
        if containsMeat then
            ApplyDebuffs(self.item, self.character, humanCount, zombieCount)
        end
    end
end

local _ISEatFoodAction_perform = ISEatFoodAction.perform
function ISEatFoodAction:perform()
    if self.item then
        local containsMeat, humanCount, zombieCount = DoesFoodContainHumanOrZombieMeat(self.item)
        if containsMeat then
            ApplyDebuffs(self.item, self.character, humanCount, zombieCount)
        end
    end

    --Call the original function
    _ISEatFoodAction_perform(self)
end
