-- @author DoomTero 2026

require('NPCs/MainCreationMethods')

local getText = getText
local string = string

local MODULE = "zomborut"

local VANILLA_ALIASES = {
    Conspicuous = "base:conspicuous",
    Inconspicuous = "base:inconspicuous",
    Desensitized = "base:desensitized",
    Brave = "base:brave",
    Cowardly = "base:cowardly",
}
local function resolveTrait(name)
    local loc = VANILLA_ALIASES[name] or (MODULE .. ":" .. name:lower())
    return CharacterTrait.get(ResourceLocation.of(loc))
end

local TRAITS_LIST = {
	{
		IdentifierType = "Sexaddict",
		Cost = -4,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Masochist",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
		Callback = function(trait)
			trait:addXPBoost(Perks.Lightfoot, 1)
		end
	},
	{
		IdentifierType = "Rapist",
		Cost = 4,
		Profession = false,
		MutualExclusives = {},
		Callback = function(trait)
			trait:addXPBoost(Perks.Sneak, 1)
			trait:addXPBoost(Perks.LongBlade, 1)
		end
	},
	{
		IdentifierType = "Wimp",
		Cost = -4,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Necrophiliac",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Virgin",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Inexperienced",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Experienced",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Nymphomaniac",
		Cost = 6,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Innocent",
		Cost = -5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Lewd",
		Cost = 4,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "Traumatized",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "succubus",
		Cost = 5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "submissive",
		Cost = -3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "dominate",
		Cost = 5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "youngBuck",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "AARP",
		Cost = -2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "inPrime",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "spunkDefault",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "lowEffort",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "smokesAfter",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "betterAlive",
		Cost = 4,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "itFollows",
		Cost = -8,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "promiscuous",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "swinger",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "unkempt",
		Cost = -5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "neatTidy",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "lovesClean",
		Cost = 5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "viciousZombies",
		Cost = -5,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "dpress",
		Cost = 0,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "proteinDiet",
		Cost = 3,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "hydration",
		Cost = 2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "drained",
		Cost = -2,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "fighter",
		Cost = 4,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "glassBones",
		Cost = -9,
		Profession = false,
		MutualExclusives = {},
	},
	{
		IdentifierType = "cardioJunkie",
		Cost = 5,
		Profession = false,
		MutualExclusives = {},
	},
}

local function _initTraits()
	for i = 1, #TRAITS_LIST do
		local data = TRAITS_LIST[i]
		local id   = data.IdentifierType
		local loc  = MODULE .. ":" .. id:lower()
		local name = getText(string.format("UI_ZL_Trait_%s", id))
		local desc = getText(string.format("UI_ZL_Trait_%s_Description", id))

		local trait = CharacterTrait.register(loc)
		local def   = CharacterTraitDefinition.addCharacterTraitDefinition(
			trait, name, data.Cost, desc, data.Profession
		)

		if data.Callback then
			data.Callback(def)
		end

		for v = 1, #data.MutualExclusives do
			local other = resolveTrait(data.MutualExclusives[v])
			if trait and other then
				CharacterTraitDefinition.setMutualExclusive(trait, other)
			end
		end
	end

	local function X(aName, bName)
		local a, b = resolveTrait(aName), resolveTrait(bName)
		if a and b then CharacterTraitDefinition.setMutualExclusive(a, b) end
	end

	X("Virgin", "Inexperienced")
	X("Virgin", "Experienced")
	X("Virgin", "Nymphomaniac")
	X("Inexperienced", "Experienced")
	X("Inexperienced", "Nymphomaniac")
	X("Experienced", "Nymphomaniac")
	X("Innocent", "Lewd")
	X("Innocent", "Nymphomaniac")
	X("Innocent", "Sexaddict")
	X("Innocent", "succubus")
	X("Innocent", "Rapist")
	X("Sexaddict", "Virgin")
	X("hydration", "drained")
	X("Wimp", "Rapist")
	X("Wimp", "Masochist")
	X("Wimp", "Nymphomaniac")
	X("Wimp", "Lewd")
	X("dominate", "submissive")
	X("dominate", "Wimp")
	X("youngBuck", "AARP")
	X("youngBuck", "inPrime")
	X("AARP", "inPrime")
	X("AARP", "lowEffort")
	X("lowEffort", "youngBuck")
	X("lowEffort", "inPrime")
	X("itFollows", "succubus")
	X("promiscuous", "Innocent")
	X("promiscuous", "swinger")
	X("swinger", "Innocent")
	X("unkempt", "neatTidy")
	X("unkempt", "lovesClean")
	X("neatTidy", "lovesClean")
end

initTraits2 = function()
	local conspicuous2 = CharacterTrait.register(MODULE .. ":conspicuous2")
	CharacterTraitDefinition.addCharacterTraitDefinition(
		conspicuous2,
		getText("UI_trait_Conspicuous"), 0,
		getText("UI_trait_ConspicuousDesc"),
		true
	)

	local desensitized2 = CharacterTrait.register(MODULE .. ":desensitized2")
	CharacterTraitDefinition.addCharacterTraitDefinition(
		desensitized2,
		getText("UI_trait_Desensitized"), 0,
		getText("UI_trait_DesensitizedDesc"),
		true
	)

	local function X(aName, bName)
		local a, b = resolveTrait(aName), resolveTrait(bName)
		if a and b then CharacterTraitDefinition.setMutualExclusive(a, b) end
	end
	X("Conspicuous2", "Conspicuous")
	X("Conspicuous2", "Inconspicuous")
	X("Desensitized2", "Desensitized")
	X("Desensitized2", "Brave")
	X("Desensitized2", "Cowardly")
end

local function prostituteOccupation()
	local prof = CharacterProfession.register(MODULE .. ":prostitute")
	local def  = CharacterProfessionDefinition.addCharacterProfessionDefinition(
		prof,
		getText("UI_prof_prostitute"),
		2,
		getText("UI_profdesc_prostitute"),
		"prof_Prostitute"
	)
	def:addXPBoost(Perks.Aiming, 1)
	def:addGrantedTrait(resolveTrait("promiscuous"))
	def:addGrantedTrait(resolveTrait("Conspicuous2"))
end

local function sexSlaveOccupation()
	local prof = CharacterProfession.register(MODULE .. ":sexslave")
	local def  = CharacterProfessionDefinition.addCharacterProfessionDefinition(
		prof,
		getText("UI_prof_sexslave"),
		-3,
		getText("UI_profdesc_sexslave"),
		"prof_sexslave"
	)
	def:addXPBoost(Perks.Strength, -2)
	def:addXPBoost(Perks.Fitness, -2)
	def:addGrantedTrait(resolveTrait("Desensitized2"))
	def:addGrantedTrait(resolveTrait("dpress"))
end

pTraitsInit = function(playernum, character)
	local player = getSpecificPlayer(playernum);
	local pTraits = player:getCharacterTraits();

	if ZR_Trait.has(player, "Conspicuous2") then
		pTraits:remove(ZR_Trait.Conspicuous2);
		pTraits:add(ZR_Trait.Conspicuous);
	end

	if ZR_Trait.has(player, "Desensitized2") then
		pTraits:remove(ZR_Trait.Desensitized2);
		pTraits:add(ZR_Trait.Desensitized);
	end

	if not ZR_Trait.has(player, "spunkDefault") and not ZR_Trait.has(player, "AARP") and not ZR_Trait.has(player, "inPrime") and not ZR_Trait.has(player, "youngBuck") and not ZR_Trait.has(player, "lowEffort") then
		pTraits:add(ZR_Trait.spunkDefault);
	end

end

function pStartGear(player)
	local desc = player:getDescriptor();
	local currentProf = desc and desc:getCharacterProfession() or nil;
	local prostituteProf  = CharacterProfession.get(ResourceLocation.of("zomborut:prostitute"));

	if currentProf ~= nil and currentProf == prostituteProf then
		player:getInventory():AddItem("Base.Revolver", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
		player:getInventory():AddItem("Base.Bullets45", 1);
	end

	if ZR_Trait.has(player, "Rapist") then
		player:getInventory():AddItem("Base.KitchenKnife", 1);
		player:getInventory():AddItem("Base.Rope", 1);
		player:getInventory():AddItem("Base.DuctTape", 1);
	end
end

Events.OnGameBoot.Add(_initTraits);
Events.OnGameBoot.Add(initTraits2);
Events.OnGameBoot.Add(prostituteOccupation);
Events.OnGameBoot.Add(sexSlaveOccupation);

Events.OnCreatePlayer.Add(pTraitsInit)
Events.OnNewGame.Add(pStartGear)