Player = {}

RegisterNetEvent("spyoo_skin:hasSpawn")
AddEventHandler("spyoo_skin:hasSpawn", function()
	TriggerServerEvent("spyoo_skin:spawned")
	Wait(5000)
	TriggerServerEvent("spyoo_skin:loadClothes")
end)

RegisterNetEvent("spyoo_skin:CharCreation")
AddEventHandler("spyoo_skin:CharCreation", function()
	DoScreenFadeOut(500)
	CharCreation()
end)

RegisterNetEvent("spyoo_skin:getClothes")
AddEventHandler("spyoo_skin:getClothes", function(clothes)
	local Ped = GetPlayerPed(-1)
	SetPedComponentVariation(Ped, 1, clothes["mask_1"], clothes["mask_2"], 0)
	SetPedComponentVariation(Ped, 3, clothes["arms"], 0, 0)
	SetPedComponentVariation(Ped, 4, clothes["pants_1"], clothes["pants_2"], 0)
	SetPedComponentVariation(Ped, 5, clothes["bags_1"], clothes["bags_2"], 0)
	SetPedComponentVariation(Ped, 6, clothes["shoes_1"], clothes["shoes_2"], 0)
	SetPedComponentVariation(Ped, 7, clothes["chain_1"], clothes["chain_2"], 0)
	SetPedComponentVariation(Ped, 8, clothes["tshirt_1"], clothes["tshirt_2"], 0)
	SetPedComponentVariation(Ped, 9, clothes["bproof_1"], clothes["bproof_2"], 0)
	SetPedComponentVariation(Ped, 10, clothes["decals_1"], clothes["decals_2"], 0)
	SetPedComponentVariation(Ped, 11, clothes["torso_1"], clothes["torso_2"], 0)
	ClearPedProp(Ped, 0)
	ClearPedProp(Ped, 1)
	ClearPedProp(Ped, 2)
	ClearPedProp(Ped, 6)
	ClearPedProp(Ped, 7)
	if clothes["helmet_1"] ~= -1 and clothes["helmet_1"] ~= nil then
		SetPedPropIndex(Ped, 0,  clothes["helmet_1"], clothes["helmet_2"], true)
	end
	if clothes["glasses_1"] ~= -1 and clothes["glasses_1"] ~= nil then
		SetPedPropIndex(Ped, 1,  clothes["glasses_1"], clothes["glasses_2"], true)
	end
	if clothes["ears_1"] ~= -1 and clothes["ears_1"] ~= nil then
		SetPedPropIndex(Ped, 2,  clothes["ears_1"], clothes["ears_2"], true)
	end
	if clothes["watches_1"] ~= -1 and clothes["watches_1"] ~= nil then
		SetPedPropIndex(Ped, 6,  clothes["watches_1"], clothes["watches_2"], true)
	end
	if clothes["bracelet_1"] ~= -1 and clothes["bracelet_1"] ~= nil then
		SetPedPropIndex(Ped, 7,  clothes["bracelet_1"], clothes["bracelet_2"], true)
	end
end)

Keys.Register("F11", "F11", "Rerol", function()
	TriggerEvent("spyoo_skin:CharCreation")
end)

function CharCreation()
	TriggerEvent("skinchanger:loadSkin", { ["sex"] = 0 })
	local pa = GetPlayerPed(-1)
	SetEntityHealth(pa, GetEntityMaxHealth(pa))
	if IsPedDeadOrDying(pa, 1) then
		TriggerServerEvent("spyoo_hopital:reviveSpe")
		Wait(1000)
		SetEntityHealth(pa, GetEntityMaxHealth(pa))
	end
	SetEntityCoordsNoOffset(GetPlayerPed(-1), vector3(-1037.98, -2738.21, 20.66), false, false, false)
	CreateSkinCam()
	Wait(5000)
	DoScreenFadeIn(500)
	local Ped = PlayerPedId()
	local listes = {}
	local ListIndex = {}
	local maxIndex = {}
	local isIn = true
	local close = false
	TriggerEvent('skinchanger:getData', function(components, maxVals)
		maxVals["sex"] = 1
		for k,v in pairs(components) do
			local add = false
			for ke,ve in pairs(Config.toAdd.Creator) do
				if ve == v.name then
					add = true
					break
				end
			end

			if add then
				table.insert(listes, { name = v.name, label = v.label })
				ListIndex[v.name] = 1
				maxIndex[v.name] = {}
				for i = 1, maxVals[v.name] + 1, 1 do
					table.insert(maxIndex[v.name], i)
				end
			end
		end
	end)

	local MenuCreationPerso = RageUI.CreateMenu("Création", " ", false, 0, 200);
	MenuCreationPerso.EnableMouse = false;
	
	function RageUI.PoolMenus:MenuCreationPerso()
		if close and RageUI.Visible(MenuCreationPerso) then
			FreezeEntityPosition(GetPlayerPed(-1), false)
			RageUI.Visible(MenuCreationPerso, not RageUI.Visible(MenuCreationPerso))
		end
		MenuCreationPerso:IsVisible(function(Items)
			for k,v in pairs(listes) do
				Items:AddList(v.label, maxIndex[v.name], ListIndex[v.name], nil, {}, function(Index, Selected, ListChange, Hovered, onActive)
					if (ListChange) then
						ListIndex[v.name] = Index
						local value = ListIndex[v.name] - 1
						TriggerEvent("skinchanger:change", v.name, value)
					end
				end)
			end
			Items:AddButton("Crée", "", { IsDisabled = false }, function(Selected, Hovered, Active)
				if (Selected) then
					close = true
					isIn = false
					DeleteSkinCam()
					TriggerEvent("skinchanger:getSkin", function(skin)
						TriggerServerEvent("spyoo_skin:saveSkin", skin, true)
						local sex
						local pants1
						local shoes1
						if skin["sex"] == 0 then
							sex = "male"
							pants1 = 61
							shoes1 = 34
						else
							sex = "female"
							pants1 = 14
							shoes1 = 35
						end
						TriggerServerEvent("spyoo_skin:saveClothes", {
							["tshirt_1"] = 15,
							["tshirt_2"] = 0,
							["torso_1"] = 15,
							["torso_2"] = 0,
							["arms"] = 15,
							["decals"] = 0,
							["pants_1"] = pants1,
							["pants_2"] = 0,
							["shoes_1"] = shoes1,
							["shoes_2"] = 0,
						})
						Wait(500)
						TriggerServerEvent("spyoo_skin:loadClothes")
					end)
				end
			end)
		end, function(Panels)
		end)
	end

	RageUI.Visible(MenuCreationPerso, not RageUI.Visible(MenuCreationPerso))
end

function OpenMenuShopClothes(toAdd, price)
	local listes = {}
	for k,v in pairs(toAdd) do
		table.insert(listes, { label = v.label, item = v.item, price = v.price })
	end

	local MenuShopClothes = RageUI.CreateMenu("Magasin", " ", true, 0, 200);
	MenuShopClothes.EnableMouse = false;
	
	function RageUI.PoolMenus:MenuShopClothes()
		MenuShopClothes:IsVisible(function(Items)
			for k,v in pairs(listes) do
				Items:AddButton(v.label, "", { IsDisabled = false }, function(Selected, Hovered, Active)
					if (Selected) then
						OpenMenuShopClothesComponents(v.item, toAdd, v.price)
					end
				end)
			end
		end, function(Panels)
		end)
	end

	RageUI.Visible(MenuShopClothes, not RageUI.Visible(MenuShopClothes))
end

function OpenMenuShopClothesComponents(item, toAdd, price)
	RageUI.Visible(MenuShopClothes, not RageUI.Visible(MenuShopClothes))
	CreateSkinCam()
	local Ped = PlayerPedId()
	local SkinPlayer = {}
	local sex
	TriggerEvent("skinchanger:getSkin", function(skin)
		SkinPlayer = skin
		if skin["sex"] == 0 then
			sex = "male"
		else
			sex = "female"
		end
	end)
	local listes = {}
	local ListIndex = {}
	local maxIndex = {}
	local isIn = true
	local other = false

	local Ped = GetPlayerPed(-1)
	local order = Config.Order[item]
	for _, key in ipairs(order) do
		local v = Config.Clothes[item][key]
		if v.second then
			table.insert(listes, { type = v.type, name = v.name, component = v.component, label = v.label, change = "first", second = v.second.name })
		else
			table.insert(listes, { type = v.type, name = v.name, component = v.component, label = v.label, change = "first" })
		end
		ListIndex[v.name] = 1
		maxIndex[v.name] = {}
		if v.type == "clothes" then
			for i = 1, GetNumberOfPedDrawableVariations(Ped, v.component), 1 do
				table.insert(maxIndex[v.name], i)
			end
		elseif v.type == "props" then
			for i = 1, GetNumberOfPedPropDrawableVariations(Ped, v.component), 1 do
				table.insert(maxIndex[v.name], i)
			end
		end
		if v.second then
			table.insert(listes, { type = v.type, name = v.second.name, component = v.component, label = v.second.label, change = "second", first = v.name })
			ListIndex[v.second.name] = 1
			maxIndex[v.second.name] = {}
			if v.type == "clothes" then
				for i = 1, GetNumberOfPedTextureVariations(Ped, v.component, 0), 1 do
					table.insert(maxIndex[v.second.name], i)
				end
			elseif v.type == "props" then
				for i = 1, GetNumberOfPedPropTextureVariations(Ped, v.component, 0), 1 do
					table.insert(maxIndex[v.second.name], i)
				end
			end
		end
	end

	local MenuShopClothesComponents = RageUI.CreateMenu("Magasin", " ", true, 0, 200);
	MenuShopClothesComponents.EnableMouse = false;
	
	local close = false
	local buying = false

	function RageUI.PoolMenus:MenuShopClothesComponents()
		if not RageUI.Visible(MenuShopClothesComponents) and isIn and not buying then
			OpenMenuShopClothes(toAdd)
		end
		if not RageUI.Visible(MenuShopClothesComponents) and isIn then
			isIn = false
			TriggerServerEvent("spyoo_skin:loadClothes")
			DeleteSkinCam()
		end
		if close then
			close = false
			TriggerServerEvent("spyoo_skin:loadClothes")
			RageUI.Visible(MenuShopClothesComponents, false)
			DeleteSkinCam()
		end
		MenuShopClothesComponents:IsVisible(function(Items)
			for k,v in pairs(listes) do
				Items:AddList(v.label, maxIndex[v.name], ListIndex[v.name], nil, {}, function(Index, Selected, ListChange, Hovered, onActive)
					if (ListChange) then
						ListIndex[v.name] = Index
						if v.type == "clothes" then
							local change = v.change
							if change == "first" then
								local second = v.second
								if second ~= nil then
									max = GetNumberOfPedTextureVariations(Ped, v.component, (ListIndex[v.name] - 1))
									max = max - 1
									ListIndex[second] = 1
									maxIndex[second] = {}
									for i = 1, max, 1 do
										table.insert(maxIndex[second], i)
									end
									SetPedComponentVariation(Ped, v.component, (ListIndex[v.name] - 1), (ListIndex[second] - 1), 0)
								else
									SetPedComponentVariation(Ped, v.component, (ListIndex[v.name] - 1), 0, 0)
								end
							end
							if change == "second" then
								local first = v.first
								SetPedComponentVariation(Ped, v.component, (ListIndex[first] - 1), (ListIndex[v.name] - 1), 0)
							end
						elseif v.type == "props" then
							ClearPedProp(Ped, v.component)
							local change = v.change
							if change == "first" then
								local second = v.second
								if second ~= nil then
									max = GetNumberOfPedPropTextureVariations(Ped, v.component, (ListIndex[v.name] - 1))
									max = max - 1
									ListIndex[second] = 1
									maxIndex[second] = {}
									for i = 1, max, 1 do
										table.insert(maxIndex[second], i)
									end
									SetPedPropIndex(Ped, v.component, (ListIndex[v.name] - 1), (ListIndex[second] - 1), true)
								else
									SetPedPropIndex(Ped, v.component, (ListIndex[v.name] - 1), 0, true)
								end
							end
							if change == "second" then
								local first = v.first
								SetPedPropIndex(Ped, v.component, (ListIndex[first] - 1), (ListIndex[v.name] - 1), true)
							end
						end
					end
				end)
			end
			Items:AddButton("Acheter", "", { IsDisabled = false }, function(Selected, Hovered, Active)
				if (Selected) then
					close = true
					buying = true
					TriggerServerEvent("spyoo_inventory:addItem", "me", item, 1, ListIndex)
					-- TriggerEvent("spyoo_inventory:methodPayment", { buying = "item", item = item, count = 1, data = ListIndex, price = price })
				end
			end)
		end, function(Panels)
		end)
	end

	RageUI.Visible(MenuShopClothesComponents, not RageUI.Visible(MenuShopClothesComponents))
end

function OpenMenuCoiffeur()
	local MenuMainCoiffeur = RageUI.CreateMenu("Coiffeur", " ", true, 0, 200);
	MenuMainCoiffeur.EnableMouse = false;
	local SkinPlayer = {}
	TriggerEvent("skinchanger:getSkin", function(skin)
		SkinPlayer = skin
	end)
	local listes = {}
	local ListIndex = {}
	local maxIndex = {}
	local isIn = true
	TriggerEvent('skinchanger:getData', function(components, maxVals)
		for k,v in pairs(components) do
			if v.name == "hair_1" or v.name == "hair_2" or v.name == "hair_color_1" or v.name == "hair_color_2" or v.name == "beard_1" or v.name == "beard_2" or v.name == "beard_3" or v.name == "beard_4" then
				table.insert(listes, { name = v.name, label = v.label })
				ListIndex[v.name] = SkinPlayer[v.name]
				maxIndex[v.name] = {}
				for i = 1, maxVals[v.name], 1 do
					table.insert(maxIndex[v.name], i)
				end
			end
		end
	end)
	CreateSkinCam()
	function RageUI.PoolMenus:MenuMainCoiffeur()
		if not RageUI.Visible(MenuMainCoiffeur) and isIn then
			isIn = false
			TriggerEvent("skinchanger:loadSkin", SkinPlayer)
			TriggerServerEvent("spyoo_skin:loadClothes")
			DeleteSkinCam()
		end
		if close then
			close = false
			isIn = false
			Wait(500)
			TriggerEvent("skinchanger:loadSkin", SkinPlayer)
			TriggerServerEvent("spyoo_skin:loadClothes")
			DeleteSkinCam()
			RageUI.Visible(MenuMainCoiffeur, false)
		end
		MenuMainCoiffeur:IsVisible(function(Items)
			for k,v in pairs(listes) do
				Items:AddList(v.label, maxIndex[v.name], ListIndex[v.name], nil, {}, function(Index, Selected, ListChange, Hovered, onActive)
					if (ListChange) then
						ListIndex[v.name] = Index
						local value = ListIndex[v.name]
						TriggerEvent("skinchanger:change", v.name, value)
						TriggerServerEvent("spyoo_skin:loadClothes")
					end
				end)
			end
			Items:AddButton("Acheter", "", { IsDisabled = false }, function(Selected, Hovered, Active)
				if (Selected) then
					close = true
					TriggerEvent("spyoo_inventory:methodPayment", { buying = "event", event = "spyoo_skin:setSkinCoiffeur", price = 5, data = ListIndex })
				end
			end)
		end, function(Panels)
		end)
	end

	RageUI.Visible(MenuMainCoiffeur, not RageUI.Visible(MenuMainCoiffeur))
end

RegisterNetEvent("spyoo_skin:setSkinCoiffeur")
AddEventHandler("spyoo_skin:setSkinCoiffeur", function(data)
	for k,v in pairs(data.data) do
		TriggerEvent("skinchanger:change", k, v)
	end
	Wait(500)
	TriggerEvent("skinchanger:getSkin", function(skin)
		TriggerServerEvent("spyoo_skin:saveSkin", skin, false)
	end)
end)

function BuyClothes(item, data)
	TriggerServerEvent("spyoo_skin:buyClothes", item, data)
end

function CreateSkinCam()
	if not DoesCamExist(cam) then
		cam = CreateCam('DEFAULT_SCRIPTED_CAMERA', true)
	end

	SetCamActive(cam, true)
	RenderScriptCams(true, true, 500, true, true)

	isCameraActiveCreator = true
	SetCamRot(cam, 0.0, 0.0, 270.0, true)
	-- SetEntityHeading(player, 90.0)
end

function DeleteSkinCam()
	isCameraActiveCreator = false
	SetCamActive(cam, false)
	RenderScriptCams(false, true, 500, true, true)
	cam = nil
end

local zoomOffset, camOffset, heading = 0.8, 0.5, 180.0

Citizen.CreateThread(function()
	while true do
		Citizen.Wait(1)

		if isCameraActiveCreator then
			ShowHelpNotification("SPYOO_SKIN_CAMERA", "Appuyez sur ~INPUT_VEH_FLY_ROLL_LEFT_ONLY~ et ~INPUT_VEH_FLY_ROLL_RIGHT_ONLY~ pour gérer l'angle~n~Appuyez sur ~INPUT_VEH_FLY_PITCH_UP_ONLY~ et ~INPUT_VEH_FLY_PITCH_DOWN_ONLY~ pour gérer la hauteur~n~Appuyez sur ~INPUT_VEH_FLY_SELECT_TARGET_LEFT~ et ~INPUT_VEH_FLY_SELECT_TARGET_RIGHT~ pour gérer le zoom")
			DisableControlAction(2, 30, true)
			DisableControlAction(2, 31, true)
			DisableControlAction(2, 32, true)
			DisableControlAction(2, 33, true)
			DisableControlAction(2, 34, true)
			DisableControlAction(2, 35, true)
			DisableControlAction(0, 25, true) -- Input Aim
			DisableControlAction(0, 24, true) -- Input Attack

			local coords = GetEntityCoords(player)

			local angle = heading * math.pi / 180.0
			local theta = {
				x = math.cos(angle),
				y = math.sin(angle)
			}

			local pos = {
				x = coords.x + (zoomOffset * theta.x),
				y = coords.y + (zoomOffset * theta.y)
			}

			local angleToLook = heading - 140.0
			if angleToLook > 360 then
				angleToLook = angleToLook - 360
			elseif angleToLook < 0 then
				angleToLook = angleToLook + 360
			end

			angleToLook = angleToLook * math.pi / 180.0
			local thetaToLook = {
				x = math.cos(angleToLook),
				y = math.sin(angleToLook)
			}

			local posToLook = {
				x = coords.x + (zoomOffset * thetaToLook.x),
				y = coords.y + (zoomOffset * thetaToLook.y)
			}

			SetCamCoord(cam, pos.x, pos.y, coords.z + camOffset)
			PointCamAtCoord(cam, posToLook.x, posToLook.y, coords.z + camOffset)
		else
			Citizen.Wait(500)
		end
	end
end)

Citizen.CreateThread(function()
	local angle = 90
	while true do
		Citizen.Wait(0)
		if isCameraActiveCreator then
			if IsControlPressed(0, 108) then
				angle = angle - 1
			elseif IsControlPressed(0, 109) then
				angle = angle + 1
			end

			if IsControlPressed(0, 111) then
				camOffset = camOffset + 0.02
			elseif IsControlPressed(0, 112) then
				camOffset = camOffset - 0.02
			end

			if IsControlPressed(0, 117) then -- 7
				zoomOffset = zoomOffset + 0.02
			elseif IsControlPressed(0, 118) then -- 9
				zoomOffset = zoomOffset - 0.02
			end

			if 0.3 > zoomOffset then
				zoomOffset = 0.3
			elseif zoomOffset > 1.5 then
				zoomOffset = 1.5
			end
			if camOffset > 0.9 then
				camOffset = 0.9
			elseif -0.8 > camOffset then
				camOffset = -0.8
			end
			if angle > 360 then
				angle = angle - 360
			elseif angle < 0 then
				angle = angle + 360
			end

			heading = angle + 0.0
		else
			Citizen.Wait(500)
		end
	end
end)

Citizen.CreateThread(function()
	while true do
		Wait(1)
		for k,v in pairs(Config.ShopClothes) do
			local dist = GetDistanceBetweenCoords(pCoords, v[1], true)
			if dist < 10.0 then
				marker(v[1], "Appuyez sur ~r~[E]~w~ pour accéder au magasin")
				if dist < 2.0 and IsControlJustPressed(0, 38) then
					if v[2] == "Coiffeur" then
						OpenMenuCoiffeur()
					else 
						OpenMenuShopClothes(Config.toAdd[v[2]])
					end
				end
			end
		end
	end
end)

RegisterNetEvent("spyoo_skin:changeClothes")
AddEventHandler("spyoo_skin:changeClothes", function(item, data, pos)
	local Ped = PlayerPedId()
	local sex
	TriggerEvent("skinchanger:getSkin", function(skin)
		if skin["sex"] == 0 then
			sex = "male"
		else
			sex = "female"
		end
	end)
	for k,v in pairs(data) do
		if k ~= "label" and k ~= "canGive" then
			data[k] = data[k] - 1
		end
	end
	local todo = Config.Clothes[item]
	local enlever = false
	local z = 0
	local x = 0
	for k,v in pairs(todo) do
		x = x + 1
		if v.type == "clothes" then
			if data[v.name] == GetPedDrawableVariation(Ped, v.component) then
				z = z + 1
			else
				if v.second then
					x = x + 1
					if data[v.second.name] == GetPedTextureVariation(Ped, v.component) then
						z = z + 1
					end
				end
			end
		elseif v.type == "props" then
			if data[v.name] == GetPedPropIndex(Ped, v.component) then
				z = z + 1
			else
				if v.second then
					x = x + 1
					if data[v.second.name] == GetPedPropTextureIndex(Ped, v.component) then
						z = z + 1
					end
				end
			end		
		end
	end
	if z == x then
		enlever = true
	end

	if enlever then
		for k,v in pairs(todo) do
			if v.second then
				data[v.name] = v.default[sex]
				data[v.second.name] = v.second.default[sex]
			else
				data[v.name] = v.default[sex]
			end
		end
	end

	TriggerServerEvent("spyoo_skin:saveClothes", data)
	TriggerServerEvent("spyoo_inventory:setWearing", item, pos, enlever)

	if Config.OnUse[item] then
		PlayAnim(Config.OnUse[item].anim[1], Config.OnUse[item].anim[2], Config.OnUse[item].time, Config.OnUse[item].anim[3])
		Wait(Config.OnUse[item].time)
	end

	for k,v in pairs(todo) do
		if v.type == "clothes" then
			if v.second then
				SetPedComponentVariation(Ped, v.component, data[v.name], data[v.second.name], 0)
			else
				SetPedComponentVariation(Ped, v.component, data[v.name], 0, 0)
			end
		elseif v.type == "props" then
			ClearPedProp(Ped, v.component)
			if v.second then
				SetPedPropIndex(Ped, v.component, data[v.name], data[v.second.name], true)
			else
				SetPedPropIndex(Ped, v.component, data[v.name], 0, true)
			end
		end
	end
end)
