-- @author DoomTero 2026
-- @copyright 2026 DoomTero - ZomboRut original work. ref:d960d736
-- @license Proprietary. Not licensed for reuse, redistribution or derivative works without written permission from DoomTero. Ask - permission is obtainable. See ZomboRut/LICENSE.txt

local ZomboRut = require("ZomboRut/ZomboRut")
local BodyCount = require("ZomboRut/ZomboRutBodyCount")

local function initData()
	local player = getPlayer();
	if player == nil then return end
	local md = player:getModData(); if md == nil then return end
	md.timedHandler = md.timedHandler or {};
	md.timedHandler.hoursSinceLastDefeat = md.timedHandler.hoursSinceLastDefeat or 0;
	BodyCount.Check(player, true);
end

local function limitTimer(player)
	BodyCount.PruneBodyCount(player)
	BodyCount.Check(player);
end

local function rollTraumaHours()
	local tl = SandboxVars and SandboxVars.ZomboRut and SandboxVars.ZomboRut.tLength
	if tl == 1 then return 0   end
	if tl == 2 then return 3   + ZombRand(4)  end
	if tl == 3 then return 6   + ZombRand(7)  end
	if tl == 4 then return 24  + ZombRand(25) end
	if tl == 5 then return 72  + ZombRand(49) end
	if tl == 6 then return 120 + ZombRand(49) end
	return 6 + ZombRand(7)
end

local function traumatizeTimer()
	local player = getPlayer();
	if player == nil then
		return;
	end

	initData();
	limitTimer(player);

	local th = player:getModData().timedHandler
	if type(th) ~= "table" then return end

	if not (ZR_Trait and ZR_Trait.has and ZR_Trait.has(player, "Traumatized")) then
		th.hoursSinceLastDefeat = 0
		th.traumaHours = nil
		return
	end

	if type(th.traumaHours) ~= "number" then
		th.traumaHours = rollTraumaHours()
		th.hoursSinceLastDefeat = 0
	end
	th.hoursSinceLastDefeat = (th.hoursSinceLastDefeat or 0) + 1

	if th.hoursSinceLastDefeat >= th.traumaHours then
		HaloTextHelper.addTextWithArrow(player, getText("UI_ZR_TraumaFading"), false, HaloTextHelper.getColorGreen());
		player:getCharacterTraits():remove(ZR_Trait.Traumatized)
		th.hoursSinceLastDefeat = 0;
		th.traumaHours = nil;
		if ZR_AutoSurrender and ZR_AutoSurrender.invalidateMods then
			ZR_AutoSurrender.invalidateMods(player)
		end
		return
	end
end

local function onNewCharacter(player)
	player = player or getPlayer()
	if player == nil then return end
	local md = player:getModData(); if md == nil then return end

	md.timedHandler = nil
	md.succubusKills = nil
	md.zr_lastSceneHour = nil
	md.zr_innocentNightmaresUntil = nil
	md.zr_groinSceneTimes = nil
	md.ZomboRutSexScene = nil

	BodyCount.resetForNewCharacter(player)
	if ZR_Arousal and ZR_Arousal.resetForNewCharacter then
		ZR_Arousal.resetForNewCharacter(player)
	end
	if ZR_Trait and ZR_Trait.resetSeed then ZR_Trait.resetSeed(player) end

	initData()
	DebugLog.log("[ZomboRut] new character — previous life's mod state cleared")
end

local function sweepCarryoverOnLoad()
	local player = getPlayer(); if player == nil then return end
	local hours = player.getHoursSurvived and player:getHoursSurvived() or 1
	local md = player:getModData()
	if hours > 0.05 then return end
	local carried = md ~= nil and ((type(md.byCount) == "table" and #md.byCount > 0)
		or type(md.zr_slimitMoodleUntil) == "number"
		or (type(md.zr_arousal) == "number" and md.zr_arousal > 0)
		or (type(md.timedHandler) == "table" and (md.timedHandler.hoursSinceLastDefeat or 0) > 0))
	if not carried then return end
	DebugLog.log("[ZomboRut] fresh survivor loaded holding a previous life's records — sweeping")
	onNewCharacter(player)
end

Events.OnGameStart.Add(initData)
Events.OnGameStart.Add(sweepCarryoverOnLoad)
Events.OnNewGame.Add(onNewCharacter)
Events.EveryHours.Add(traumatizeTimer)
