require "MF_ISMoodle"
local CannibalismUtils = require("Cannibalism_Utils")

MF.createMoodle("insane");

local function onChopCorpse(playerNum, corpse, knife)
    local character = getSpecificPlayer(playerNum)
    if luautils.walkAdj(character, corpse:getSquare()) then
        ISInventoryPaneContextMenu.transferIfNeeded(character, knife)
        ISTimedActionQueue.add(ISEquipWeaponAction:new(character, knife, 10, true, true))
        ISTimedActionQueue.add(Cannibalism_ChopCorpse:new(character, corpse, knife))
    end
end

local _ISWorldObjectContextMenu_createMenu = ISWorldObjectContextMenu.createMenu
ISWorldObjectContextMenu.createMenu = function(player, worldobjects, x, y, test)
    local result = _ISWorldObjectContextMenu_createMenu(player, worldobjects, x, y, test)
    local context = getPlayerContextMenu(player)

    ---@type IsoDeadBody
    if body then
        local knife = CannibalismUtils.getKnife(player)
        local option = context:addOption(getText("ContextMenu_ChopUpCorpse"), player, onChopCorpse, body,
            knife)
        local description = getText("ContextMenu_ChopUpCorpse_Tooltip")
        if not knife then
            option.notAvailable = true
            description = "<RED>" .. getText("ContextMenu_ChopUpCorpse_ToolRequired")
        end
        local tooltip = ISToolTip:new();
        tooltip:initialise();
        tooltip:setVisible(false);
        tooltip.description = description
        option.toolTip = tooltip
    end
    return result
end

local function onCreatePlayer()
    local character = getPlayer()
    local insanityStage = CannibalismUtils.getPlayerInsanityStage(character)
    MF.getMoodle("insane", character:getPlayerNum()):setValue(insanityStage) --float
end
Events.OnCreatePlayer.Add(onCreatePlayer)

local function everyOneMinute()
    local character = getPlayer()
    local insanityStage = CannibalismUtils.getPlayerInsanityStage(character)
    if insanityStage == 0.5 then return end

    local sandboxVars = SandboxVars.Cannibalism
    local presetVars = CannibalismUtils.getInsanitySettings()
    local emitter = character:getEmitter()

    CannibalismUtils.lastSoundAttemptTimestamp = CannibalismUtils.lastSoundAttemptTimestamp or getTimestamp()

    if insanityStage == 0.4 then --Stage one
        if (getTimestamp() - CannibalismUtils.lastSoundAttemptTimestamp) / 60 >= presetVars.StageOneSoundFrequency then
            local rng = ZombRand(0, 101)
            if rng <= presetVars.StageOneSoundChance then
                local sound = CannibalismUtils.getRandomSound(sandboxVars.StageOneSounds)
                if sound then
                    emitter:playSoundImpl(sound, nil)
                end
                CannibalismUtils.lastSoundAttemptTimestamp = getTimestamp()
            end
        end
    elseif insanityStage == 0.3 then --Stage two
        if (getTimestamp() - CannibalismUtils.lastSoundAttemptTimestamp) / 60 >= presetVars.StageTwoSoundFrequency then
            local rng = ZombRand(0, 101)
            if rng <= presetVars.StageTwoSoundChance then
                local sound = CannibalismUtils.getRandomSound(sandboxVars.StageTwoSounds)
                if sound then
                    emitter:playSoundImpl(sound, nil)
                end
                CannibalismUtils.lastSoundAttemptTimestamp = getTimestamp()
            end
        end
    elseif insanityStage == 0.2 then --Stage three
        if (getTimestamp() - CannibalismUtils.lastSoundAttemptTimestamp) / 60 >= presetVars.StageThreeSoundFrequency then
            local rng = ZombRand(0, 101)
            if rng <= presetVars.StageThreeSoundChance then
                local sound = CannibalismUtils.getRandomSound(sandboxVars.StageThreeSounds)
                if sound then
                    emitter:playSoundImpl(sound, nil)
                end
                CannibalismUtils.lastSoundAttemptTimestamp = getTimestamp()
            end
        end
    end
end
Events.EveryOneMinute.Add(everyOneMinute)

local function everyDays()
    local character = getPlayer()
    local hasCannibalisedToday = character:getModData().Cannibalism_hasCannibalisedToday or false
    local sandboxVars = SandboxVars.Cannibalism
    if not hasCannibalisedToday then
        local currentPoints = CannibalismUtils.getPlayerInsanityPoints(character)
        if currentPoints > 0 then
            local newPoints = currentPoints - sandboxVars.PointsDecrementDays
            if newPoints < 0 then newPoints = 0 end

            character:getModData().Cannibalism_InsanityPoints = newPoints

            local insanityStage = CannibalismUtils.getPlayerInsanityStage(character)
            MF.getMoodle("insane", character:getPlayerNum()):setValue(insanityStage) --float
        end
    end
    character:getModData().Cannibalism_hasCannibalisedToday = false
end
Events.EveryDays.Add(everyDays)
