if not LLRP then return print('Не загружен фреймворк LLPR_Medic') end

-- local QBCore = exports['qb-core']:GetCoreObject()

local Active = false
local ambulanceVehicle = nil
local doctorPed = nil
local canCall = true
local ambulanceBlip = nil




-- Обработчик события уведомления
RegisterNetEvent('LLRP:notify')
AddEventHandler('LLRP:notify', function(msg, state)
	Notify(msg, state)
end)

function Notify(msg, state)
	LLRP.Core.Functions.Notify(msg, state)
end

function SpawnVehicle(location)
	canCall = false
	local vehHash = GetHashKey("ambulance")
	local pedHash = GetHashKey('s_m_m_doctor_01')

	RequestModel(vehHash)
	RequestModel(pedHash)

	local attempts = 0
	while (not HasModelLoaded(vehHash) or not HasModelLoaded(pedHash)) and attempts < 50 do
		Citizen.Wait(100)
		attempts = attempts + 1
	end

	if not HasModelLoaded(vehHash) or not HasModelLoaded(pedHash) then
		Notify("Не удалось загрузить модель.", "error")
		canCall = true
		return
	end

	local spawnRadius = 100
	local found, spawnPos, spawnHeading = GetClosestVehicleNodeWithHeading(
		location.x + math.random(-spawnRadius, spawnRadius),
		location.y + math.random(-spawnRadius, spawnRadius),
		location.z, 0, 3, 0)

	if found then
		ambulanceVehicle = CreateVehicle(vehHash, spawnPos, spawnHeading, true, false)
		if not DoesEntityExist(ambulanceVehicle) then
			Notify("Не удалось создать машину скорой помощи.", "error")
			canCall = true
			return
		end
		SetVehicleNumberPlateText(ambulanceVehicle, "LLRP")
		SetEntityAsMissionEntity(ambulanceVehicle, true, true)
		SetVehicleEngineOn(ambulanceVehicle, true, true, false)

		doctorPed = CreatePedInsideVehicle(ambulanceVehicle, 26, pedHash, -1, true, false)
		if not DoesEntityExist(doctorPed) then
			Notify("Не удалось создать доктора.", "error")
			DeleteEntity(ambulanceVehicle)
			canCall = true
			return
		end

		ambulanceBlip = AddBlipForEntity(ambulanceVehicle)
		SetBlipFlashes(ambulanceBlip, true)
		SetBlipColour(ambulanceBlip, 5)

		PlaySoundFrontend(-1, "Text_Arrive_Tone", "Phone_SoundSet_Default", 1)
		TaskVehicleDriveToCoord(doctorPed, ambulanceVehicle, location.x, location.y, location.z, 20.0, 0,
			GetEntityModel(ambulanceVehicle), 786603, 2.0)


		Active = true

		SettingVehicle()
	else
		Notify("Не удалось найти подходящее место для спавна транспорта.", "error")
		canCall = true
	end
end

function DoctorsOnLine(callback)
	LLRP.Core.Functions.TriggerCallback('LLRP:DoctorsOnLine', function(doctorOnline)
		callback(doctorOnline)
	end)
end

function GetDeadOutOfVehicle(pullingPed, targetPed, vehicle)
	-- Проверяем, находится ли целевой персонаж в автомобиле
	if IsPedInAnyVehicle(targetPed, false) then
		local doorLockStatus = GetVehicleDoorLockStatus(vehicle)
		if doorLockStatus == 2 then
			Notify('Двери заблокированы, невозможно вытащить персонажа!', "error")
			return
		end

		-- Загружаем анимационный словарь для анимации вытаскивания
		RequestAnimDict("veh@break_in@0h@p_m_one@")
		while not HasAnimDictLoaded("veh@break_in@0h@p_m_one@") do
			Citizen.Wait(100)
		end

		-- Применяем анимацию "вытаскивания" к pullingPed
		TaskPlayAnim(pullingPed, "veh@break_in@0h@p_m_one@", "low_force_entry_ds", 8.0, -8.0, -1, 49, 0, false, false, false)
		Citizen.Wait(2000)

		-- Вытаскиваем персонажа из машины
		TaskLeaveVehicle(targetPed, vehicle, 16)
		Citizen.Wait(100)
		TaskPlayAnim(targetPed, "mini@cpr@char_b@cpr_def", "cpr_pumpchest_idle", 8.0, -8.0, -1, 49, 0, false, false,
			false)

		-- Очищаем задачи целевого персонажа, чтобы он не возвращался в машину
		ClearPedTasksImmediately(targetPed)

		-- Очищаем задачи вытаскивающего педа (pullingPed)
		ClearPedTasks(pullingPed)
	end
end

function Cleanup()
	if DoesEntityExist(ambulanceVehicle) then
		DeleteEntity(ambulanceVehicle)
	end
	if DoesEntityExist(doctorPed) then
		ClearPedTasksImmediately(doctorPed)
		DeleteEntity(doctorPed)
	end
	if DoesBlipExist(ambulanceBlip) then
		RemoveBlip(ambulanceBlip)
	end
	canCall = true
end

function DoctorNPC()
	-- HideDeathNui()
	-- Загрузка анимаций
	RequestAnimDict("mini@cpr@char_a@cpr_str")             -- реанимация
	RequestAnimDict("anim@heists@ornate_bank@hostages@hit") -- положение больного
	RequestAnimDict("missfinale_c2mcs_1")                  -- положение доктора

	-- ожидание загрузки словарей анимации
	while not HasAnimDictLoaded("mini@cpr@char_a@cpr_str") or
		not HasAnimDictLoaded("anim@heists@ornate_bank@hostages@hit") or
		not HasAnimDictLoaded("missfinale_c2mcs_1") do
		Citizen.Wait(100)
	end

	-- Выполнить реанимацию
	TaskPlayAnim(doctorPed, "mini@cpr@char_a@cpr_str", "cpr_pumpchest", 1.0, 1.0, -1, 9, 1.0, 0, 0, 0)
	Citizen.Wait(7000)
	ClearPedTasks(doctorPed)

	-- Поднять игрока на спину
	local playerPed = PlayerPedId()
	TaskPlayAnim(doctorPed, "missfinale_c2mcs_1", "fin_c2_mcs_1_camman", 1.0, 1.0, -1, 49, 1.0, 0, 0, 0)
	AttachEntityToEntity(playerPed, doctorPed, GetPedBoneIndex(doctorPed, 11816), -0.6, 0.3, 1.2, 0.0, 0.0, 270.0, false, false, false, true, 1, true)
	TaskPlayAnim(playerPed, "anim@heists@ornate_bank@hostages@hit", "hit_react_die_loop_ped_a", 8.0, -8.0, -1, 49, 0, false, false, false) -- положение больного
	Citizen.Wait(1500)

	-- Нести игрока к машине
	local nearestVehicle = GetEntityModel(ambulanceVehicle)
	if nearestVehicle == GetHashKey("ambulance") or nearestVehicle == GetHashKey("20ramambo") or nearestVehicle == GetHashKey("ec135") then
		TaskEnterVehicle(doctorPed, ambulanceVehicle, -1, 1, 2.0, 1, 0) -- Бот несет в машину
		Citizen.Wait(7000)
		ClearPedTasks(playerPed)
		DetachEntity(playerPed, true, false)                                                                       -- открепляем игрока от бота
		DisableControlAction(0, 75, true)                                                                          -- отключить управление игроку
		SetPedIntoVehicle(playerPed, ambulanceVehicle, 2)                                                          -- посадить в машину

		TaskPlayAnim(playerPed, 'veh@bus@passenger@common@idle_duck', 'sit', 8.0, -8, -1, 2, 0, false, false, false) -- сидеть на заднем сиденье опустив голову
		ClearPedTasks(doctorPed)
		Citizen.Wait(3000)

		-- Доктор выходит из машины и садится на водительское место
		TaskLeaveVehicle(doctorPed, ambulanceVehicle, 0)
		Citizen.Wait(2000)
		TaskEnterVehicle(doctorPed, ambulanceVehicle, -1, -1, 2.0, 1, 0) -- Доктор на водительское место
		Citizen.Wait(2000)
	end

	-- Доктор везет игрока в госпиталь
	TaskVehicleDriveToCoord(doctorPed, ambulanceVehicle, Config.HospitalCoords.x, Config.HospitalCoords.y, Config.HospitalCoords.z, 20.0, 0, GetEntityModel(ambulanceVehicle), 524863, 2.0)
	Notify("Вас везут в больницу", "primary")

	Citizen.CreateThread(function()
		while true do
			Citizen.Wait(500)
			local distToHospital = #(GetEntityCoords(ambulanceVehicle) - vector3(Config.HospitalCoords.x, Config.HospitalCoords.y, Config.HospitalCoords.z))
			if distToHospital <= 10.0 then
				TaskLeaveVehicle(playerPed, ambulanceVehicle, 0)
				ClearPedTasks(playerPed) -- Очищаем задачи у игрока при выходе
				Notify("Вы прибыли в больницу. Вам будет оказана медицинская помощь.", "success")
				Citizen.Wait(6000)

				LLRP.Core.Functions.TriggerCallback('LLRP:charge_for_revive', function(success)
					if success then
						Notify("Средства за оказанные услуги удержаны.", "success")
					else
						Notify("Недостаточно средств для оплаты услуг.", "error")
					end
				end)
				if LLRP.Ambulance == 'qb-core' then
					TriggerEvent('hospital:client:RespawnAtHospital')
					Cleanup()
					break
				elseif LLRP.Ambulance == 'wasabi' then
					print('start StartRPDeath()')
					-- StartRPDeath()
					TriggerEvent('hospital:client:RespawnAtHospital')
					Cleanup()
					break
				end
			end
		end
	end)
end

RegisterCommand("helpme", function(source, args, raw)
	-- local playerData = QBCore.Functions.GetPlayerData()
	local playerData = LLRP.Core.Functions.GetPlayerData()
	if (playerData.metadata["isdead"] or playerData.metadata["inlaststand"]) then
		if canCall then
			DoctorsOnLine(function(doctorOnline)
				if not doctorOnline then
					SpawnVehicle(GetEntityCoords(PlayerPedId()))
					Notify("Медик уже в пути!")
				else
					Notify("В наличии полно медиков, ждите...", "error")
				end
			end)
		else
			Notify("Вы уже вызвали медика, пожалуйста, подождите.", "error")
		end
	else
		Notify("Вы не нуждаетесь в помощи.", "error")
	end
end)




function SettingVehicle()
	EnableSiren()
	exports.LegacyFuel:SetFuel(ambulanceVehicle, 100)

	Citizen.CreateThread(function()
		while Active do
			Citizen.Wait(0)

			if IsVehicleDriveable(ambulanceVehicle) then
				-- Отключаем радио
				SetVehicleRadioEnabled(ambulanceVehicle, false)
				EnableAggressiveDriver(ambulanceVehicle, doctorPed)
			end
		end
	end)
end

function EnableAggressiveDriver(vehicle, ped)
	SetDriveTaskDrivingStyle(ped, 788)
	SetEntityInvincible(vehicle, true)
	SetDriverAggressiveness(ped, 1.0)
end

function EnableSiren()
	SetVehicleSiren(ambulanceVehicle, true)
	SetVehicleLights(vehicle, 2) -- 2 для мигания
end

Citizen.CreateThread(function()
	while true do
		Citizen.Wait(3000)
		local playerData = LLRP.Core.Functions.GetPlayerData()
		if not playerData.metadata["isdead"] and not playerData.metadata["inlaststand"] then
			canCall = true
		end
	end
end)

Citizen.CreateThread(function()
	while true do
		Citizen.Wait(500)
		if Active and DoesEntityExist(ambulanceVehicle) and DoesEntityExist(doctorPed) then
			local playerPed = PlayerPedId()
			local playerPos = GetEntityCoords(playerPed)
			local vehPos = GetEntityCoords(ambulanceVehicle)
			local pedPos = GetEntityCoords(doctorPed)
			local distToVeh = #(playerPos - vehPos)
			local distToPed = #(playerPos - pedPos)

			if distToVeh <= 10 then
				TaskLeaveVehicle(doctorPed, ambulanceVehicle, 0)
				TaskGoToCoordAnyMeans(doctorPed, playerPos.x, playerPos.y, playerPos.z, 1.0, 0, 0, 786603, 0)
				if distToPed <= 2 and IsPedInAnyVehicle(playerPed, false) then
					local vehicle = GetVehiclePedIsIn(playerPed, false)
					GetDeadOutOfVehicle(doctorPed, playerPed, vehicle)
				elseif distToPed <= 1 and not IsPedInAnyVehicle(playerPed, false) then
					Active = false
					ClearPedTasksImmediately(doctorPed)
					DoctorNPC()
				end
			end
		end
	end
end)