-- parasite_longleg.lua (5 stages — SPAWNER)
-- The Hämis has laid eggs inside you. They will hatch.
--
-- S1: Eggs deposited, silk anchors forming. Light web trail.
-- S2: Cocoon thickens, silk pulls taut. Web trail widens, movement drag.
-- S3: Spiderlings stir inside the cocoon. Silk erupts from skin, player leaves web everywhere.
-- Reduced jump. Periodic silk constriction damage.
-- S4: The nest matures. Silk threads radiate outward, catching prey.
-- Nearby enemies snared (movement slow applied to them). Twin spawns.
-- S5: You are the cocoon. Longlegs emerge endlessly. All Hämis charmed.
-- Silk web pattern radiates from player. Movement penalty reduced (symbiosis).
dofile_once("mods/lewd_noita/files/status_effects/parasite_utils.lua")
dofile_once("mods/lewd_noita/files/status_effects/parasite_compulsion.lua")
dofile_once("mods/lewd_noita/files/text/ln_text.lua")


local MAX_STAGE = 5
local SPAWN_INTERVAL_MIN = 25 * 60
local SPAWN_INTERVAL_MAX = 55 * 60

local entity = GetUpdatedEntityID()
local vsc = get_parasite_timer_vsc(entity)
if vsc == nil then return end

local player_id = EntityGetParent(entity)
if player_id == nil or player_id == 0 then return end
local UI_MSG = "mods/lewd_noita/files/sex_logic/ui_msg.png"

local dmg_comp_h = EntityGetFirstComponent(player_id, "DamageModelComponent")
if dmg_comp_h ~= nil then
	local hp = tonumber(ComponentGetValue2(dmg_comp_h, "hp")) or 0
	local max_hp = tonumber(ComponentGetValue2(dmg_comp_h, "max_hp")) or 0
	local prev_hp = tonumber(GlobalsGetValue("LN_PREV_HP_LONGLEG", "-1"))
	GlobalsSetValue("LN_PREV_HP_LONGLEG", tostring(hp))
	if prev_hp >= 0 and max_hp > 0 and hp >= max_hp and prev_hp < max_hp then
		-- Restore jump on cure
		local plat = EntityGetFirstComponent(player_id, "CharacterPlatformingComponent")
		if plat then
			local orig = tonumber(GlobalsGetValue("LN_LONGLEG_ORIG_JUMP", "0"))
			if orig > 0 then ComponentSetValue2(plat, "jump_velocity_y", orig) end
		end
		remove_parasite_emitter(player_id, "ln_em_longleg")
		remove_parasite_overlay(player_id, "longleg")
		force_release_compulsion(player_id, "parasite_longleg")
		EntityKill(entity)
		ln_print_cure("parasite_longleg", UI_MSG)
		return
	end
end

local stage, did_advance = check_parasite_stage_change(entity, MAX_STAGE, "LN_STAGE_ANN_LONGLEG")
update_parasite_overlay(player_id, "longleg", stage)  -- resolves to spider art via ASSET_NAME

if did_advance then
	ln_print_stage("parasite_longleg", stage, UI_MSG)
end

local frame = GameGetFrameNum()
local px, py = EntityGetTransform(player_id)
SetRandomSeed(frame, entity)

-- Store original jump
local plat = EntityGetFirstComponent(player_id, "CharacterPlatformingComponent")
if plat and GlobalsGetValue("LN_LONGLEG_ORIG_JUMP", "0") == "0" then
	GlobalsSetValue("LN_LONGLEG_ORIG_JUMP", tostring(ComponentGetValue2(plat, "jump_velocity_y") or 300))
end

---------------------------------------------------------------------
-- VISUAL EFFECTS (scale with stage)
---------------------------------------------------------------------
-- Material-deposit particles disabled (was flooding the world with
-- blood_worm liquid material). Visuals now handled entirely by the
-- attached ParticleEmitterComponent (emitter_silk.xml) below.

-- S3+: Silk constriction damage + reduced jump (no particle spam)
if stage >= 3 then
	if Random(1, 12) == 1 then
		local max_hp = tonumber(ComponentGetValue2(dmg_comp_h, "max_hp")) or 4
		EntityInflictDamage(player_id, max_hp * 0.012, "DAMAGE_CURSE", "silk constriction", "NORMAL", 0, 0)
	end
	if plat then
		local orig = tonumber(GlobalsGetValue("LN_LONGLEG_ORIG_JUMP", "300"))
		local target = orig * 0.65
		local cur = tonumber(ComponentGetValue2(plat, "jump_velocity_y")) or orig
		if cur > target then
			ComponentSetValue2(plat, "jump_velocity_y", math.max(target, cur - 0.5))
		end
	end
end

-- S4+: Hunting web - snare nearby enemies with movement slow (no particle spam)
if stage >= 4 and frame % 45 == 0 then
	for _, e in ipairs(EntityGetInRadiusWithTag(px, py, 70, "enemy") or {}) do
		local gc = GetGameEffectLoadTo(e, "MOVEMENT_SLOWER", true)
		if gc then ComponentSetValue2(gc, "frames", 180) end
	end
end

-- S5: Full cocoon - symbiosis movement bonus, charm longlegs (no particle spam)
if stage >= 5 then
	-- Symbiosis: restore and boost movement
	if plat then
		local orig = tonumber(GlobalsGetValue("LN_LONGLEG_ORIG_JUMP", "300"))
		ComponentSetValue2(plat, "jump_velocity_y", orig * 1.3)
		local cur_speed = tonumber(ComponentGetValue2(plat, "run_velocity")) or 120
		if cur_speed < 170 then ComponentSetValue2(plat, "run_velocity", 170) end
	end
	-- Charm nearby longlegs
	if frame % 60 == 0 then
		for _, e in ipairs(EntityGetInRadiusWithTag(px, py, 120, "enemy") or {}) do
			local fname = EntityGetFilename(e) or ""
			if fname:find("longleg") then
				GetGameEffectLoadTo(e, "CHARM", true)
			end
		end
	end
end

-- Movement slow (all stages, reduced at S5 symbiosis)
local slow_dur = 120 + stage * 40
if stage >= 5 then slow_dur = 60 end
local has_slow = false
for _, child in ipairs(EntityGetAllChildren(player_id) or {}) do
	local gc = EntityGetFirstComponent(child, "GameEffectComponent")
	if gc ~= nil and ComponentGetValue2(gc, "effect") == "MOVEMENT_SLOWER" then
		local remaining = ComponentGetValue2(gc, "frames") or 0
		if remaining > 0 and remaining < 600 then
			ComponentSetValue2(gc, "frames", slow_dur)
			has_slow = true
			break
		end
	end
end
if not has_slow and stage < 5 then
	local effect = EntityCreateNew("ln_longleg_slow")
	EntityAddComponent2(effect, "InheritTransformComponent", {})
	EntityAddComponent2(effect, "GameEffectComponent", { effect="MOVEMENT_SLOWER", frames=slow_dur })
	EntityAddChild(player_id, effect)
end

---------------------------------------------------------------------

-- Particle emitter (stage 2+)
if stage >= 2 then
	attach_parasite_emitter(player_id, "ln_em_longleg", "mods/lewd_noita/files/particles/emitter_silk.xml")
end

-- COMPULSION
try_compulsion(player_id, "parasite_longleg", stage, {
	min_stage = 3,
	duration_min = 150, duration_max = 300,
	cooldown_min = 50 * 60, cooldown_max = 95 * 60,
})

-- INNER MONOLOGUE
---------------------------------------------------------------------
local next_msg = tonumber(GlobalsGetValue("LN_MSG_LONGLEG", "0"))
if next_msg == 0 then
	SetRandomSeed(frame, entity + 333)
	GlobalsSetValue("LN_MSG_LONGLEG", tostring(frame + Random(30 * 60, 150 * 60)))
elseif frame >= next_msg then
	SetRandomSeed(frame, entity + 333)
	ln_print_monologue("parasite_longleg", UI_MSG)
	GlobalsSetValue("LN_MSG_LONGLEG", tostring(frame + Random(30 * 60, 150 * 60)))
end

---------------------------------------------------------------------
-- SPAWNER LOGIC
---------------------------------------------------------------------
if EntityGetWithName("ln_sex_cooldown") ~= 0 then return end

local already_pregnant = false
for _, child in ipairs(EntityGetAllChildren(player_id) or {}) do
	if EntityGetName(child) == "ln_pregnancy" then
		local pvsc = EntityGetFirstComponent(child, "VariableStorageComponent")
		if pvsc ~= nil and ComponentGetValue2(pvsc, "value_string") == "data/entities/animals/longleg.xml" then
			already_pregnant = true
			break
		end
	end
end
if already_pregnant then return end

local dmg_comp = EntityGetFirstComponent(player_id, "DamageModelComponent")
if dmg_comp ~= nil and ComponentGetValue2(dmg_comp, "is_on_fire") == true then return end

local last_spawn = tonumber(ComponentGetValue2(vsc, "value_string")) or 0
local next_interval = tonumber(ComponentGetValue2(vsc, "value_int")) or 0
local mult = get_spawn_interval_mult(stage)

if next_interval == 0 then
	SetRandomSeed(frame, entity)
	next_interval = math.floor(Random(SPAWN_INTERVAL_MIN, SPAWN_INTERVAL_MAX) * mult)
	ComponentSetValue2(vsc, "value_int", next_interval)
	ComponentSetValue2(vsc, "value_string", tostring(frame))
	return
end
if frame - last_spawn < next_interval then return end

SetRandomSeed(frame, entity)
local spawn_file = "data/entities/animals/longleg.xml"

local function create_pregnancy(file)
	local pregnancy = EntityCreateNew("ln_pregnancy")
	EntityAddComponent2(pregnancy, "InheritTransformComponent", {})
	EntityAddComponent2(pregnancy, "GameEffectComponent", { effect="CUSTOM", custom_effect_id="EFFECT_PREGNANCY" })
	EntityAddComponent2(pregnancy, "UIIconComponent", { icon_sprite_file="mods/lewd_noita/files/status_effects/pregnant.png", name="Pregnant", description=ln_spawn_pregnancy_desc("parasite_longleg") })
	EntityAddComponent2(pregnancy, "VariableStorageComponent", { value_string=file, value_int=GameGetFrameNum() })
	EntityAddComponent2(pregnancy, "LuaComponent", { script_source_file="mods/lewd_noita/files/sex_logic/start_birth.lua", execute_every_n_frame=Random(60, 90) * 60, remove_after_executed=true })
	EntityAddChild(player_id, pregnancy)
end

create_pregnancy(spawn_file)
if stage >= 3 and Random(1, stage >= 5 and 1 or 3) == 1 then
	create_pregnancy(spawn_file)
	ln_print_spawn("parasite_longleg", "twin", UI_MSG)
else
	ln_print_spawn("parasite_longleg", "single", UI_MSG)
end

ComponentSetValue2(vsc, "value_string", tostring(frame))
ComponentSetValue2(vsc, "value_int", math.floor(Random(SPAWN_INTERVAL_MIN, SPAWN_INTERVAL_MAX) * mult))
