-- wolf_leash_drive.lua
-- Player keeps FULL control. Chain only yanks player back if they
-- exceed tether distance from the wolf. Wolf moves independently.

dofile_once("data/scripts/lib/utilities.lua")

local leash = GetUpdatedEntityID()
local player_id = EntityGetParent(leash)
if player_id == nil or player_id == 0 then
	EntityKill(leash)
	return
end

if GlobalsGetValue("LN_WOLF_BOND_ACTIVE", "0") ~= "1" then
	local rope_id = tonumber(GlobalsGetValue("LN_WOLF_ROPE_ID", "0")) or 0
	if rope_id ~= 0 and EntityGetIsAlive(rope_id) then EntityKill(rope_id) end
	GlobalsSetValue("LN_WOLF_ROPE_ID", "0")
	EntityKill(leash)
	return
end

local wolf_id = tonumber(GlobalsGetValue("LN_WOLF_BOND_OWNER", "0")) or 0
if wolf_id == 0 or not EntityGetIsAlive(wolf_id) then
	dofile_once("mods/lewd_noita/files/status_effects/wolf_bonding.lua")
	release_wolf_leash(player_id)
	EntityKill(leash)
	return
end

local px, py = EntityGetTransform(player_id)
local wx, wy = EntityGetTransform(wolf_id)
if wx == nil or wy == nil then return end

-- Collar on player, chain to wolf body
local py_chain = py - 4
local wy_chain = wy - 2

local dx = wx - px
local dy = wy - py
local dist = math.sqrt(dx * dx + dy * dy)

local CHAIN_LENGTH = 35

---------------------------------------------------------------------
-- ONE-DIRECTIONAL TETHER: wolf moves freely, player gets yanked
-- back if they exceed chain length. Player controls are untouched.
---------------------------------------------------------------------
if dist > CHAIN_LENGTH then
	local nx = dx / dist
	local ny = dy / dist
	local target_x = wx - nx * CHAIN_LENGTH
	local target_y = wy - ny * CHAIN_LENGTH
	EntitySetTransform(player_id, target_x, target_y)
	px, py = target_x, target_y
	py_chain = py - 4
end

---------------------------------------------------------------------
-- VERLET ROPE: two world anchors (player <-> wolf). Must use a cord
-- with VERLET_ROPE_TWO_JOINTS — verlet_cord_short only supports one.
---------------------------------------------------------------------
local ROPE_ENTITY = "data/entities/verlet_chains/cords/verlet_cord.xml"

local function spawn_tracked_rope(entity_filename, x1, y1, x2, y2)
	local eid = EntityLoad(entity_filename, x1, y1)
	if not is_valid_entity(eid) then return 0 end

	local move_comp = EntityGetFirstComponent(eid, "MoveToSurfaceOnCreateComponent")
	if move_comp then EntityRemoveComponent(eid, move_comp) end

	local last_point_index = 0
	edit_component(eid, "VerletPhysicsComponent", function(comp, vars)
		local num_points = tonumber(ComponentGetValue2(comp, "num_points")) or 2
		last_point_index = math.max(0, num_points - 1)
		vars.simulate_gravity = "0"
		vars.simulate_wind = "0"
	end)

	EntityAddComponent2(eid, "VerletWorldJointComponent", {})
	EntityAddComponent2(eid, "VerletWorldJointComponent", {})
	local joints = EntityGetComponent(eid, "VerletWorldJointComponent") or {}
	if #joints >= 2 then
		ComponentSetValue2(joints[1], "verlet_point_index", 0)
		ComponentSetValueVector2(joints[1], "world_position", x1, y1)
		ComponentSetValue2(joints[2], "verlet_point_index", last_point_index)
		ComponentSetValueVector2(joints[2], "world_position", x2, y2)
	end

	return eid
end

local function update_rope_joints(rope_id, x1, y1, x2, y2)
	local joints = EntityGetComponent(rope_id, "VerletWorldJointComponent") or {}
	if #joints < 2 then return end
	ComponentSetValueVector2(joints[1], "world_position", x1, y1)
	ComponentSetValueVector2(joints[2], "world_position", x2, y2)
end

local rope_id = tonumber(GlobalsGetValue("LN_WOLF_ROPE_ID", "0")) or 0
if rope_id == 0 or not EntityGetIsAlive(rope_id) then
	rope_id = spawn_tracked_rope(ROPE_ENTITY, px, py_chain, wx, wy_chain)
	if rope_id ~= 0 then
		GlobalsSetValue("LN_WOLF_ROPE_ID", tostring(rope_id))
	end
else
	update_rope_joints(rope_id, px, py_chain, wx, wy_chain)
end

---------------------------------------------------------------------
-- AMBIENT THOUGHTS (every ~8s)
---------------------------------------------------------------------
local frame = GameGetFrameNum()
if frame % 480 == 0 then
	SetRandomSeed(frame, player_id + 4444)
	local THOUGHTS = {
		"The chain tugs at your throat. The wolf leads.",
		"You are its bitch. The word fits like a collar.",
		"The knot swells in memory. You clench around the phantom.",
		"It stops. You stop. Trained.",
		"The wolf glances back. Satisfied. You flush with warmth.",
		"You have forgotten what you came down here for.",
		"The leash is not punishment. It is relief.",
		"Your body knows its place. At heel. On the chain.",
	}
	GamePrint(THOUGHTS[Random(1, #THOUGHTS)])
end
