local PLUGIN = PLUGIN

-- Координаты баз для запрета авиаударов
local BASE_RF = {
	min = Vector(-12686, 4350, -10000),
	max = Vector(-8714, 12126, 10000)
}
local BASE_UK = {
	min = Vector(9778, 2972, -10000),
	max = Vector(13576, 10852, 10000)
}

local function IsInBase(pos)
	if (pos:WithinAABox(BASE_RF.min, BASE_RF.max)) then return true end
	if (pos:WithinAABox(BASE_UK.min, BASE_UK.max)) then return true end
	return false
end

function PLUGIN:SpawnAirdrop(weapon)
	local center = Vector(0, 0, 0)
	local players = player.GetAll()
	if (#players > 0) then
		local targetPlayer = players[math.random(#players)]
		center = targetPlayer:GetPos()
	end

	local angle = math.random(0, 360)
	local radian = math.rad(angle)
	local altitude = math.random(2000, 2500)
	local startPos = center + Vector(math.cos(radian) * 15000, math.sin(radian) * 15000, 0)
	startPos.z = altitude
	local endPos = center - Vector(math.cos(radian) * 15000, math.sin(radian) * 15000, 0)
	endPos.z = altitude
	
	util.PrecacheModel(ix.config.Get("airdropPlaneModel", "models/gunkov2056/su25.mdl"))
	local plane = ents.Create("prop_dynamic")
	plane:SetModel(ix.config.Get("airdropPlaneModel", "models/gunkov2056/su25.mdl"))
	plane:SetPos(startPos)
	local angles = (endPos - startPos):Angle()
	plane:SetAngles(angles)
	plane:SetMoveType(MOVETYPE_FLY)
	plane:Spawn()
	plane:Activate()
	
	print("[Airdrop] Спавн самолета: " .. plane:GetModel() .. " на " .. tostring(startPos))
	
	local speed = 2500
	local distance = startPos:Distance(endPos)
	local duration = distance / speed
	local dropFrac = math.Rand(0.45, 0.55)
	local dropped = false
	local startTime = CurTime()
	
	plane:EmitSound("su25/su25.wav", 150, 100, 1, CHAN_AUTO)

	timer.Create("AirdropPlaneMove_" .. plane:EntIndex(), 0.05, 0, function()
		if (!IsValid(plane)) then return end
		local elapsed = CurTime() - startTime
		local frac = elapsed / duration
		if (frac >= 1) then
			plane:StopSound("su25/su25.wav")
			plane:Remove()
			timer.Remove("AirdropPlaneMove_" .. plane:EntIndex())
			return
		end
		plane:SetPos(LerpVector(frac, startPos, endPos))
		if (!dropped and frac >= dropFrac) then
			dropped = true
			self:DropCrate(plane:GetPos(), weapon)
		end
	end)
end

function PLUGIN:SpawnAirstrike()
	ix.util.Notify("Внимание! Обнаружена воздушная угроза. Авиаудар через 30 секунд!", nil, "all")
	
	timer.Simple(30, function()
		local targetPos = Vector(0, 0, 0)
		local players = player.GetAll()
		local attempts = 0
		
		-- Ищем валидную точку для удара (не в базе)
		repeat
			if (#players > 0) then
				targetPos = players[math.random(#players)]:GetPos()
			else
				targetPos = Vector(math.random(-10000, 10000), math.random(-10000, 10000), 0)
			end
			attempts = attempts + 1
		until (!IsInBase(targetPos) or attempts > 10)

		if (IsInBase(targetPos)) then return end -- Отмена если не нашли безопасную точку

		local angle = math.random(0, 360)
		local radian = math.rad(angle)
		local altitude = math.random(2000, 2500)
		local startPos = targetPos + Vector(math.cos(radian) * 15000, math.sin(radian) * 15000, 0)
		startPos.z = altitude
		local endPos = targetPos - Vector(math.cos(radian) * 15000, math.sin(radian) * 15000, 0)
		endPos.z = altitude
		
		util.PrecacheModel(ix.config.Get("airstrikePlaneModel", "models/gunkov2056/su25.mdl"))
		local plane = ents.Create("prop_dynamic")
		plane:SetModel(ix.config.Get("airstrikePlaneModel", "models/gunkov2056/su25.mdl"))
		plane:SetPos(startPos)
		plane:SetAngles((endPos - startPos):Angle())
		plane:SetMoveType(MOVETYPE_FLY)
		plane:Spawn()
		plane:Activate()
		
		print("[Airstrike] Спавн самолета: " .. plane:GetModel() .. " на " .. tostring(startPos))
		
		local speed = 3000
		local duration = startPos:Distance(endPos) / speed
		local dropped = false
		local startTime = CurTime()
		
		plane:EmitSound("su25/su25.wav", 150, 100, 1, CHAN_AUTO)

		timer.Create("AirstrikePlaneMove_" .. plane:EntIndex(), 0.05, 0, function()
			if (!IsValid(plane)) then return end
			local elapsed = CurTime() - startTime
			local frac = elapsed / duration
			if (frac >= 1) then
				plane:StopSound("su25/su25.wav")
				plane:Remove()
				timer.Remove("AirstrikePlaneMove_" .. plane:EntIndex())
				return
			end
			plane:SetPos(LerpVector(frac, startPos, endPos))
			if (!dropped and frac >= 0.5) then
				dropped = true
				self:DropBomb(plane:GetPos(), plane:GetForward() * speed)
			end
		end)
	end)
end

function PLUGIN:DropBomb(pos, velocity)
	local bomb = ents.Create("sw_bomb_fab250m62_v3")
	if (!IsValid(bomb)) then
		-- Если энтити нет, создадим обычный взрыв для теста
		local exp = ents.Create("env_explosion")
		exp:SetPos(pos)
		exp:SetKeyValue("iMagnitude", "300")
		exp:Spawn()
		exp:Fire("Explode", 0, 0)
		return
	end
	
	bomb:SetPos(pos)
	bomb:SetAngles(velocity:Angle())
	bomb:Spawn()
	bomb:Activate()
	
	local phys = bomb:GetPhysicsObject()
	if (IsValid(phys)) then
		phys:SetVelocity(velocity)
	end
end

function PLUGIN:DropCrate(pos, weapon)
	if (!weapon) then
		local weaponsConfig = ix.config.Get("airdropWeapons", "")
		local weapons = {}

		if (type(weaponsConfig) == "string" and weaponsConfig:Trim() != "") then
			for _, v in pairs(string.Split(weaponsConfig, "\n")) do
				local s = v:Trim()
				if (s != "") then
					table.insert(weapons, s)
				end
			end
		end
		
		-- Если конфиг пустой или старый, берем список по умолчанию
		if (#weapons == 0) then
			weapons = {
				"tacrp_io_degala",
				"tacrp_io_fiveseven",
				"tacrp_mr96",
				"tacrp_pdw",
				"tacrp_superv",
				"tacrp_sd_aac_hb",
				"tacrp_ak_ak12",
				"tacrp_ak_an94",
				"tacrp_sg551",
				"tacrp_io_xm8car",
				"tacrp_hk417",
				"tacrp_io_scarh",
				"tacrp_mg4",
				"tacrp_io_xm8lmg",
				"tacrp_io_sg550r",
				"tacrp_io_sl8",
				"tacrp_io_sg550",
				"tacrp_io_vss",
				"tacrp_as50",
				"tacrp_ex_hecate",
				"tacrp_civ_m320"
			}
		end
		
		weapon = weapons[math.random(#weapons)]
	end

	local crate = ents.Create("ix_airdrop")
	if (!IsValid(crate)) then
		print("[Airdrop] ОШИБКА: Не удалось создать энтити ix_airdrop!")
		return
	end
	crate:SetPos(pos)
	crate:SetAngles(Angle(0, math.random(0, 360), 0))
	crate:Spawn()
	crate.ixWeapon = weapon
	
	-- Создаем парашют
	util.PrecacheModel("models/jessev92/bf2/parachute.mdl")
	local parachute = ents.Create("prop_dynamic")
	parachute:SetModel("models/jessev92/bf2/parachute.mdl")
	parachute:SetPos(crate:GetPos() + Vector(0, 0, 50))
	parachute:SetParent(crate)
	parachute:Spawn()
	crate.ixParachute = parachute

	local phys = crate:GetPhysicsObject()
	if (IsValid(phys)) then
		phys:Wake()
		phys:SetVelocity(Vector(0, 0, -200)) -- Скорость падения
		phys:SetDragCoefficient(5)
		phys:SetAngleDragCoefficient(100)
	end

	local function StartSmoke()
		if (!IsValid(crate)) then return end
		local smoke = ents.Create("env_smokestack")
		smoke:SetPos(crate:GetPos())
		smoke:SetAngles(Angle(-90, 0, 0))
		smoke:SetKeyValue("InitialState", "1")
		smoke:SetKeyValue("rendercolor", "255 100 0") 
		smoke:SetKeyValue("renderamt", "255")
		smoke:SetKeyValue("SmokeMaterial", "particle/smokesprites_0001.vmt")
		smoke:SetKeyValue("BaseSpread", "20")
		smoke:SetKeyValue("SpreadSpeed", "10")
		smoke:SetKeyValue("Speed", "80")
		smoke:SetKeyValue("StartSize", "30")
		smoke:SetKeyValue("EndSize", "120")
		smoke:SetKeyValue("Rate", "40")
		smoke:SetKeyValue("JetLength", "300")
		smoke:Spawn()
		smoke:Activate()
		smoke:SetParent(crate)
		crate.ixSmoke = smoke
		ix.util.Notify("Аирдроп приземлился! Ищите оранжевый дым.", nil, "all")
	end

	-- Принудительно держим ящик ровно во время падения
	timer.Create("AirdropUpright_" .. crate:EntIndex(), 0.1, 0, function()
		if (!IsValid(crate)) then 
			timer.Remove("AirdropUpright_" .. crate:EntIndex())
			return 
		end
		
		local phys = crate:GetPhysicsObject()
		if (IsValid(phys) and phys:IsMotionEnabled()) then
			crate:SetAngles(Angle(0, crate:GetAngles().y, 0))
			phys:SetAngleVelocity(Vector(0, 0, 0))
		else
			timer.Remove("AirdropUpright_" .. crate:EntIndex())
		end
	end)

	timer.Create("AirdropLand_" .. crate:EntIndex(), 0.2, 0, function()
		if (!IsValid(crate)) then 
			timer.Remove("AirdropLand_" .. crate:EntIndex())
			return 
		end
		local phys = crate:GetPhysicsObject()
		if (!IsValid(phys)) then return end

		-- Если скорость мала или мы коснулись земли
		local tr = util.TraceLine({
			start = crate:GetPos() + Vector(0, 0, 10),
			endpos = crate:GetPos() - Vector(0, 0, 40),
			filter = crate
		})

		if (tr.Hit or phys:GetVelocity():Length() < 5) then
			phys:EnableMotion(false)
			crate:SetPos(tr.HitPos)
			crate:SetAngles(Angle(0, crate:GetAngles().y, 0))
			
			if (IsValid(crate.ixParachute)) then
				crate.ixParachute:Remove()
			end

			StartSmoke()
			timer.Remove("AirdropLand_" .. crate:EntIndex())
			timer.Remove("AirdropUpright_" .. crate:EntIndex())
		end
	end)

	timer.Simple(900, function()
		if (IsValid(crate)) then
			if (IsValid(crate.ixSmoke)) then crate.ixSmoke:Remove() end
			crate:Remove()
		end
	end)
end

function PLUGIN:Initialize()
	self:SetupAirdropTimer()
	self:SetupAirstrikeTimer()
end

function PLUGIN:SetupAirdropTimer()
	local delay = math.random(ix.config.Get("airdropMinInterval", 3600), ix.config.Get("airdropMaxInterval", 7200))
	timer.Create("ixAirdropTimer", delay, 1, function()
		self:SpawnAirdrop()
		self:SetupAirdropTimer()
	end)
end

function PLUGIN:SetupAirstrikeTimer()
	local delay = math.random(ix.config.Get("airstrikeMinInterval", 1800), ix.config.Get("airstrikeMaxInterval", 3600))
	timer.Create("ixAirstrikeTimer", delay, 1, function()
		self:SpawnAirstrike()
		self:SetupAirstrikeTimer()
	end)
end
