DiseaseNpcLogic = {}

local function nz(v, d)
    if v == nil then
        return d
    end
    return v
end

function DiseaseNpcLogic:advanceFieldForNewDay(core, farmlandId, entry, field, defs, tuning)
    if core == nil or entry == nil or field == nil then
        return 0
    end

    local oldState = nz(entry.state, 0)
    local promoted = 0
    if oldState > 0 then
        local npcStageCap = nz(tuning.npcFieldsMaxDiseaseStage, 2)
        local newState = math.min(oldState + 1, npcStageCap)
        local threatId = defs and defs.getThreatId and defs:getThreatId(entry.threatKey) or 0

        if newState > oldState and DiseaseGrid ~= nil then
            promoted = DiseaseGrid:promoteThreatOnField(field, newState, threatId) or 0
            entry.state = newState
            entry.neglectDays = nz(entry.neglectDays, 0) + 1
            core:beginThreatStage(entry, newState, field)
            core:debugLog("daily stage rise npc: farmland=%s oldState=%d newState=%d",
                tostring(farmlandId), oldState, nz(entry.state, 0))
        end
    end

    local npcStageCap = nz(tuning.npcFieldsMaxDiseaseStage, 2)
    if nz(entry.state, 0) <= npcStageCap then
        return promoted
    end

    local threatId = defs and defs.getThreatId and defs:getThreatId(entry.threatKey) or 0
    local capped = DiseaseGrid ~= nil and DiseaseGrid:capThreatOnField(field, npcStageCap, threatId) or 0
    local healed = 0
    if tuning.npcAutoHealBeforeStage3 ~= false and DiseaseGrid ~= nil then
        local healSpotsMin = math.max(1, nz(tuning.npcAutoHealSpotsMin, 2))
        local healSpotsMax = math.max(healSpotsMin, nz(tuning.npcAutoHealSpotsMax, 4))
        healed = DiseaseGrid:healRandomSpots(
            field,
            math.random(healSpotsMin, healSpotsMax),
            nz(tuning.npcAutoHealRadiusMin, 5.0),
            nz(tuning.npcAutoHealRadiusMax, 10.0)
        )
    end

    local summary = DiseaseGrid ~= nil and DiseaseGrid:getFieldSummary(field) or nil
    entry.state = math.min(npcStageCap, math.max(0, tonumber(summary and summary.maxSeverity or 0) or 0))
    entry.damageReady = false
    if entry.state <= 0 then
        core:clearThreat(entry)
    else
        core:beginThreatStage(entry, entry.state, field)
    end

    core:debugLog("npc pseudo-heal: farmland=%s oldState=%d cap=%d capped=%d healed=%d finalState=%d autoHeal=%s",
        tostring(farmlandId), oldState, npcStageCap, capped or 0, healed or 0, nz(entry.state, 0),
        tostring(tuning.npcAutoHealBeforeStage3 ~= false))

    return promoted
end

function DiseaseNpcLogic:advanceFieldTimers(core, farmlandId, entry, field, defs, tuning, deltaHours, currentHoursInDay, _, currentDayToken)
    if core == nil or entry == nil or field == nil or deltaHours == nil or deltaHours <= 0 or DiseaseGrid == nil then
        return
    end

    entry.stageHours = nz(entry.stageHours, 0) + deltaHours
end
