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

print("------------------------------------------------------")
print("")
print("                    	|Police Job      |")
print("                    	|By: Bxnny | V:1 |")
print("")
print("------------------------------------------------------")


---------------------------------------------------------------------------------------------------------------------------------------------------------
-- [AI SPEEDZONE]
---------------------------------------------------------------------------------------------------------------------------------------------------------
-- By: Jacooob | V1 | Coms.lua | Client
---------------------------------------------------------------------------------------------------------------------------------------------------------
-- [COMMAND]

RegisterCommand(Config.CommandName, function(source, args)
	local command = args[1]

	if command == Config.SlowZoneName then
		TriggerEvent('speedzone:ZoneSlow')

		if Config.EnableChatMsg then
			TriggerEvent('chat:addMessage', {
				color = Config.SenderColor,
				multiline = true,
				args = { Config.MessageSender .. Config.SlowMessage }
			})
		end
	elseif command == Config.StopZoneName then
		TriggerEvent('speedzone:ZoneStop')

		if Config.EnableChatMsg then
			TriggerEvent('chat:addMessage', {
				color = Config.SenderColor,
				multiline = true,
				args = { Config.MessageSender .. Config.StopMessage }
			})
		end
	elseif command == Config.ClearZoneName then
		TriggerEvent('speedzone:ZoneClear')

		if Config.EnableChatMsg then
			TriggerEvent('chat:addMessage', {
				color = Config.SenderColor,
				multiline = true,
				args = { Config.MessageSender .. Config.ClearMessage }
			})
		end
	end
end)

---------------------------------------------------------------------------------------------------------------------------------------------------------
-- [EVENTS]

RegisterNetEvent('speedzone:ZoneSlow')
AddEventHandler("speedzone:ZoneSlow", function(source)
	activateSlowSpeedZone()
end)

RegisterNetEvent('speedzone:ZoneStop')
AddEventHandler("speedzone:ZoneStop", function(source)
	activateStopSpeedZone()
end)

RegisterNetEvent('speedzone:ZoneClear')
AddEventHandler("speedzone:ZoneClear", function(source)
	clearActiveSpeedZones()
end)
---------------------------------------------------------------------------------------------------------------------------------------------------------
-- [SUGGESTION]

TriggerEvent('chat:addSuggestion', '/zone', 'Activates A SpeedZone', {
	{ name = "slow, stop, clear", help = "Activates/Deactivates A SpeedZone" }
})


---------------------------------------------------------------------------------------------------------------------------------------------------------
-- [AI SPEEDZONE]
---------------------------------------------------------------------------------------------------------------------------------------------------------
-- By: Jacooob | V1 | Main.lua | Client
---------------------------------------------------------------------------------------------------------------------------------------------------------
-- [LOCAL VARIABLES]

-- Limit To Active Zones
local zoneLimit = 1

-- Amount Of Active Zones (Will Break If >0 )
local activeZones = 0

-- Zone Table
local zones = {}

-- Speed Zone Node And Blip Variables
local blip = nil
local speedzone = nil

local radus = 50.0
---------------------------------------------------------------------------------------------------------------------------------------------------------
-- [NOTIFY FUNCTION]
-- Function To Display Notification
function notify(msg)
	SetNotificationTextEntry("STRING")
	AddTextComponentString(msg)
	DrawNotification(true, false)
end

---------------------------------------------------------------------------------------------------------------------------------------------------------
-- [ZONE FUNCTIONS]

-- Slow Zone
function activateSlowSpeedZone()
	local player = GetPlayerPed(-1)
	local playerPos = GetEntityCoords(player)

	zones[activeZones] = blip
	activeZones = activeZones + 1

	if (activeZones <= zoneLimit) then
		print(radus)
		speedzone = AddRoadNodeSpeedZone(playerPos.x, playerPos.y, playerPos.z, radus, Config.SlowZoneSpeed, true)
		blip = AddBlipForRadius(playerPos.x, playerPos.y, playerPos.z, radus)
		SetBlipAlpha(blip, Config.BlipAlpha)
		SetBlipColour(blip, Config.BlipColorSlow)

		if Config.EnableNotifications then
			notify(Config.ZoneSlowNotify)
		end
	elseif (activeZones > zoneLimit) then
		if Config.EnableNotifications then
			notify(Config.LimitErrorNotify)
		end
	end
end

-- Stop Zone
function activateStopSpeedZone()
	local player = GetPlayerPed(-1)
	local playerPos = GetEntityCoords(player)

	zones[activeZones] = blip
	activeZones = activeZones + 1

	if (activeZones <= zoneLimit) then
		print(radus)
		speedzone = AddRoadNodeSpeedZone(playerPos.x, playerPos.y, playerPos.z, radus, 0.0, true)
		blip = AddBlipForRadius(playerPos.x, playerPos.y, playerPos.z, radus)
		SetBlipAlpha(blip, Config.BlipAlpha)
		SetBlipColour(blip, Config.BlipColorStop)
		print(radus)

		if Config.EnableNotifications then
			notify(Config.ZoneStopNotify)
		end
	elseif (activeZones > zoneLimit) then
		if Config.EnableNotifications then
			notify(Config.LimitErrorNotify)
		end
	end
end

-- Clear Zone
function clearActiveSpeedZones()
	RemoveBlip(blip)
	RemoveRoadNodeSpeedZone(speedzone)
	activeZones = 0
	speedzone = nil
	zoneBlip = nil

	if Config.EnableNotifications then
		notify(Config.ZoneClearNotify)
	end
end

local CurrentActionData, handcuffTimer, dragStatus, blipsCops, currentTask = {}, {}, {}, {}, {}
local HasAlreadyEnteredMarker, isDead, isHandcuffed, hasAlreadyJoined, playerInService = false, false, false, false,
	false
local LastStation, LastPart, LastPartNum, LastEntity, CurrentAction, CurrentActionMsg
dragStatus.isDragged, isInShopMenu = false, false
ESX = exports["es_extended"]:getSharedObject()

Citizen.CreateThread(function()
	while ESX.GetPlayerData().job == nil do
		Citizen.Wait(10)
	end

	ESX.PlayerData = ESX.GetPlayerData()
end)

function cleanPlayer(playerPed)
	SetPedArmour(playerPed, 0)
	ClearPedBloodDamage(playerPed)
	ResetPedVisibleDamage(playerPed)
	ClearPedLastWeaponDamage(playerPed)
	ResetPedMovementClipset(playerPed, 0)
end

function setUniform(uniform, playerPed)
	TriggerEvent('skinchanger:getSkin', function(skin)
		local uniformObject

		if skin.sex == 0 then
			uniformObject = Config.Uniforms[uniform].male
		else
			uniformObject = Config.Uniforms[uniform].female
		end

		if uniformObject then
			TriggerEvent('skinchanger:loadClothes', skin, uniformObject)

			if uniform == 'bullet_wear' or uniform == 'bullet_wear_2' or uniform == 'bullet_wear_3' or uniform == 'bullet_wear_4' or uniform == 'bullet_wear_5' then
				SetPedArmour(playerPed, 100)
			end
		else
			ESX.ShowNotification(_U('no_outfit'))
		end
	end)
end

function OpenCloakroomMenu()
	local playerPed = PlayerPedId()
	local grade = ESX.PlayerData.job.grade_name

	local elements = {
		{ unselectable = true,   icon = "fas fa-shirt",                  title = TranslateCap("cloakroom") },
		{ icon = "fas fa-shirt", title = TranslateCap('citizen_wear'),   value = 'citizen_wear' },
		{ icon = "fas fa-shirt", title = TranslateCap('police_wear'),    uniform = grade },
		{ icon = "fas fa-shirt", title = TranslateCap('body_radio_cam'), uniform = 'body_radio_cam' },
		{ icon = "fas fa-shirt", title = TranslateCap('gilet_wear'),     uniform = 'gilet_wear' },
		{ icon = "fas fa-shirt", title = TranslateCap('bullet_wear'),    uniform = 'bullet_wear' },
		{ icon = "fas fa-shirt", title = TranslateCap('bullet_wear_2'),  uniform = 'bullet_wear_2' },
		{ icon = "fas fa-shirt", title = TranslateCap('bullet_wear_3'),  uniform = 'bullet_wear_3' },
		{ icon = "fas fa-shirt", title = TranslateCap('bullet_wear_4'),  uniform = 'bullet_wear_4' },
		{ icon = "fas fa-shirt", title = TranslateCap('bullet_wear_5'),  uniform = 'bullet_wear_5' },
	}

	if Config.EnableCustomPeds then
		for k, v in ipairs(Config.CustomPeds.shared) do
			elements[#elements + 1] = {
				icon = "fas fa-shirt",
				title = v.label,
				value = 'freemode_ped',
				maleModel = v.maleModel,
				femaleModel = v.femaleModel
			}
		end

		for k, v in ipairs(Config.CustomPeds[grade]) do
			elements[#elements + 1] = {
				icon = "fas fa-shirt",
				title = v.label,
				value = 'freemode_ped',
				maleModel = v.maleModel,
				femaleModel = v.femaleModel
			}
		end
	end

	ESX.OpenContext("right", elements, function(menu, element)
		cleanPlayer(playerPed)
		local data = { current = element }

		if data.current.value == 'citizen_wear' then
			if Config.EnableCustomPeds then
				ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
					local isMale = skin.sex == 0

					TriggerEvent('skinchanger:loadDefaultModel', isMale, function()
						ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
							TriggerEvent('skinchanger:loadSkin', skin)
							TriggerEvent('esx:restoreLoadout')
						end)
					end)
				end)
			else
				ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
					TriggerEvent('skinchanger:loadSkin', skin)
				end)
			end

			if Config.EnableESXService then
				ESX.TriggerServerCallback('esx_service:isInService', function(isInService)
					if isInService then
						playerInService = false

						local notification = {
							title    = TranslateCap('service_anonunce'),
							subject  = '',
							msg      = TranslateCap('service_out_announce', GetPlayerName(PlayerId())),
							iconType = 1
						}

						TriggerServerEvent('esx_service:notifyAllInService', notification, 'police')

						TriggerServerEvent('esx_service:disableService', 'police')
						TriggerEvent('esx_policejob:updateBlip')
						ESX.ShowNotification(TranslateCap('service_out'))
					end
				end, 'police')
			end
		end

		if Config.EnableESXService and data.current.value ~= 'citizen_wear' then
			local awaitService

			ESX.TriggerServerCallback('esx_service:isInService', function(isInService)
				if not isInService then
					if Config.MaxInService ~= -1 then
						ESX.TriggerServerCallback('esx_service:enableService',
							function(canTakeService, maxInService, inServiceCount)
								if not canTakeService then
									ESX.ShowNotification(TranslateCap('service_max', inServiceCount, maxInService))
								else
									awaitService = true
									playerInService = true

									local notification = {
										title    = TranslateCap('service_anonunce'),
										subject  = '',
										msg      = TranslateCap('service_in_announce', GetPlayerName(PlayerId())),
										iconType = 1
									}

									TriggerServerEvent('esx_service:notifyAllInService', notification, 'police')
									TriggerEvent('esx_policejob:updateBlip')
									ESX.ShowNotification(TranslateCap('service_in'))
								end
							end, 'police')
					else
						awaitService = true
						playerInService = true

						local notification = {
							title    = TranslateCap('service_anonunce'),
							subject  = '',
							msg      = TranslateCap('service_in_announce', GetPlayerName(PlayerId())),
							iconType = 1
						}

						TriggerServerEvent('esx_service:notifyAllInService', notification, 'police')
						TriggerEvent('esx_policejob:updateBlip')
						ESX.ShowNotification(TranslateCap('service_in'))
					end
				else
					awaitService = true
				end
			end, 'police')

			while awaitService == nil do
				Wait(0)
			end

			-- if we couldn't enter service don't let the player get changed
			if not awaitService then
				return
			end
		end

		if data.current.uniform then
			setUniform(data.current.uniform, playerPed)
		elseif data.current.value == 'freemode_ped' then
			local modelHash

			ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
				if skin.sex == 0 then
					modelHash = joaat(data.current.maleModel)
				else
					modelHash = joaat(data.current.femaleModel)
				end

				ESX.Streaming.RequestModel(modelHash, function()
					SetPlayerModel(PlayerId(), modelHash)
					SetModelAsNoLongerNeeded(modelHash)
					SetPedDefaultComponentVariation(PlayerPedId())

					TriggerEvent('esx:restoreLoadout')
				end)
			end)
		end
	end, function(menu)
		CurrentAction     = 'menu_cloakroom'
		CurrentActionMsg  = TranslateCap('open_cloackroom')
		CurrentActionData = {}
	end)
end

function OpenArmoryMenu(station)
	local elements = {
		{ label = _U('buy_weapons'), value = 'buy_weapons' }
	}

	if Config.EnableArmoryManagement then
		table.insert(elements, { label = _U('get_weapon'), value = 'get_weapon' })
		table.insert(elements, { label = _U('put_weapon'), value = 'put_weapon' })
		table.insert(elements, { label = _U('remove_object'), value = 'get_stock' })
		table.insert(elements, { label = _U('deposit_object'), value = 'put_stock' })
	end

	ESX.UI.Menu.CloseAll()

	ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory', {
		title    = _U('armory'),
		align    = 'top-left',
		elements = elements
	}, function(data, menu)
		if data.current.value == 'get_weapon' then
			OpenGetWeaponMenu()
		elseif data.current.value == 'put_weapon' then
			OpenPutWeaponMenu()
		elseif data.current.value == 'buy_weapons' then
			OpenBuyWeaponsMenu()
		elseif data.current.value == 'put_stock' then
			OpenPutStocksMenu()
		elseif data.current.value == 'get_stock' then
			OpenGetStocksMenu()
		end
	end, function(data, menu)
		menu.close()

		CurrentAction     = 'menu_armory'
		CurrentActionMsg  = _U('open_armory')
		CurrentActionData = { station = station }
	end)
end


function OpenPoliceActionsMenu()
	ESX.UI.Menu.CloseAll()

	local elements = {}
	
	if Config.Grappler and Config.Pepperspray then
		elements = {
			{ label = _U('citizen_interaction'),  value = 'citizen_interaction' },
			{ label = _U('vehicle_interaction'),  value = 'vehicle_interaction' },
			{ label = _U('object_spawner'),       value = 'object_spawner' },
			{ label = _U('speed_zone'),           value = 'speed_zone_menu' },
			{ label = _U('grappler_interaction'), value = 'grappler_interaction' },
			{ label = _U('pepperspray_interaction'), value = 'pepperspray_interaction' },
		}
	elseif Config.Grappler then
		elements = {
			{ label = _U('citizen_interaction'),  value = 'citizen_interaction' },
			{ label = _U('vehicle_interaction'),  value = 'vehicle_interaction' },
			{ label = _U('object_spawner'),       value = 'object_spawner' },
			{ label = _U('speed_zone'),           value = 'speed_zone_menu' },
			{ label = _U('grappler_interaction'), value = 'grappler_interaction' },
		}
	elseif Config.Pepperspray then
		elements = {
			{ label = _U('citizen_interaction'),  value = 'citizen_interaction' },
			{ label = _U('vehicle_interaction'),  value = 'vehicle_interaction' },
			{ label = _U('object_spawner'),       value = 'object_spawner' },
			{ label = _U('speed_zone'),           value = 'speed_zone_menu' },
			{ label = _U('pepperspray_interaction'), value = 'pepperspray_interaction' },
		}
	else
		elements = {
			{ label = _U('citizen_interaction'),  value = 'citizen_interaction' },
			{ label = _U('vehicle_interaction'),  value = 'vehicle_interaction' },
			{ label = _U('object_spawner'),       value = 'object_spawner' },
			{ label = _U('speed_zone'),           value = 'speed_zone_menu' },
		}
	end

	ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'police_actions', {
		title    = 'Police',
		align    = 'top-left',
		elements = elements,

	}, function(data, menu)
		if data.current.value == 'citizen_interaction' then
			local elements = {
				{ label = _U('id_card'),         value = 'identity_card' },
				{ label = _U('search'),          value = 'search' },
				{ label = _U('handcuff'),        value = 'handcuff' },
				{ label = _U('drag'),            value = 'drag' },
				{ label = _U('put_in_vehicle'),  value = 'put_in_vehicle' },
				{ label = _U('out_the_vehicle'), value = 'out_the_vehicle' },
				{ label = _U('fine'),            value = 'fine' },
				{ label = _U('unpaid_bills'),    value = 'unpaid_bills' }
			}

			if Config.EnableLicenses then
				table.insert(elements, { label = _U('license_check'), value = 'license' })
			end

			ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
				title    = _U('citizen_interaction'),
				align    = 'top-left',
				elements = elements
			}, function(data2, menu2)
				local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
				if closestPlayer ~= -1 and closestDistance <= 3.0 then
					local action = data2.current.value

					if action == 'identity_card' then
						OpenIdentityCardMenu(closestPlayer)
					elseif action == 'search' then
						OpenBodySearchMenu(closestPlayer)
					elseif action == 'handcuff' then
						TriggerServerEvent('esx_policejob:handcuff', GetPlayerServerId(closestPlayer))
					elseif action == 'drag' then
						TriggerServerEvent('esx_policejob:drag', GetPlayerServerId(closestPlayer))
					elseif action == 'put_in_vehicle' then
						TriggerServerEvent('esx_policejob:putInVehicle', GetPlayerServerId(closestPlayer))
					elseif action == 'out_the_vehicle' then
						TriggerServerEvent('esx_policejob:OutVehicle', GetPlayerServerId(closestPlayer))
					elseif action == 'fine' then
						OpenFineMenu(closestPlayer)
					elseif action == 'license' then
						ShowPlayerLicense(closestPlayer)
					elseif action == 'unpaid_bills' then
						OpenUnpaidBillsMenu(closestPlayer)
					end
				else
					ESX.ShowNotification(_U('no_players_nearby'))
				end
			end, function(data2, menu2)
				menu2.close()
			end)
		elseif data.current.value == 'vehicle_interaction' then
			local elements  = {}
			local playerPed = PlayerPedId()
			local vehicle   = ESX.Game.GetVehicleInDirection()

			if DoesEntityExist(vehicle) then
				table.insert(elements, { label = _U('vehicle_info'), value = 'vehicle_infos' })
				table.insert(elements, { label = _U('pick_lock'), value = 'hijack_vehicle' })
				table.insert(elements, { label = _U('impound'), value = 'impound' })
			end

			table.insert(elements, { label = _U('search_database'), value = 'search_database' })

			ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_interaction', {
				title    = _U('vehicle_interaction'),
				align    = 'top-left',
				elements = elements
			}, function(data2, menu2)
				local coords = GetEntityCoords(playerPed)
				vehicle      = ESX.Game.GetVehicleInDirection()
				action       = data2.current.value

				if action == 'search_database' then
					LookupVehicle()
				elseif DoesEntityExist(vehicle) then
					if action == 'vehicle_infos' then
						local vehicleData = ESX.Game.GetVehicleProperties(vehicle)
						OpenVehicleInfosMenu(vehicleData)
					elseif action == 'hijack_vehicle' then
						if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 3.0) then
							TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_WELDING', 0, true)
							Citizen.Wait(20000)
							ClearPedTasksImmediately(playerPed)

							SetVehicleDoorsLocked(vehicle, 1)
							SetVehicleDoorsLockedForAllPlayers(vehicle, false)
							ESX.ShowNotification(_U('vehicle_unlocked'))
						end
					elseif action == 'impound' then
						-- is the script busy?
						if currentTask.busy then
							return
						end

						ESX.ShowHelpNotification(_U('impound_prompt'))
						TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true)

						currentTask.busy = true
						currentTask.task = ESX.SetTimeout(10000, function()
							ClearPedTasks(playerPed)
							ImpoundVehicle(vehicle)
							Citizen.Wait(100) -- sleep the entire script to let stuff sink back to reality
						end)

						-- keep track of that vehicle!
						Citizen.CreateThread(function()
							while currentTask.busy do
								Citizen.Wait(1000)

								vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71)
								if not DoesEntityExist(vehicle) and currentTask.busy then
									ESX.ShowNotification(_U('impound_canceled_moved'))
									ESX.ClearTimeout(currentTask.task)
									ClearPedTasks(playerPed)
									currentTask.busy = false
									break
								end
							end
						end)
					end
				else
					ESX.ShowNotification(_U('no_vehicles_nearby'))
				end
			end, function(data2, menu2)
				menu2.close()
			end)
		elseif data.current.value == 'object_spawner' then
			ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
				title    = _U('traffic_interaction'),
				align    = 'top-left',
				elements = {
					{ label = _U('cone'),                              model = 'prop_roadcone02a' },
					{ label = _U('barrier'),                           model = 'prop_barrier_work05' },
					{ label = _U('spikestrips'),                       model = 'p_ld_stinger_s' },
					{ label = _U('box'),                               model = 'prop_boxpile_07d' },
					{ label = _U('cash'),                              model = 'hei_prop_cash_crate_half_full' },
					{ label = 'Flagger Paddle',                        model = 'prop_flagger_sign_01' },
					{ label = 'Scene Lights',                          model = 'prop_worklight_03b' },
					{ label = 'Large Striped Cone',                    model = 'prop_roadcone01a' },
					{ label = 'Large Cone',                            model = 'prop_roadcone01c' },
					{ label = 'Medium Striped Cone',                   model = 'prop_roadcone02a' },
					{ label = 'Medium Cone',                           model = 'prop_roadcone02c' },
					{ label = 'Delineator',                            model = 'prop_mp_cone_04' },
					{ label = 'Road Work Flag',                        model = 'prop_consign_flag_01' },
					{ label = 'Work Crew Flag',                        model = 'prop_consign_flag_21' },
					{ label = 'Utility Work Flag',                     model = 'prop_consign_flag_18' },
					{ label = 'Shoulder Work Flag',                    model = 'prop_consign_flag_19' },
					{ label = 'Right Lane Closed Flag',                model = 'prop_consign_flag_02' },
					{ label = 'Left Lane Closed Flag',                 model = 'prop_consign_flag_03' },
					{ label = 'Right Lane Ends Flag',                  model = 'prop_consign_flag_04' },
					{ label = 'Left Lane Ends Flag',                   model = 'prop_consign_flag_05' },
					{ label = 'Keep Left Flag',                        model = 'prop_consign_flag_13' },
					{ label = 'Keep Right Flag',                       model = 'prop_consign_flag_14' },
					{ label = 'Flagger Ahead Flag',                    model = 'prop_consign_flag_08' },
					{ label = 'Flagger Symbol Flag',                   model = 'prop_consign_flag_06' },
					{ label = 'Prepare to Stop Flag',                  model = 'prop_consign_flag_07' },
					{ label = 'Road Closed Ahead Flag',                model = 'prop_consign_flag_10' },
					{ label = 'Road Closed Flag',                      model = 'prop_consign_flag_09' },
					{ label = 'Detour Ahead Flag',                     model = 'prop_consign_flag_25' },
					{ label = 'Detour Left/Right Flag',                model = 'prop_consign_flag_26' },
					{ label = 'Detour Left Flag',                      model = 'prop_consign_flag_27' },
					{ label = 'Detour Right Flag',                     model = 'prop_consign_flag_28' },
					{ label = 'Detour Straight Flag',                  model = 'prop_consign_flag_29' },
					{ label = 'Traffic Incident Flag',                 model = 'prop_consign_flag_11' },
					{ label = 'Emergency Scene Flag',                  model = 'prop_consign_flag_22' },
					{ label = 'Road Flooded Flag',                     model = 'prop_consign_flag_15' },
					{ label = 'Fire Activity Flag',                    model = 'prop_consign_flag_16' },
					{ label = 'Tow Truck Flag',                        model = 'prop_consign_flag_17' },
					{ label = 'Check Point Flag',                      model = 'prop_consign_flag_12' },
					{ label = 'Pilot Car Flag',                        model = 'prop_consign_flag_23' },
					{ label = 'Fines Doubled Flag',                    model = 'prop_consign_flag_24' },
					{ label = 'Mower Ahead Flag',                      model = 'prop_consign_flag_20' },
					{ label = 'Slow Flag',                             model = 'prop_consign_flag_30' },
					{ label = 'Stop Flag',                             model = 'prop_consign_flag_stop' },
					{ label = 'custom Flag',                           model = 'prop_consign_flag_custom' },
					{ label = 'Road Work Barrier',                     model = 'prop_barrier_sign_01' },
					{ label = 'Work Crew Barrier',                     model = 'prop_barrier_sign_21' },
					{ label = 'Utility Work Barrier',                  model = 'prop_barrier_sign_18' },
					{ label = 'Shoulder Work Barrier',                 model = 'prop_barrier_sign_19' },
					{ label = 'Right Lane Closed Barrier',             model = 'prop_barrier_sign_02' },
					{ label = 'Left Lane Closed Barrier',              model = 'prop_barrier_sign_03' },
					{ label = 'Right Lane Ends Barrier',               model = 'prop_barrier_sign_04' },
					{ label = 'Left Lane Ends Barrier',                model = 'prop_barrier_sign_05' },
					{ label = 'Keep Left Barrier',                     model = 'prop_barrier_sign_13' },
					{ label = 'Keep Right Barrier',                    model = 'prop_barrier_sign_14' },
					{ label = 'Flagger Ahead Barrier',                 model = 'prop_barrier_sign_08' },
					{ label = 'Flagger Symbol Barrier',                model = 'prop_barrier_sign_06' },
					{ label = 'Prepare to Stop Barrier',               model = 'prop_barrier_sign_07' },
					{ label = 'Road Closed Ahead Barrier',             model = 'prop_barrier_sign_10' },
					{ label = 'Road Closed Barrier',                   model = 'prop_barrier_sign_09' },
					{ label = 'Detour Ahead Barrier',                  model = 'prop_barrier_sign_25' },
					{ label = 'Detour Arrow Barricade',                model = 'prop_barrier_sign_detour' },
					{ label = 'Detour Left/Right Barrier',             model = 'prop_barrier_sign_26' },
					{ label = 'Detour Left Barrier',                   model = 'prop_barrier_sign_27' },
					{ label = 'Detour Right Barrier',                  model = 'prop_barrier_sign_28' },
					{ label = 'Detour Straight Barrier',               model = 'prop_barrier_sign_29' },
					{ label = 'Traffic Incident Barrier',              model = 'prop_barrier_sign_11' },
					{ label = 'Emergency Scene Barrier',               model = 'prop_barrier_sign_22' },
					{ label = 'Road Flooded Barrier',                  model = 'prop_barrier_sign_15' },
					{ label = 'Fire Activity Barrier',                 model = 'prop_barrier_sign_16' },
					{ label = 'Tow Truck Barrier',                     model = 'prop_barrier_sign_17' },
					{ label = 'Check Point Barrier',                   model = 'prop_barrier_sign_12' },
					{ label = 'Pilot Car Barrier',                     model = 'prop_barrier_sign_23' },
					{ label = 'Fines Doubled Barrier',                 model = 'prop_barrier_sign_24' },
					{ label = 'Mower Ahead Barrier',                   model = 'prop_barrier_sign_20' },
					{ label = 'Slow Barrier',                          model = 'prop_barrier_sign_30' },
					{ label = 'Custom Barrier',                        model = 'prop_barrier_sign_custom' },
					{ label = 'Stop Barrier',                          model = 'prop_barrier_sign_stop' },
					{ label = 'Police Barricade',                      model = 'prop_barrier_work05' },
					{ label = 'Striped Barricade',                     model = 'prop_barrier_work06a' },
					{ label = 'Road Work Barricade',                   model = 'prop_barrier_work06b' },
					{ label = 'Street Closed Barricade',               model = 'prop_barrier_work06c' },
					{ label = 'Sidewalk Closed Barricade',             model = 'prop_barrier_work06d' },
					{ label = 'Road Barrel w/ Base',                   model = 'prop_barrier_wat_03a' },
					{ label = 'Road Barrel',                           model = 'prop_barrier_wat_03b' },
					{ label = 'Small Barricade',                       model = 'prop_barrier_work01a' },
					{ label = 'Small Barricade w/ Light',              model = 'prop_barrier_work02a' },
					{ label = 'Road Work Type-III Barricade',          model = 'prop_barrier_work04a' },
					{ label = 'Type-III Barricade (Left)',             model = 'prop_barrier_work04b' },
					{ label = 'Type-III Barricade (Right)',            model = 'prop_barrier_work04br' },
					{ label = 'Type-III Barricade (Left w/ lights)',   model = 'prop_barrier_work04c' },
					{ label = 'Type-III Barricade (Right w/ lights)',  model = 'prop_barrier_work04cr' },
					{ label = 'Type-III Road Closed (Left)',           model = 'prop_barrier_work04dx' },
					{ label = 'Type-III Road Closed (Right)',          model = 'prop_barrier_work04drx' },
					{ label = 'Type-III Road Closed (Left w/ lights)', model = 'prop_barrier_work04d' },
					{ label = 'Type-III Road Closed (Right w/ light)', model = 'prop_barrier_work04dr' },
					{ label = 'Type-III Detour (Left)',                model = 'prop_barrier_work04ex' },
					{ label = 'Type-III Detour (Right)',               model = 'prop_barrier_work04erx' },
					{ label = 'Type-III Detour (Left w/ lights)',      model = 'prop_barrier_work04e' },
					{ label = 'Type-III Detour (Right w/ lights)',     model = 'prop_barrier_work04er' },
					{ label = 'Left Arrow Board',                      model = 'prop_trafficdiv_01' },
					{ label = 'Right Arrow Board',                     model = 'prop_trafficdiv_02' }
				}
			}, function(data2, menu2)
				local playerPed = PlayerPedId()
				local coords, forward = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed)
				local objectCoords = (coords + forward * 1.0)

				ESX.Game.SpawnObject(data2.current.model, objectCoords, function(obj)
					local playerRotation = GetEntityRotation(playerPed, 2)
					local objRotation = vec4(playerRotation.x, playerRotation.y, playerRotation.z + 90.0, 0.0) -- Anpassung der Ausrichtung um 90 Grad

					SetEntityQuaternion(obj, objRotation.x, objRotation.y, objRotation.z, objRotation.w)
					PlaceObjectOnGroundProperly(obj)
				end)
			end, function(data2, menu2)
				menu2.close()
			end)
		elseif data.current.value == 'speed_zone_menu' then
			function OpenSpeedZoneMenu()
				local elements = {
					{ label = "Zone-Größe",  name = "size",  value = 50, type = 'slider', min = 45, max = 250 },
					{ label = 'Langsame Zone', value = 'slow' },
					{ label = 'Stop-Zone',     value = 'stop' },
					{ label = 'Zone löschen', value = 'clear' },
				}

				ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'speed_zone_menu', {
					title = 'SpeedZone-Menü',
					align = 'top-left',
					elements = elements
				}, function(data, menu)
					local zoneType = data.current

					if zoneType.name == 'size' then
						radus = zoneType.value + .0
						print("Zone-Größe geändert zu " .. zoneType.value)
						if zoneType.value == 69 then
							print("Hööömmmaaaaaaa")
						end

						if zoneType.value == 7 or zoneType.value == 14 then
							print("Du bist n cooler Dude")
						end

						-- Füge hier den Code hinzu, um die langsame Zone zu erstellen
					end

					if zoneType.value == 'slow' then
						print("SlwoZone erstellt")
						TriggerEvent('speedzone:ZoneSlow')
						-- Füge hier den Code hinzu, um die langsame Zone zu erstellen
					elseif zoneType.value == 'stop' then
						print("Stop-Zone erstellt")
						TriggerEvent('speedzone:ZoneStop')
						-- Füge hier den Code hinzu, um die Stop-Zone zu erstellen
					elseif zoneType.value == 'clear' then
						print("Zonen Gelöscht")
						TriggerEvent('speedzone:ZoneClear')
						-- Füge hier den Code hinzu, um die Zone zu löschen
					end
				end, function(data, menu)
					menu.close()
				end)
			end

			OpenSpeedZoneMenu()
		elseif data.current.value == 'grappler_interaction' then
			function OpenGrapplerMenu()
				local elements = {
					{ label = 'Grappler - Installieren',  name = 'install' },
					{ label = 'Grappler - Entfernen',     name = 'remove' },
					{ label = 'Grappler - Zurücksetzen', name = 'reset' },
					{ label = 'Grappler-Ausfahren mit Z', name = 'deploy' }
				}

				ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'speed_zone_menu', {
					title = 'Grappler-Menü',
					align = 'top-left',
					elements = elements
				}, function(data, menu)
					local grappler_select = data.current

					if grappler_select.name == 'install' then
						print("Grabbler wurde Installiert")
						ExecuteCommand("grappler install")
					elseif grappler_select.name == 'remove' then
						print("Grabbler wurde Entfernt")
						ExecuteCommand("grappler remove")
					elseif grappler_select.name == 'reset' then
						print("Grabbler wurde Zurückgesetzt")
						ExecuteCommand("grappler reset")
					end
				end, function(data, menu)
					menu.close()
				end)
			end

			OpenGrapplerMenu()
		elseif data.current.value == 'pepperspray_interaction' then
			function OpenPepperMenu()
				local elements = {
					{ label = 'Pfefferspray - Bekommen',  name = 'getpepper' },
				}

				ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'speed_zone_menu', {
					title = 'Pfefferspray-Menü',
					align = 'top-left',
					elements = elements
				}, function(data, menu)
					local grappler_select = data.current

					if grappler_select.name == 'getpepper' then
						print("Pfefferspray wurde gegeben")
						ExecuteCommand("pepperspray")
					end
				end, function(data, menu)
					menu.close()
				end)
			end

			OpenPepperMenu()
		end
	end, function(data, menu)
		menu.close()
	end)
end



function OpenIdentityCardMenu(player)
	ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data)
		local elements = {
			{ label = _U('name', data.name) },
			{ label = _U('job', ('%s - %s'):format(data.job, data.grade)) }
		}

		if Config.EnableESXIdentity then
			table.insert(elements, { label = _U('sex', _U(data.sex)) })
			table.insert(elements, { label = _U('dob', data.dob) })
			table.insert(elements, { label = _U('height', data.height) })
		end

		if data.drunk then
			table.insert(elements, { label = _U('bac', data.drunk) })
		end

		if data.licenses then
			table.insert(elements, { label = _U('license_label') })

			for i = 1, #data.licenses, 1 do
				table.insert(elements, { label = data.licenses[i].label })
			end
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
			title    = _U('citizen_interaction'),
			align    = 'top-left',
			elements = elements
		}, nil, function(data, menu)
			menu.close()
		end)
	end, GetPlayerServerId(player))
end

function grabdna(player)
	local player, distance = ESX.Game.GetClosestPlayer()

	if distance ~= -1 and distance <= 3.0 then
		TriggerEvent('jsfour-dna:get', player)
	end

	-- There's also a remove event which could be added to a menu or something..
	TriggerEvent('jsfour-dna:remove')
end

function OpenBodySearchMenu(player)
	ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data)
		local elements = {}

		for i = 1, #data.accounts, 1 do
			if data.accounts[i].name == 'black_money' and data.accounts[i].money > 0 then
				table.insert(elements, {
					label    = _U('confiscate_dirty', ESX.Math.Round(data.accounts[i].money)),
					value    = 'black_money',
					itemType = 'item_account',
					amount   = data.accounts[i].money
				})

				break
			end
		end

		table.insert(elements, { label = _U('guns_label') })

		for i = 1, #data.weapons, 1 do
			table.insert(elements, {
				label    = _U('confiscate_weapon', ESX.GetWeaponLabel(data.weapons[i].name), data.weapons[i].ammo),
				value    = data.weapons[i].name,
				itemType = 'item_weapon',
				amount   = data.weapons[i].ammo
			})
		end

		table.insert(elements, { label = _U('inventory_label') })

		for i = 1, #data.inventory, 1 do
			if data.inventory[i].count > 0 then
				table.insert(elements, {
					label    = _U('confiscate_inv', data.inventory[i].count, data.inventory[i].label),
					value    = data.inventory[i].name,
					itemType = 'item_standard',
					amount   = data.inventory[i].count
				})
			end
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'body_search', {
			title    = _U('search'),
			align    = 'top-left',
			elements = elements
		}, function(data, menu)
			if data.current.value then
				TriggerServerEvent('esx_policejob:confiscatePlayerItem', GetPlayerServerId(player), data.current
					.itemType, data.current.value, data.current.amount)
				OpenBodySearchMenu(player)
			end
		end, function(data, menu)
			menu.close()
		end)
	end, GetPlayerServerId(player))
end

function OpenFineMenu(player)
	ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine', {
		title    = _U('fine'),
		align    = 'top-left',
		elements = {
			{ label = _U('traffic_offense'), value = 0 },
			{ label = _U('minor_offense'),   value = 1 },
			{ label = _U('average_offense'), value = 2 },
			{ label = _U('major_offense'),   value = 3 }
		}
	}, function(data, menu)
		OpenFineCategoryMenu(player, data.current.value)
	end, function(data, menu)
		menu.close()
	end)
end

function OpenFineCategoryMenu(player, category)
	ESX.TriggerServerCallback('esx_policejob:getFineList', function(fines)
		local elements = {}

		for k, fine in ipairs(fines) do
			table.insert(elements, {
				label     = ('%s <span style="color:green;">%s</span>'):format(fine.label,
					_U('armory_item', ESX.Math.GroupDigits(fine.amount))),
				value     = fine.id,
				amount    = fine.amount,
				fineLabel = fine.label
			})
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine_category', {
			title    = _U('fine'),
			align    = 'top-left',
			elements = elements
		}, function(data, menu)
			menu.close()

			if Config.EnablePlayerManagement then
				TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), 'society_police',
					_U('fine_total', data.current.fineLabel), data.current.amount)
			else
				TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), '',
					_U('fine_total', data.current.fineLabel), data.current.amount)
			end

			ESX.SetTimeout(300, function()
				OpenFineCategoryMenu(player, category)
			end)
		end, function(data, menu)
			menu.close()
		end)
	end, category)
end

function LookupVehicle()
	ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'lookup_vehicle', {
		title = _U('search_database_title'),
	}, function(data, menu)
		local length = string.len(data.value)
		if not data.value or length < 2 or length > 8 then
			ESX.ShowNotification(_U('search_database_error_invalid'))
		else
			ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo)
				local elements = { { label = _U('plate', retrivedInfo.plate) } }
				menu.close()

				if not retrivedInfo.owner then
					table.insert(elements, { label = _U('owner_unknown') })
				else
					table.insert(elements, { label = _U('owner', retrivedInfo.owner) })
				end

				ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', {
					title    = _U('vehicle_info'),
					align    = 'top-left',
					elements = elements
				}, nil, function(data2, menu2)
					menu2.close()
				end)
			end, data.value)
		end
	end, function(data, menu)
		menu.close()
	end)
end

function ShowPlayerLicense(player)
	local elements = {}

	ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(playerData)
		if playerData.licenses then
			for i = 1, #playerData.licenses, 1 do
				if playerData.licenses[i].label and playerData.licenses[i].type then
					table.insert(elements, {
						label = playerData.licenses[i].label,
						type = playerData.licenses[i].type
					})
				end
			end
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_license', {
			title    = _U('license_revoke'),
			align    = 'top-left',
			elements = elements,
		}, function(data, menu)
			ESX.ShowNotification(_U('licence_you_revoked', data.current.label, playerData.name))
			TriggerServerEvent('esx_policejob:message', GetPlayerServerId(player),
				_U('license_revoked', data.current.label))

			TriggerServerEvent('esx_license:removeLicense', GetPlayerServerId(player), data.current.type)

			ESX.SetTimeout(300, function()
				ShowPlayerLicense(player)
			end)
		end, function(data, menu)
			menu.close()
		end)
	end, GetPlayerServerId(player))
end

function OpenUnpaidBillsMenu(player)
	local elements = {}

	ESX.TriggerServerCallback('esx_billing:getTargetBills', function(bills)
		for k, bill in ipairs(bills) do
			table.insert(elements, {
				label = ('%s - <span style="color:red;">%s</span>'):format(bill.label,
					_U('armory_item', ESX.Math.GroupDigits(bill.amount))),
				billId = bill.id
			})
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', {
			title    = _U('unpaid_bills'),
			align    = 'top-left',
			elements = elements
		}, nil, function(data, menu)
			menu.close()
		end)
	end, GetPlayerServerId(player))
end

function OpenVehicleInfosMenu(vehicleData)
	ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo)
		local elements = { { label = _U('plate', retrivedInfo.plate) } }

		if not retrivedInfo.owner then
			table.insert(elements, { label = _U('owner_unknown') })
		else
			table.insert(elements, { label = _U('owner', retrivedInfo.owner) })
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', {
			title    = _U('vehicle_info'),
			align    = 'top-left',
			elements = elements
		}, nil, function(data, menu)
			menu.close()
		end)
	end, vehicleData.plate)
end

function OpenGetWeaponMenu()
	ESX.TriggerServerCallback('esx_policejob:getArmoryWeapons', function(weapons)
		local elements = {}

		for i = 1, #weapons, 1 do
			if weapons[i].count > 0 then
				table.insert(elements, {
					label = 'x' .. weapons[i].count .. ' ' .. ESX.GetWeaponLabel(weapons[i].name),
					value = weapons[i].name
				})
			end
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_get_weapon', {
			title    = _U('get_weapon_menu'),
			align    = 'top-left',
			elements = elements
		}, function(data, menu)
			menu.close()

			ESX.TriggerServerCallback('esx_policejob:removeArmoryWeapon', function()
				OpenGetWeaponMenu()
			end, data.current.value)
		end, function(data, menu)
			menu.close()
		end)
	end)
end

function OpenPutWeaponMenu()
	local elements   = {}
	local playerPed  = PlayerPedId()
	local weaponList = ESX.GetWeaponList()

	for i = 1, #weaponList, 1 do
		local weaponHash = GetHashKey(weaponList[i].name)

		if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= 'WEAPON_UNARMED' then
			table.insert(elements, {
				label = weaponList[i].label,
				value = weaponList[i].name
			})
		end
	end

	ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_put_weapon', {
		title    = _U('put_weapon_menu'),
		align    = 'top-left',
		elements = elements
	}, function(data, menu)
		menu.close()

		ESX.TriggerServerCallback('esx_policejob:addArmoryWeapon', function()
			OpenPutWeaponMenu()
		end, data.current.value, true)
	end, function(data, menu)
		menu.close()
	end)
end

function OpenBuyWeaponsMenu()
	local elements = {}
	local playerPed = PlayerPedId()

	for k, v in ipairs(Config.AuthorizedWeapons[ESX.PlayerData.job.grade_name]) do
		local weaponNum, weapon = ESX.GetWeapon(v.weapon)
		local components, label = {}
		local hasWeapon = HasPedGotWeapon(playerPed, GetHashKey(v.weapon), false)

		if v.components then
			for i = 1, #v.components do
				if v.components[i] then
					local component = weapon.components[i]
					local hasComponent = HasPedGotWeaponComponent(playerPed, GetHashKey(v.weapon), component.hash)

					if hasComponent then
						label = ('%s: <span style="color:green;">%s</span>'):format(component.label, _U('armory_owned'))
					else
						if v.components[i] > 0 then
							label = ('%s: <span style="color:green;">%s</span>'):format(component.label,
								_U('armory_item', ESX.Math.GroupDigits(v.components[i])))
						else
							label = ('%s: <span style="color:green;">%s</span>'):format(component.label,
								_U('armory_free'))
						end
					end

					table.insert(components, {
						label = label,
						componentLabel = component.label,
						hash = component.hash,
						name = component.name,
						price = v.components[i],
						hasComponent = hasComponent,
						componentNum = i
					})
				end
			end
		end

		if hasWeapon and v.components then
			label = ('%s: <span style="color:green;">></span>'):format(weapon.label)
		elseif hasWeapon and not v.components then
			label = ('%s: <span style="color:green;">%s</span>'):format(weapon.label, _U('armory_owned'))
		else
			if v.price > 0 then
				label = ('%s: <span style="color:green;">%s</span>'):format(weapon.label,
					_U('armory_item', ESX.Math.GroupDigits(v.price)))
			else
				label = ('%s: <span style="color:green;">%s</span>'):format(weapon.label, _U('armory_free'))
			end
		end

		table.insert(elements, {
			label = label,
			weaponLabel = weapon.label,
			name = weapon.name,
			components = components,
			price = v.price,
			hasWeapon = hasWeapon
		})
	end

	ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_buy_weapons', {
		title    = _U('armory_weapontitle'),
		align    = 'top-left',
		elements = elements
	}, function(data, menu)
		if data.current.hasWeapon then
			if #data.current.components > 0 then
				OpenWeaponComponentShop(data.current.components, data.current.name, menu)
			end
		else
			ESX.TriggerServerCallback('esx_policejob:buyWeapon', function(bought)
				if bought then
					if data.current.price > 0 then
						ESX.ShowNotification(_U('armory_bought', data.current.weaponLabel,
							ESX.Math.GroupDigits(data.current.price)))
					end

					menu.close()
					OpenBuyWeaponsMenu()
				else
					ESX.ShowNotification(_U('armory_money'))
				end
			end, data.current.name, 1)
		end
	end, function(data, menu)
		menu.close()
	end)
end

function OpenWeaponComponentShop(components, weaponName, parentShop)
	ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_buy_weapons_components', {
		title    = _U('armory_componenttitle'),
		align    = 'top-left',
		elements = components
	}, function(data, menu)
		if data.current.hasComponent then
			ESX.ShowNotification(_U('armory_hascomponent'))
		else
			ESX.TriggerServerCallback('esx_policejob:buyWeapon', function(bought)
				if bought then
					if data.current.price > 0 then
						ESX.ShowNotification(_U('armory_bought', data.current.componentLabel,
							ESX.Math.GroupDigits(data.current.price)))
					end

					menu.close()
					parentShop.close()
					OpenBuyWeaponsMenu()
				else
					ESX.ShowNotification(_U('armory_money'))
				end
			end, weaponName, 2, data.current.componentNum)
		end
	end, function(data, menu)
		menu.close()
	end)
end

function OpenGetStocksMenu()
	ESX.TriggerServerCallback('esx_policejob:getStockItems', function(items)
		local elements = {}

		for i = 1, #items, 1 do
			table.insert(elements, {
				label = 'x' .. items[i].count .. ' ' .. items[i].label,
				value = items[i].name
			})
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', {
			title    = _U('police_stock'),
			align    = 'top-left',
			elements = elements
		}, function(data, menu)
			local itemName = data.current.value

			ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', {
				title = _U('quantity')
			}, function(data2, menu2)
				local count = tonumber(data2.value)

				if not count then
					ESX.ShowNotification(_U('quantity_invalid'))
				else
					menu2.close()
					menu.close()
					TriggerServerEvent('esx_policejob:getStockItem', itemName, count)

					Citizen.Wait(300)
					OpenGetStocksMenu()
				end
			end, function(data2, menu2)
				menu2.close()
			end)
		end, function(data, menu)
			menu.close()
		end)
	end)
end

function OpenPutStocksMenu()
	ESX.TriggerServerCallback('esx_policejob:getPlayerInventory', function(inventory)
		local elements = {}

		for i = 1, #inventory.items, 1 do
			local item = inventory.items[i]

			if item.count > 0 then
				table.insert(elements, {
					label = item.label .. ' x' .. item.count,
					type = 'item_standard',
					value = item.name
				})
			end
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', {
			title    = _U('inventory'),
			align    = 'top-left',
			elements = elements
		}, function(data, menu)
			local itemName = data.current.value

			ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', {
				title = _U('quantity')
			}, function(data2, menu2)
				local count = tonumber(data2.value)

				if not count then
					ESX.ShowNotification(_U('quantity_invalid'))
				else
					menu2.close()
					menu.close()
					TriggerServerEvent('esx_policejob:putStockItems', itemName, count)

					Citizen.Wait(300)
					OpenPutStocksMenu()
				end
			end, function(data2, menu2)
				menu2.close()
			end)
		end, function(data, menu)
			menu.close()
		end)
	end)
end

RegisterNetEvent('esx:setJob')
AddEventHandler('esx:setJob', function(job)
	ESX.PlayerData.job = job

	Citizen.Wait(5000)
	TriggerServerEvent('esx_policejob:forceBlip')
end)

RegisterNetEvent('esx_phone:loaded')
AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts)
	local specialContact = {
		name       = _U('phone_police'),
		number     = 'police',
		base64Icon =
		'data:image/png;base64, '
	}

	TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon)
end)

-- don't show dispatches if the player isn't in service
AddEventHandler('esx_phone:cancelMessage', function(dispatchNumber)
	if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and ESX.PlayerData.job.name == dispatchNumber then
		-- if esx_service is enabled
		if Config.EnableESXService and not playerInService then
			CancelEvent()
		end
	end
end)

AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNum)
	if part == 'Cloakroom' then
		CurrentAction     = 'menu_cloakroom'
		CurrentActionMsg  = _U('open_cloackroom')
		CurrentActionData = {}
	elseif part == 'Armory' then
		CurrentAction     = 'menu_armory'
		CurrentActionMsg  = _U('open_armory')
		CurrentActionData = { station = station }
	elseif part == 'Vehicles' then
		CurrentAction     = 'menu_vehicle_spawner'
		CurrentActionMsg  = _U('garage_prompt')
		CurrentActionData = { station = station, part = part, partNum = partNum }
	elseif part == 'Helicopters' then
		CurrentAction     = 'Helicopters'
		CurrentActionMsg  = _U('helicopter_prompt')
		CurrentActionData = { station = station, part = part, partNum = partNum }
	elseif part == 'BossActions' then
		CurrentAction     = 'menu_boss_actions'
		CurrentActionMsg  = _U('open_bossmenu')
		CurrentActionData = {}
	end
end)

AddEventHandler('esx_policejob:hasExitedMarker', function(station, part, partNum)
	if not isInShopMenu then
		ESX.UI.Menu.CloseAll()
	end

	CurrentAction = nil
end)

AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity)
	local playerPed = PlayerPedId()

	if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and IsPedOnFoot(playerPed) then
		CurrentAction     = 'remove_entity'
		CurrentActionMsg  = _U('remove_prop')
		CurrentActionData = { entity = entity }
	end

	if GetEntityModel(entity) == GetHashKey('p_ld_stinger_s') then
		local playerPed = PlayerPedId()
		local coords    = GetEntityCoords(playerPed)

		if IsPedInAnyVehicle(playerPed, false) then
			local vehicle = GetVehiclePedIsIn(playerPed)

			for i = 0, 7, 1 do
				SetVehicleTyreBurst(vehicle, i, true, 1000)
			end
		end
	end
end)

AddEventHandler('esx_policejob:hasExitedEntityZone', function(entity)
	if CurrentAction == 'remove_entity' then
		CurrentAction = nil
	end
end)

RegisterNetEvent('esx_policejob:handcuff')
AddEventHandler('esx_policejob:handcuff', function()
	isHandcuffed = not isHandcuffed
	local playerPed = PlayerPedId()

	if isHandcuffed then
		RequestAnimDict('mp_arresting')
		while not HasAnimDictLoaded('mp_arresting') do
			Citizen.Wait(100)
		end

		TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0)

		SetEnableHandcuffs(playerPed, true)
		DisablePlayerFiring(playerPed, true)
		SetCurrentPedWeapon(playerPed, GetHashKey('WEAPON_UNARMED'), true) -- unarm player
		SetPedCanPlayGestureAnims(playerPed, false)
		FreezeEntityPosition(playerPed, false)
		DisplayRadar(false)

		if Config.EnableHandcuffTimer then
			if handcuffTimer.active then
				ESX.ClearTimeout(handcuffTimer.task)
			end

			StartHandcuffTimer()
		end
	else
		if Config.EnableHandcuffTimer and handcuffTimer.active then
			ESX.ClearTimeout(handcuffTimer.task)
		end

		ClearPedSecondaryTask(playerPed)
		SetEnableHandcuffs(playerPed, false)
		DisablePlayerFiring(playerPed, false)
		SetPedCanPlayGestureAnims(playerPed, true)
		FreezeEntityPosition(playerPed, false)
		DisplayRadar(true)
	end
end)

RegisterNetEvent('esx_policejob:unrestrain')
AddEventHandler('esx_policejob:unrestrain', function()
	if isHandcuffed then
		local playerPed = PlayerPedId()
		isHandcuffed = false

		ClearPedSecondaryTask(playerPed)
		SetEnableHandcuffs(playerPed, false)
		DisablePlayerFiring(playerPed, false)
		SetPedCanPlayGestureAnims(playerPed, true)
		FreezeEntityPosition(playerPed, false)
		DisplayRadar(true)

		-- end timer
		if Config.EnableHandcuffTimer and handcuffTimer.active then
			ESX.ClearTimeout(handcuffTimer.task)
		end
	end
end)

RegisterNetEvent('esx_policejob:drag')
AddEventHandler('esx_policejob:drag', function(copId)
	if isHandcuffed then
		dragStatus.isDragged = not dragStatus.isDragged
		dragStatus.CopId = copId
	end
end)

Citizen.CreateThread(function()
	local wasDragged

	while true do
		Citizen.Wait(0)
		local playerPed = PlayerPedId()

		if isHandcuffed and dragStatus.isDragged then
			local targetPed = GetPlayerPed(GetPlayerFromServerId(dragStatus.CopId))

			if DoesEntityExist(targetPed) and IsPedOnFoot(targetPed) and not IsPedDeadOrDying(targetPed, true) then
				if not wasDragged then
					AttachEntityToEntity(playerPed, targetPed, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false,
						false, 2, true)
					wasDragged = true
				else
					Citizen.Wait(1000)
				end
			else
				wasDragged = false
				dragStatus.isDragged = false
				DetachEntity(playerPed, true, false)
			end
		elseif wasDragged then
			wasDragged = false
			DetachEntity(playerPed, true, false)
		else
			Citizen.Wait(500)
		end
	end
end)

RegisterNetEvent('esx_policejob:putInVehicle')
AddEventHandler('esx_policejob:putInVehicle', function()
	if isHandcuffed then
		local playerPed = PlayerPedId()
		local coords = GetEntityCoords(playerPed)

		if IsAnyVehicleNearPoint(coords, 5.0) then
			local vehicle = GetClosestVehicle(coords, 5.0, 0, 71)

			if DoesEntityExist(vehicle) then
				local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle)

				for i = maxSeats - 1, 0, -1 do
					if IsVehicleSeatFree(vehicle, i) then
						freeSeat = i
						break
					end
				end

				if freeSeat then
					TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat)
					dragStatus.isDragged = false
				end
			end
		end
	end
end)

RegisterNetEvent('esx_policejob:OutVehicle')
AddEventHandler('esx_policejob:OutVehicle', function()
	local playerPed = PlayerPedId()

	if IsPedSittingInAnyVehicle(playerPed) then
		local vehicle = GetVehiclePedIsIn(playerPed, false)
		TaskLeaveVehicle(playerPed, vehicle, 64)
	end
end)

-- Handcuff
Citizen.CreateThread(function()
	while true do
		Citizen.Wait(0)
		local playerPed = PlayerPedId()

		if isHandcuffed then
			DisableControlAction(0, 1, true) -- Disable pan
			DisableControlAction(0, 2, true) -- Disable tilt
			DisableControlAction(0, 24, true) -- Attack
			DisableControlAction(0, 257, true) -- Attack 2
			DisableControlAction(0, 25, true) -- Aim
			DisableControlAction(0, 263, true) -- Melee Attack 1
			--DisableControlAction(0, 32, true) -- W
			--DisableControlAction(0, 34, true) -- A
			--DisableControlAction(0, 31, true) -- S
			--DisableControlAction(0, 30, true) -- D

			DisableControlAction(0, 45, true) -- Reload
			DisableControlAction(0, 22, true) -- Jump
			DisableControlAction(0, 44, true) -- Cover
			DisableControlAction(0, 37, true) -- Select Weapon
			DisableControlAction(0, 23, true) -- Also 'enter'?

			DisableControlAction(0, 288, true) -- Disable phone
			DisableControlAction(0, 289, true) -- Inventory
			DisableControlAction(0, 170, true) -- Animations
			DisableControlAction(0, 167, true) -- Job

			DisableControlAction(0, 0, true) -- Disable changing view
			DisableControlAction(0, 26, true) -- Disable looking behind
			DisableControlAction(0, 73, true) -- Disable clearing animation
			DisableControlAction(2, 199, true) -- Disable pause screen

			DisableControlAction(0, 59, true) -- Disable steering in vehicle
			DisableControlAction(0, 71, true) -- Disable driving forward in vehicle
			DisableControlAction(0, 72, true) -- Disable reversing in vehicle

			DisableControlAction(2, 36, true) -- Disable going stealth

			DisableControlAction(0, 47, true) -- Disable weapon
			DisableControlAction(0, 264, true) -- Disable melee
			DisableControlAction(0, 257, true) -- Disable melee
			DisableControlAction(0, 140, true) -- Disable melee
			DisableControlAction(0, 141, true) -- Disable melee
			DisableControlAction(0, 142, true) -- Disable melee
			DisableControlAction(0, 143, true) -- Disable melee
			DisableControlAction(0, 75, true) -- Disable exit vehicle
			DisableControlAction(27, 75, true) -- Disable exit vehicle

			if IsEntityPlayingAnim(playerPed, 'mp_arresting', 'idle', 3) ~= 1 then
				ESX.Streaming.RequestAnimDict('mp_arresting', function()
					TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0.0, false, false, false)
				end)
			end
		else
			Citizen.Wait(500)
		end
	end
end)

-- Create blips
Citizen.CreateThread(function()
	for k, v in pairs(Config.PoliceStations) do
		local blip = AddBlipForCoord(v.Blip.Coords)

		SetBlipSprite(blip, v.Blip.Sprite)
		SetBlipDisplay(blip, v.Blip.Display)
		SetBlipScale(blip, v.Blip.Scale)
		SetBlipColour(blip, v.Blip.Colour)
		SetBlipAsShortRange(blip, true)

		BeginTextCommandSetBlipName('STRING')
		AddTextComponentSubstringPlayerName(_U('map_blip'))
		EndTextCommandSetBlipName(blip)
	end
end)

-- Draw markers and more
Citizen.CreateThread(function()
	while true do
		Citizen.Wait(0)

		if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
			local playerPed = PlayerPedId()
			local playerCoords = GetEntityCoords(playerPed)
			local isInMarker, hasExited, letSleep = false, false, true
			local currentStation, currentPart, currentPartNum

			for k, v in pairs(Config.PoliceStations) do
				for i = 1, #v.Cloakrooms, 1 do
					local distance = #(playerCoords - v.Cloakrooms[i])

					if distance < Config.DrawDistance then
						DrawMarker(Config.MarkerType.Cloakrooms, v.Cloakrooms[i], 0.0, 0.0, 0.0, 0, 0.0, 0.0, 1.0, 1.0,
							1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2,
							true, false, false, false)
						letSleep = false

						if distance < Config.MarkerSize.x then
							isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Cloakroom', i
						end
					end
				end

				for i = 1, #v.Armories, 1 do
					local distance = #(playerCoords - v.Armories[i])

					if distance < Config.DrawDistance then
						DrawMarker(Config.MarkerType.Armories, v.Armories[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5,
							Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true,
							false, false, false)
						letSleep = false

						if distance < Config.MarkerSize.x then
							isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Armory', i
						end
					end
				end

				for i = 1, #v.Vehicles, 1 do
					local distance = #(playerCoords - v.Vehicles[i].Spawner)

					if distance < Config.DrawDistance then
						DrawMarker(Config.MarkerType.Vehicles, v.Vehicles[i].Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
							1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true,
							2, true, false, false, false)
						letSleep = false

						if distance < Config.MarkerSize.x then
							isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Vehicles', i
						end
					end
				end

				for i = 1, #v.Helicopters, 1 do
					local distance = #(playerCoords - v.Helicopters[i].Spawner)

					if distance < Config.DrawDistance then
						DrawMarker(Config.MarkerType.Helicopters, v.Helicopters[i].Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
							1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false,
							true, 2, true, false, false, false)
						letSleep = false

						if distance < Config.MarkerSize.x then
							isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Helicopters', i
						end
					end
				end

				if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == 'boss' then
					for i = 1, #v.BossActions, 1 do
						local distance = #(playerCoords - v.BossActions[i])

						if distance < Config.DrawDistance then
							DrawMarker(Config.MarkerType.BossActions, v.BossActions[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
								1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false,
								true, 2, true, false, false, false)
							letSleep = false

							if distance < Config.MarkerSize.x then
								isInMarker, currentStation, currentPart, currentPartNum = true, k, 'BossActions', i
							end
						end
					end
				end
			end

			if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then
				if
					(LastStation and LastPart and LastPartNum) and
					(LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum)
				then
					TriggerEvent('esx_policejob:hasExitedMarker', LastStation, LastPart, LastPartNum)
					hasExited = true
				end

				HasAlreadyEnteredMarker = true
				LastStation             = currentStation
				LastPart                = currentPart
				LastPartNum             = currentPartNum

				TriggerEvent('esx_policejob:hasEnteredMarker', currentStation, currentPart, currentPartNum)
			end

			if not hasExited and not isInMarker and HasAlreadyEnteredMarker then
				HasAlreadyEnteredMarker = false
				TriggerEvent('esx_policejob:hasExitedMarker', LastStation, LastPart, LastPartNum)
			end

			if letSleep then
				Citizen.Wait(500)
			end
		else
			Citizen.Wait(500)
		end
	end
end)

-- Enter / Exit entity zone events
Citizen.CreateThread(function()
	local trackedEntities = {
		'prop_roadcone02a',
		'prop_barrier_work05',
		'p_ld_stinger_s',
		'prop_boxpile_07d',
		'hei_prop_cash_crate_half_full',
		'prop_barrier_work05',
		'p_ld_stinger_s',
		'prop_boxpile_07d',
		'hei_prop_cash_crate_half_full',
		'prop_flagger_sign_01',
		'prop_worklight_03b',
		'prop_roadcone01a',
		'prop_roadcone01c',
		'prop_roadcone02c',
		'prop_mp_cone_04',
		'prop_consign_flag_01',
		'prop_consign_flag_21',
		'prop_consign_flag_18',
		'prop_consign_flag_19',
		'prop_consign_flag_02',
		'prop_consign_flag_03',
		'prop_consign_flag_04',
		'prop_consign_flag_05',
		'prop_consign_flag_13',
		'prop_consign_flag_14',
		'prop_consign_flag_08',
		'prop_consign_flag_06',
		'prop_consign_flag_07',
		'prop_consign_flag_10',
		'prop_consign_flag_09',
		'prop_consign_flag_25',
		'prop_consign_flag_26',
		'prop_consign_flag_27',
		'prop_consign_flag_28',
		'prop_consign_flag_29',
		'prop_consign_flag_11',
		'prop_consign_flag_22',
		'prop_consign_flag_15',
		'prop_consign_flag_16',
		'prop_consign_flag_17',
		'prop_consign_flag_12',
		'prop_consign_flag_23',
		'prop_consign_flag_24',
		'prop_consign_flag_20',
		'prop_consign_flag_30',
		'prop_consign_flag_stop',
		'prop_consign_flag_custom',
		'prop_barrier_sign_01',
		'prop_barrier_sign_21',
		'prop_barrier_sign_18',
		'prop_barrier_sign_19',
		'prop_barrier_sign_02',
		'prop_barrier_sign_03',
		'prop_barrier_sign_04',
		'prop_barrier_sign_05',
		'prop_barrier_sign_13',
		'prop_barrier_sign_14',
		'prop_barrier_sign_08',
		'prop_barrier_sign_06',
		'prop_barrier_sign_07',
		'prop_barrier_sign_10',
		'prop_barrier_sign_09',
		'prop_barrier_sign_25',
		'prop_barrier_sign_detour',
		'prop_barrier_sign_26',
		'prop_barrier_sign_27',
		'prop_barrier_sign_28',
		'prop_barrier_sign_29',
		'prop_barrier_sign_11',
		'prop_barrier_sign_22',
		'prop_barrier_sign_15',
		'prop_barrier_sign_16',
		'prop_barrier_sign_17',
		'prop_barrier_sign_12',
		'prop_barrier_sign_23',
		'prop_barrier_sign_24',
		'prop_barrier_sign_20',
		'prop_barrier_sign_30',
		'prop_barrier_sign_stop',
		'prop_barrier_sign_custom',
		'prop_barrier_work05',
		'prop_barrier_work06a',
		'prop_barrier_work06b',
		'prop_barrier_work06c',
		'prop_barrier_work06d',
		'prop_barrier_wat_03a',
		'prop_barrier_wat_03b',
		'prop_barrier_work01a',
		'prop_barrier_work02a',
		'prop_barrier_work04a',
		'prop_barrier_work04b',
		'prop_barrier_work04br',
		'prop_barrier_work04c',
		'prop_barrier_work04cr',
		'prop_barrier_work04dx',
		'prop_barrier_work04drx',
		'prop_barrier_work04d',
		'prop_barrier_work04dr',
		'prop_barrier_work04ex',
		'prop_barrier_work04erx',
		'prop_barrier_work04e',
		'prop_barrier_work04er',
		'prop_trafficdiv_01',
		'prop_trafficdiv_02'
	}

	while true do
		Citizen.Wait(500)

		local playerPed       = PlayerPedId()
		local playerCoords    = GetEntityCoords(playerPed)

		local closestDistance = -1
		local closestEntity   = nil

		for i = 1, #trackedEntities, 1 do
			local object = GetClosestObjectOfType(playerCoords, 3.0, GetHashKey(trackedEntities[i]), false, false, false)

			if DoesEntityExist(object) then
				local objCoords = GetEntityCoords(object)
				local distance = #(playerCoords - objCoords)

				if closestDistance == -1 or closestDistance > distance then
					closestDistance = distance
					closestEntity   = object
				end
			end
		end

		if closestDistance ~= -1 and closestDistance <= 3.0 then
			if LastEntity ~= closestEntity then
				TriggerEvent('esx_policejob:hasEnteredEntityZone', closestEntity)
				LastEntity = closestEntity
			end
		else
			if LastEntity then
				TriggerEvent('esx_policejob:hasExitedEntityZone', LastEntity)
				LastEntity = nil
			end
		end
	end
end)

-- Key Controls
Citizen.CreateThread(function()
	while true do
		Citizen.Wait(0)

		if CurrentAction then
			ESX.ShowHelpNotification(CurrentActionMsg)

			if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
				if CurrentAction == 'menu_cloakroom' then
					OpenCloakroomMenu()
				elseif CurrentAction == 'menu_armory' then
					if not Config.EnableESXService then
						OpenArmoryMenu(CurrentActionData.station)
					elseif playerInService then
						OpenArmoryMenu(CurrentActionData.station)
					else
						ESX.ShowNotification(_U('service_not'))
					end
				elseif CurrentAction == 'menu_vehicle_spawner' then
					if not Config.EnableESXService then
						OpenVehicleSpawnerMenu('car', CurrentActionData.station, CurrentActionData.part,
							CurrentActionData.partNum)
					elseif playerInService then
						OpenVehicleSpawnerMenu('car', CurrentActionData.station, CurrentActionData.part,
							CurrentActionData.partNum)
					else
						ESX.ShowNotification(_U('service_not'))
					end
				elseif CurrentAction == 'Helicopters' then
					if not Config.EnableESXService then
						OpenVehicleSpawnerMenu('helicopter', CurrentActionData.station, CurrentActionData.part,
							CurrentActionData.partNum)
					elseif playerInService then
						OpenVehicleSpawnerMenu('helicopter', CurrentActionData.station, CurrentActionData.part,
							CurrentActionData.partNum)
					else
						ESX.ShowNotification(_U('service_not'))
					end
				elseif CurrentAction == 'delete_vehicle' then
					ESX.Game.DeleteVehicle(CurrentActionData.vehicle)
				elseif CurrentAction == 'menu_boss_actions' then
					ESX.UI.Menu.CloseAll()
					TriggerEvent('esx_society:openBossMenu', 'police', function(data, menu)
						menu.close()

						CurrentAction     = 'menu_boss_actions'
						CurrentActionMsg  = _U('open_bossmenu')
						CurrentActionData = {}
					end, { wash = false }) -- disable washing money
				elseif CurrentAction == 'remove_entity' then
					DeleteEntity(CurrentActionData.entity)
				end

				CurrentAction = nil
			end
		end -- CurrentAction end

		if IsControlJustReleased(0, 167) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') then
			if not Config.EnableESXService then
				OpenPoliceActionsMenu()
			elseif playerInService then
				OpenPoliceActionsMenu()
			else
				ESX.ShowNotification(_U('service_not'))
			end
		end

		if IsControlJustReleased(0, 38) and currentTask.busy then
			ESX.ShowNotification(_U('impound_canceled'))
			ESX.ClearTimeout(currentTask.task)
			ClearPedTasks(PlayerPedId())

			currentTask.busy = false
		end
	end
end)

-- Create blip for colleagues
function createBlip(id)
	local ped = GetPlayerPed(id)
	local blip = GetBlipFromEntity(ped)

	if not DoesBlipExist(blip) then -- Add blip and create head display on player
		blip = AddBlipForEntity(ped)
		SetBlipSprite(blip, 1)
		ShowHeadingIndicatorOnBlip(blip, true)            -- Player Blip indicator
		SetBlipRotation(blip, math.ceil(GetEntityHeading(ped))) -- update rotation
		SetBlipNameToPlayerName(blip, id)                 -- update blip name
		SetBlipScale(blip, 0.85)                          -- set scale
		SetBlipAsShortRange(blip, true)

		table.insert(blipsCops, blip) -- add blip to array so we can remove it later
	end
end

RegisterNetEvent('esx_policejob:updateBlip')
AddEventHandler('esx_policejob:updateBlip', function()
	-- Refresh all blips
	for k, existingBlip in pairs(blipsCops) do
		RemoveBlip(existingBlip)
	end

	-- Clean the blip table
	blipsCops = {}

	-- Enable blip?
	if Config.EnableESXService and not playerInService then
		return
	end

	if not Config.EnableJobBlip then
		return
	end

	-- Is the player a cop? In that case show all the blips for other cops
	if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
		ESX.TriggerServerCallback('esx_society:getOnlinePlayers', function(players)
			for i = 1, #players, 1 do
				if players[i].job.name == 'police' then
					local id = GetPlayerFromServerId(players[i].source)
					if NetworkIsPlayerActive(id) and GetPlayerPed(id) ~= PlayerPedId() then
						createBlip(id)
					end
				end
			end
		end)
	end
end)

AddEventHandler('playerSpawned', function(spawn)
	isDead = false
	TriggerEvent('esx_policejob:unrestrain')

	if not hasAlreadyJoined then
		TriggerServerEvent('esx_policejob:spawned')
	end
	hasAlreadyJoined = true
end)

AddEventHandler('esx:onPlayerDeath', function(data)
	isDead = true
end)

AddEventHandler('onResourceStop', function(resource)
	if resource == GetCurrentResourceName() then
		TriggerEvent('esx_policejob:unrestrain')
		TriggerEvent('esx_phone:removeSpecialContact', 'police')

		if Config.EnableESXService then
			TriggerServerEvent('esx_service:disableService', 'police')
		end

		if Config.EnableHandcuffTimer and handcuffTimer.active then
			ESX.ClearTimeout(handcuffTimer.task)
		end
	end
end)

-- handcuff timer, unrestrain the player after an certain amount of time
function StartHandcuffTimer()
	if Config.EnableHandcuffTimer and handcuffTimer.active then
		ESX.ClearTimeout(handcuffTimer.task)
	end

	handcuffTimer.active = true

	handcuffTimer.task = ESX.SetTimeout(Config.HandcuffTimer, function()
		ESX.ShowNotification(_U('unrestrained_timer'))
		TriggerEvent('esx_policejob:unrestrain')
		handcuffTimer.active = false
	end)
end

-- TODO
--   - return to garage if owned
--   - message owner that his vehicle has been impounded
function ImpoundVehicle(vehicle)
	--local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(vehicle)))
	ESX.Game.DeleteVehicle(vehicle)
	ESX.ShowNotification(_U('impound_successful'))
	currentTask.busy = false
end

function openMenu()
	ESX.UI.Menu.Open(
		'default', GetCurrentResourceName(), 'id_card_menu',
		{
			css      = 'documenti',
			title    = 'Police Badge',
			elements = {
				{ label = 'Check your ID', value = 'checkBadge' },
				{ label = 'Show your ID',  value = 'showBadge' },
			}
		},

		function(data, menu)
			local val = data.current.value


			if val == 'checkBadge' then
				TriggerServerEvent('policebadge:open', GetPlayerServerId(PlayerId()), GetPlayerServerId(PlayerId()))
				local lPed = GetPlayerPed(-1)
			else
				local player, distance = ESX.Game.GetClosestPlayer()

				if distance ~= -1 and distance <= 3.0 then
					if val == 'showBadge' then
						TriggerServerEvent('policebadge:open', GetPlayerServerId(PlayerId()), GetPlayerServerId(player))
					end
				else
					ESX.ShowNotification('No players nearby')
				end
			end
		end,
		function(data, menu)
			menu.close()
		end
	)
end

CreateThread(function()
	while true do
		Citizen.Wait(0)
		if IsControlJustReleased(0, 161) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'id_card_menu') then
			openMenu()
		end
	end
end)

CreateThread(function()
	while true do
		Citizen.Wait(5000)
		if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
			TriggerServerEvent('policebadge:ItemsBadge', GetPlayerPed(-1))
		end
	end
end)

function openMenu()
	ESX.UI.Menu.Open(
		'default', GetCurrentResourceName(), 'id_card_menu',
		{
			css      = 'documenti',
			title    = 'Police Badge',
			elements = {
				{ label = 'Check your ID', value = 'checkBadge' },
				{ label = 'Show your ID',  value = 'showBadge' },
			}
		},

		function(data, menu)
			local val = data.current.value


			if val == 'checkBadge' then
				TriggerServerEvent('policebadge:open', GetPlayerServerId(PlayerId()), GetPlayerServerId(PlayerId()))
				local lPed = GetPlayerPed(-1)
			else
				local player, distance = ESX.Game.GetClosestPlayer()

				if distance ~= -1 and distance <= 3.0 then
					if val == 'showBadge' then
						TriggerServerEvent('policebadge:open', GetPlayerServerId(PlayerId()), GetPlayerServerId(player))
					end
				else
					ESX.ShowNotification('No players nearby')
				end
			end
		end,
		function(data, menu)
			menu.close()
		end
	)
end

CreateThread(function()
	while true do
		Citizen.Wait(0)
		if IsControlJustReleased(0, 161) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'id_card_menu') then
			openMenu()
		end
	end
end)

CreateThread(function()
	while true do
		Citizen.Wait(5000)
		if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
			TriggerServerEvent('policebadge:ItemsBadge', GetPlayerPed(-1))
		end
	end
end)
