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

local ZomboRutScene = require "ZomboRut/ZomboRutScene"

local BEING_FEMALE_ID   = "BF"
local INTERCOURSE_EVENT = "BFIntercourse"
local WOMB_START_EVENT  = "BFWombAnimationStart"
local WOMB_UPDATE_EVENT = "BFWombAnimationUpdate"
local WOMB_STOP_EVENT   = "BFWombAnimationStop"
local WOMB_IMAGE_EVENT  = "BFWombImage"

local CONDOM_ITEM       = "BF.Condom"

local function rangeSteps(n)
	local t = {}
	for i = 0, n - 1 do t[#t + 1] = i end
	return t
end

local MAIN_VARIANTS = {
	{
		name            = "intercourse",
		steps           = { 0, 1, 2, 3, 4, 3, 2, 1 },
		loop            = 20,
		fullnessSupport = { "empty", "full" },
		path            = "media/ui/animation",
	},
	{
		name            = "intercourse-v1",
		steps           = rangeSteps(171),
		loop            = 1,
		fullnessSupport = { "empty" },
		path            = "media/ui/animation",
	},
	{
		name  = "intercourse-v3",
		steps = rangeSteps(29),
		loop  = 20,
		path  = "media/ui/animation",
	},
}

local OUTRO_CLIMAX_STEPS = { 5, 6, 7, 8, 9 }

if not getActivatedMods():contains(BEING_FEMALE_ID) then
	return
end

local DEBUG = true
local function log(fmt, ...)
	if DEBUG then DebugLog.log(string.format("[ZR BeingFemale] " .. fmt, ...)) end
end

log("detected '%s' — pregnancy + womb-anim integration enabled",
	BEING_FEMALE_ID)

ZomboRutScene.registerSceneStartCallback(function(player, active)
	if not player or not active then return end
	if not (active.cfg and active.cfg.pregnancyRisk) then return end

	local inv = player.getInventory and player:getInventory()
	if inv and inv:contains(CONDOM_ITEM) then
		active.ctx = active.ctx or {}
		active.ctx.condomActive = true
		log("scene '%s' start: condom in play -> zombie-sex sickness suppressed",
			tostring(active.sceneId))
	end

	if not (player.isFemale and player:isFemale()) then return end

	if not (Events and Events[WOMB_START_EVENT]) then
		log("scene '%s' start: %s not registered - womb anim skipped",
			tostring(active.sceneId), WOMB_START_EVENT)
		return
	end

	active.ctx = active.ctx or {}
	active.ctx.wombPhase = "pending"
	log("scene '%s' start: womb anim armed (will fire on intro end)",
		tostring(active.sceneId))
end)

ZomboRutScene.registerSceneUpdateCallback(function(player, active)
	if not (active and active.ctx) then return end
	local phase = active.ctx.wombPhase
	if not phase or phase == "done" then return end

	local introDone   = (player:getVariableString("ZR_IntroDone") == "true")
	local outroActive = (active.outroActivated == true)
	local dragTicks   = active.dragTicks or 0

	if phase == "pending" then
		if not introDone then return end
		active.ctx.wombPhase = "main"
		active.ctx.wombMainStartTicks = dragTicks
		local variant = MAIN_VARIANTS[ZombRand(#MAIN_VARIANTS) + 1]
		log("scene '%s' intro->main: start(%s)",
			tostring(active.sceneId), variant.name)
		triggerEvent(WOMB_START_EVENT, variant)
		phase = "main"
	end

	if phase == "main" then
		if outroActive then
			active.ctx.wombPhase = "outro"
			active.ctx.wombOutroStartTicks = dragTicks
			log("scene '%s' main->outro: stop + start(climax)",
				tostring(active.sceneId))
			triggerEvent(WOMB_STOP_EVENT)
			triggerEvent(WOMB_START_EVENT, {
				name            = "intercourse",
				steps           = OUTRO_CLIMAX_STEPS,
				loop            = 1,
				fullnessSupport = { "empty", "full" },
				path            = "media/ui/animation",
			})
			phase = "outro"
		else
			local effDur   = active.effectiveDuration
				or (active.cfg and active.cfg.duration) or 0
			local outroDur = (active.cfg and active.cfg.outroDuration) or 0
			if effDur <= 0 then return end
			local mainStart      = active.ctx.wombMainStartTicks or 0
			local mainEndTicks   = (effDur - outroDur) * 60
			local mainTotalTicks = math.max(1, mainEndTicks - mainStart)
			local delta = (dragTicks - mainStart) / mainTotalTicks
			if delta < 0 then delta = 0 end
			if delta > 1 then delta = 1 end
			triggerEvent(WOMB_UPDATE_EVENT, {
				delta    = delta,
				duration = mainTotalTicks / 60,
			})
			return
		end
	end

	if phase == "outro" then
		local outroDur = (active.cfg and active.cfg.outroDuration) or 0
		if outroDur <= 0 then return end
		local outroStart      = active.ctx.wombOutroStartTicks or dragTicks
		local outroTotalTicks = outroDur * 60
		local delta = (dragTicks - outroStart) / outroTotalTicks
		if delta < 0 then delta = 0 end
		if delta > 1 then delta = 1 end
		triggerEvent(WOMB_UPDATE_EVENT, {
			delta    = delta,
			duration = outroDur,
		})
	end
end)

ZomboRutScene.registerSceneEndCallback(function(player, active, result)
	if not player or not active then return end

	local hadAnim = active.ctx and active.ctx.wombPhase
		and active.ctx.wombPhase ~= "done"
		and active.ctx.wombPhase ~= "pending"

	if hadAnim then
		log("scene '%s' end (%s): triggerEvent('%s') from phase=%s",
			tostring(active.sceneId), tostring(result),
			WOMB_STOP_EVENT, tostring(active.ctx.wombPhase))
		triggerEvent(WOMB_STOP_EVENT)
	end

	if active.ctx and active.ctx.wombPhase then
		active.ctx.wombPhase = "done"
	end

	if result == "Released"
		and not active.struggleEscaped
		and active.cfg and active.cfg.pregnancyRisk
		and player.isFemale and player:isFemale()
	then
		if Events and Events[INTERCOURSE_EVENT] then
			log("scene '%s' completed -> triggerEvent('%s')",
				tostring(active.sceneId), INTERCOURSE_EVENT)
			triggerEvent(INTERCOURSE_EVENT)
		else
			log("scene '%s' completed but %s not registered - skipped",
				tostring(active.sceneId), INTERCOURSE_EVENT)
		end
	end

	if hadAnim and Events and Events[WOMB_IMAGE_EVENT] then
		triggerEvent(WOMB_IMAGE_EVENT)
	end
end)
