local PLUGIN = PLUGIN

PLUGIN.factionPoints = PLUGIN.factionPoints or {}
PLUGIN.spawnPoints = PLUGIN.spawnPoints or {}
PLUGIN.activeVehicles = PLUGIN.activeVehicles or {} -- Таблица для отслеживания активной техники

function PLUGIN:LoadData()
    local data = self:GetData() or {}
    
    -- Загрузка очков фракций
    if type(data) == "table" and data.factionPoints then
        self.factionPoints = data.factionPoints
    elseif type(data) == "table" and not data.factionPoints then
        -- Старый формат (только очки)
        self.factionPoints = data
    else
        self.factionPoints = {}
    end
    
    -- Загрузка терминалов
    if data.terminals then
        for _, v in ipairs(data.terminals) do
            local terminal = ents.Create(v.class or "ix_vehicle_terminal_ground")
            if IsValid(terminal) then
                terminal:SetPos(v.pos)
                terminal:SetAngles(v.angles)
                terminal:Spawn()
                
                local phys = terminal:GetPhysicsObject()
                if IsValid(phys) then
                    phys:EnableMotion(false)
                end
            end
        end
    end
    
    -- Загрузка точек спавна из конфига
    local mapName = game.GetMap()
    local spawnPointsForMap = self.config.spawnPoints[mapName]
    if spawnPointsForMap then
        self.spawnPoints = type(spawnPointsForMap) == "function" and spawnPointsForMap() or spawnPointsForMap
    else
        self.spawnPoints = {}
    end
    
    local factions = self.config.getFactions and self.config.getFactions() or self.config.factions or {}
    for factionID, factionConfig in pairs(factions) do
        if not self.factionPoints[factionID] then
            self.factionPoints[factionID] = factionConfig.points or 1000
        end
    end

    -- Прекеширование LVS классов техники: создаём и сразу удаляем каждый класс,
    -- чтобы LVS инициализировал их заранее и при первом спавне игроком всё работало
    timer.Simple(5, function()
        local precached = {}
        for _, factionConfig in pairs(factions) do
            for _, vehicleList in pairs({factionConfig.groundVehicles or {}, factionConfig.airVehicles or {}}) do
                for _, vehConfig in pairs(vehicleList) do
                    local class = vehConfig.class
                    if class and not precached[class] then
                        local ent = ents.Create(class)
                        if IsValid(ent) then
                            ent:SetPos(Vector(0, 0, -10000)) -- далеко под картой
                            ent:Spawn()
                            ent:Activate()
                            SafeRemoveEntityDelayed(ent, 1) -- удаляем через секунду после инициализации
                            precached[class] = true
                            print("[LVS] Прекешировано: " .. class)
                        end
                    end
                end
            end
        end
        print("[LVS] Прекеширование завершено, классов: " .. table.Count(precached))
    end)
end

function PLUGIN:GetFactions()
    if not self.cachedFactions then
        self.cachedFactions = self.config.getFactions and self.config.getFactions() or self.config.factions or {}
    end
    return self.cachedFactions
end

function PLUGIN:SaveData()
	local data = {
		terminals = {}
	}
	
	-- Сохраняем все терминалы
	for _, entity in ipairs(ents.FindByClass("ix_vehicle_terminal_ground")) do
		if IsValid(entity) then
			data.terminals[#data.terminals + 1] = {
				class = "ix_vehicle_terminal_ground",
				pos = entity:GetPos(),
				angles = entity:GetAngles()
			}
		end
	end
	
	for _, entity in ipairs(ents.FindByClass("ix_vehicle_terminal_air")) do
		if IsValid(entity) then
			data.terminals[#data.terminals + 1] = {
				class = "ix_vehicle_terminal_air",
				pos = entity:GetPos(),
				angles = entity:GetAngles()
			}
		end
	end
	
	self:SetData(data)
end

function PLUGIN:GetFactionPoints(faction)
    local points = self.factionPoints[faction] or 0
    local maxPoints = (self.config and self.config.maxPoints) or 20000
    return math.min(points, maxPoints)
end

function PLUGIN:AddFactionPoints(faction, amount)
    if not self.factionPoints[faction] then
        self.factionPoints[faction] = 0
    end
    
    local maxPoints = (self.config and self.config.maxPoints) or 20000 
    self.factionPoints[faction] = math.Clamp(self.factionPoints[faction] + amount, 0, maxPoints)
    self:SyncFactionPoints(faction)
    
    -- Логирование изменения очков техники
    local serverlogsPlugin = ix.plugin.list["serverlogs"]
    if (serverlogsPlugin) then
        local factionName = ix.faction.Get(faction).name or tostring(faction)
        if amount > 0 then
            local message = string.format("Фракция '%s' получила +%d очков техники (итого: %d)", factionName, amount, self.factionPoints[faction])
            serverlogsPlugin:AddLog("VEHICLE_POINTS_ADD", message, nil, {
                faction = faction,
                factionName = factionName,
                amount = amount,
                total = self.factionPoints[faction]
            })
        elseif amount < 0 then
            local message = string.format("Фракция '%s' потратила %d очков техники (итого: %d)", factionName, math.abs(amount), self.factionPoints[faction])
            serverlogsPlugin:AddLog("VEHICLE_POINTS_USE", message, nil, {
                faction = faction,
                factionName = factionName,
                amount = math.abs(amount),
                total = self.factionPoints[faction]
            })
        end
    end
    
    return self.factionPoints[faction]
end

function PLUGIN:SyncFactionPoints(faction)
    net.Start("LVS_SyncFactionPoints")
        net.WriteUInt(faction, 8)
        net.WriteUInt(self.factionPoints[faction] or 0, 32)
    net.Broadcast()
end

function PLUGIN:GetSpawnPoints(faction, vehicleType, podr)
    local validPoints = {}
    local podrPoints = {} -- Точки, специфичные для подразделения
    
    for _, point in pairs(self.spawnPoints) do
        if istable(point) and point.factions and point.factions[faction] then
            -- Проверяем тип техники
            local validType = false
            if point.vehicleTypes then
                for _, allowedType in ipairs(point.vehicleTypes) do
                    if allowedType == vehicleType then
                        validType = true
                        break
                    end
                end
            else
                validType = true
            end
            
            if validType then
                -- Если у точки есть привязка к подразделениям
                if point.allowedPodr then
                    if podr and point.allowedPodr[podr] then
                        table.insert(podrPoints, point)
                    end
                else
                    -- Точка без привязки к подразделению — доступна всем
                    table.insert(validPoints, point)
                end
            end
        end
    end
    
    -- Если есть точки для конкретного подразделения — используем их
    -- Иначе — используем общие точки фракции
    if #podrPoints > 0 then
        return podrPoints
    end
    
    return validPoints
end

function PLUGIN:FindSpawnPosition(player, spawnSettings, vehicleType)
    local faction = player:Team()
    
    if spawnSettings.useSpawnPoints then
        local spawnPoints = self:GetSpawnPoints(faction, vehicleType)
        
        if #spawnPoints > 0 then
            local point = spawnPoints[math.random(1, #spawnPoints)]
            
            local angle = math.random(0, 360)
            local distance = math.random(0, spawnSettings.spawnPointRadius)
            local offset = Vector(
                math.cos(angle) * distance,
                math.sin(angle) * distance,
                0
            )
            
            local spawnPos = point.pos + offset + Vector(0, 0, spawnSettings.spawnHeight)
            
            local traceCheck = util.TraceHull({
                start = spawnPos,
                endpos = spawnPos,
                mins = Vector(-130, -130, 20),
                maxs = Vector(130, 130, 180),
                filter = function(ent)
                    if ent == player or ent:GetClass() == "lvs_vehicle_repair" then return false end
                    return true
                end
            })
            
            if not traceCheck.Hit then
                return spawnPos, point.ang
            end
        end
    end
    
    local trace = util.TraceLine({
        start = player:GetShootPos(),
        endpos = player:GetShootPos() + player:GetAimVector() * spawnSettings.maxDistance,
        filter = player
    })
    
    if trace.Hit then
        local spawnPos = trace.HitPos + Vector(0, 0, spawnSettings.spawnHeight)
        
        local traceCheck = util.TraceHull({
            start = spawnPos,
            endpos = spawnPos,
            mins = Vector(-130, -130, 20),
            maxs = Vector(130, 130, 180),
            filter = function(ent)
                if ent == player or ent:GetClass() == "lvs_vehicle_repair" then return false end
                return true
            end
        })
        
        if not traceCheck.Hit then
            return spawnPos, player:GetAngles()
        end
    end
    
    return nil
end

function PLUGIN:SpawnVehicle(player, vehicleID, vehicleType, loadoutVariant)
    if not IsValid(player) then print("[LVS DEBUG] FAIL: player not valid") return false, "Игрок не валиден" end
    
    local character = player:GetCharacter()
    if not character then print("[LVS DEBUG] FAIL: no character") return false, "Персонаж не найден" end
    
    local faction = player:Team()
    local factionConfig = PLUGIN:GetFactions()[faction]
    
    print("[LVS DEBUG] Player:", player:Nick(), "Faction:", faction, "VehicleID:", vehicleID, "Type:", vehicleType)
    print("[LVS DEBUG] FactionConfig exists:", factionConfig ~= nil)
    
    loadoutVariant = loadoutVariant or 0
    
    if not factionConfig then
        print("[LVS DEBUG] FAIL: no factionConfig for faction", faction)
        print("[LVS DEBUG] Available factions:")
        for k, v in pairs(PLUGIN:GetFactions()) do
            print("[LVS DEBUG]   faction key:", k, "name:", v.name)
        end
        return false, "Ваша фракция не может вызывать технику"
    end
    
    -- Проверка подразделения
    local playerSubdivision = character:GetPodr()
    print("[LVS DEBUG] PlayerSubdivision:", playerSubdivision)
    
    -- Проверяем массив разрешенных подразделений для конкретной техники
    local vehicles = vehicleType == "ground" and factionConfig.groundVehicles or factionConfig.airVehicles
    local vehicleConfig = vehicles[vehicleID]
    
    if not vehicleConfig then
        print("[LVS DEBUG] FAIL: vehicleConfig not found for ID:", vehicleID)
        print("[LVS DEBUG] Available vehicles:")
        for k, v in pairs(vehicles) do
            print("[LVS DEBUG]   ", k, "->", v.name)
        end
        return false, "Техника не найдена"
    end
    
    if vehicleConfig.allowedPodr and istable(vehicleConfig.allowedPodr) then
        if not vehicleConfig.allowedPodr[playerSubdivision] then
            -- Получаем названия разрешенных подразделений
            local podrNames = {}
            local factionTable = ix.faction.Get(faction)
            
            if factionTable and factionTable.Podr then
                for podrID, _ in pairs(vehicleConfig.allowedPodr) do
                    local podrData = factionTable.Podr[podrID]
                    if podrData and podrData.name then
                        table.insert(podrNames, podrData.name)
                    end
                end
            end
            
            if #podrNames > 0 then
                return false, "Эту технику могут вызывать только: " .. table.concat(podrNames, ", ")
            else
                return false, "Эта техника недоступна для вашего подразделения"
            end
        end
    end
    
    local factionPoints = self:GetFactionPoints(faction)
    if factionPoints < vehicleConfig.price then
        print("[LVS DEBUG] FAIL: not enough points. Has:", factionPoints, "Need:", vehicleConfig.price)
        return false, "Недостаточно очков техники у фракции"
    end
    
    local vehiclesData = character:GetData("lvs_vehicles", {})
    local lastSpawn = vehiclesData[vehicleID]
    
    if lastSpawn and lastSpawn > os.time() then
        local remaining = lastSpawn - os.time()
        local minutes = math.floor(remaining / 60)
        local seconds = math.floor(remaining % 60)
        return false, "Техника в кд: " .. string.format("%02d:%02d", minutes, seconds)
    end

    local spawnSettings = PLUGIN.config.spawnSettings[vehicleType] or PLUGIN.config.spawnSettings.ground

    -- Попытаемся взять точку спавна из конфигурации (если такие точки заданы для карты)
    local spawnPos, spawnAng = nil, nil
    local spawnPointUsed = nil
    local validPoints = self:GetSpawnPoints(faction, vehicleType, playerSubdivision)
    print("[LVS DEBUG] SpawnPoints found:", #validPoints, "for faction:", faction, "type:", vehicleType, "podr:", tostring(playerSubdivision))
    -- Требуем, чтобы для карты были настроены точки спавна
    if not validPoints or #validPoints == 0 then
        print("[LVS DEBUG] FAIL: no spawn points!")
        print("[LVS DEBUG] Total spawnPoints loaded:", table.Count(self.spawnPoints))
        for i, sp in pairs(self.spawnPoints) do
            if istable(sp) then
                print("[LVS DEBUG]   point", i, "id:", sp.id, "factions:", table.ToString(sp.factions or {}), "types:", table.ToString(sp.vehicleTypes or {}), "podr:", table.ToString(sp.allowedPodr or {}))
            end
        end
        return false, "На этой карте не настроены точки спавна техники"
    end

    local effectiveSpawnHeight = spawnSettings.spawnHeight
    if vehicleType == "air" then
        effectiveSpawnHeight = 20 
    end

    local function IsPosClear(pos)
        local traceCheck = util.TraceHull({
            start = pos,
            endpos = pos,
            mins = Vector(-70, -70, 30), -- Еще меньше, чтобы танки с длинными дулами или широкие машины не цепляли стены
            maxs = Vector(70, 70, 100),
            mask = MASK_SOLID,
            filter = function(ent)
                if ent == player then return false end
                
                local class = ent:GetClass()
                -- Игнорируем ремонтные станции и терминалы
                if class == "lvs_vehicle_repair" or class:find("ix_vehicle_terminal") then 
                    return false 
                end
                
                return true
            end
        })
        
        if traceCheck.Hit then
            if IsValid(traceCheck.Entity) then
                print("[LVS DEBUG] Точка спавна заблокирована энтити: " .. traceCheck.Entity:GetClass())
            else
                print("[LVS DEBUG] Точка спавна заблокирована картой (World/Brush)!")
            end
        end
        
        return not traceCheck.Hit and not traceCheck.StartSolid
    end

    -- Сначала пробуем найти свободную точку среди всех доступных
    for _, p in ipairs(validPoints) do
        -- 1. Сначала пробуем ровно в центре точки (без смещения)
        local testPos = p.pos + Vector(0, 0, effectiveSpawnHeight)
        if IsPosClear(testPos) then
            spawnPos = testPos
            spawnAng = p.ang or player:GetAngles()
            spawnPointUsed = p
            break
        end

        -- 2. Если центр занят, пробуем 5 случайных смещений в радиусе
        local radius = spawnSettings.spawnPointRadius or 0
        if radius > 0 then
            for i = 1, 5 do
                local angle = math.random(0, 360)
                local distance = math.random(50, radius)
                local offset = Vector(math.cos(angle) * distance, math.sin(angle) * distance, 0)
                local offsetPos = p.pos + offset + Vector(0, 0, effectiveSpawnHeight)

                if IsPosClear(offsetPos) then
                    spawnPos = offsetPos
                    spawnAng = p.ang or player:GetAngles()
                    spawnPointUsed = p
                    break
                end
            end
        end
        
        if spawnPos then break end
    end

    if not spawnPos then
        return false, "Все точки спавна заняты или заблокированы препятствиями"
    end
    
    -- Создаём технику (проверка класса через IsValid после создания)
    
    local vehicle = ents.Create(vehicleConfig.class)
    if not IsValid(vehicle) then
        return false, "Ошибка создания техники"
    end
    
    vehicle:SetPos(spawnPos)
    vehicle:SetAngles(spawnAng or player:GetAngles())
    
    vehicle:Spawn()
    
    -- Для LVS транспорта нужен Activate после Spawn
    if vehicle.LVS then
        vehicle:Activate()
    end

    timer.Simple(1, function()
        if not IsValid(vehicle) then return end
        
        if vehicle.Loadouts and loadoutVariant then
            local loadoutID = tonumber(loadoutVariant) or 1
            print("[LVS] Применяю loadout ID=" .. loadoutID .. " для техники " .. vehicleConfig.name)
            vehicle:SetLoadout(loadoutID)
        end
    end)

    local chosenSkin = nil
    if istable(vehicleConfig.skin) and next(vehicleConfig.skin or {}) ~= nil then
        if vehicleConfig.skin[faction] ~= nil then
            chosenSkin = vehicleConfig.skin[faction]
        else
            for k, v in pairs(vehicleConfig.skin) do
                if tostring(k) == tostring(faction) then
                    chosenSkin = v
                    break
                end
            end
        end
    end

    if chosenSkin == nil and vehicleConfig.default_skin ~= nil then
        chosenSkin = vehicleConfig.default_skin
    end

    if chosenSkin ~= nil then
        pcall(function() vehicle:SetSkin(chosenSkin) end)
    end

    if istable(vehicleConfig.default_bodygroups) then
        for _, bg in ipairs(vehicleConfig.default_bodygroups) do
            if bg and bg.id and bg.value then
                pcall(function()
                    vehicle:SetBodygroup(bg.id, bg.value)
                end)
            end
        end
    end

    if istable(vehicleConfig.bodygroups) then
        for k, v in pairs(vehicleConfig.bodygroups) do
            if isnumber(k) and istable(v) and v.id and v.value then
                pcall(function() vehicle:SetBodygroup(v.id, v.value) end)
            elseif isnumber(k) and isnumber(v) then
                pcall(function() vehicle:SetBodygroup(k, v) end)
            end
        end
    end

    -- Сохраняем информацию о технике для возможности возврата
    local vehicleInfo = {
        owner = player,
        ownerSteamID = player:SteamID(),
        vehicleID = vehicleID,
        vehicleType = vehicleType,
        vehicleConfig = vehicleConfig,
        spawnTime = os.time(),
        faction = faction,
        appliedSkin = chosenSkin,
        appliedBodygroups = vehicleConfig.default_bodygroups,
        appliedLoadout = loadoutVariant,
        lastUse = CurTime()
    }
    -- Сохраняем использованную точку спавна (если была)
    if spawnPointUsed and spawnPointUsed.pos then
        vehicleInfo.spawnPoint = spawnPointUsed.pos
        vehicleInfo.spawnPointAng = spawnPointUsed.ang
        vehicleInfo.spawnPointID = spawnPointUsed.id
    end
    
    vehicle.lvsVehicleInfo = vehicleInfo
    self.activeVehicles[vehicle] = vehicleInfo

    -- Устанавливаем сетевые переменные на сущности, чтобы клиенты могли узнать данные даже если net сообщение не доспело
    pcall(function()
        vehicle:SetNWString("LVS_OwnerSteamID", vehicleInfo.ownerSteamID or "")
        vehicle:SetNWString("LVS_VehicleID", tostring(vehicleInfo.vehicleID or ""))
        vehicle:SetNWString("LVS_VehicleType", tostring(vehicleInfo.vehicleType or ""))
    end)

    -- Синхронизируем информацию с клиентом
    self:SyncVehicleInfo(vehicle)

    self:AddFactionPoints(faction, -vehicleConfig.price)
    
    vehiclesData[vehicleID] = os.time() + vehicleConfig.cooldown
    character:SetData("lvs_vehicles", vehiclesData)
    
    self:NotifyFaction(faction, player:Name() .. " вызвал " .. vehicleConfig.name .. " за " .. vehicleConfig.price .. " очков")
    
    -- Логирование вызова техники
    local serverlogsPlugin = ix.plugin.list["serverlogs"]
    if (serverlogsPlugin) then
        local factionName = ix.faction.Get(faction).name or tostring(faction)
        local message = string.format("%s вызвал технику '%s' (стоимость: %d очков техники)", 
            player:Nick(), vehicleConfig.name, vehicleConfig.price)
        serverlogsPlugin:AddLog("VEHICLE_SPAWN", message, player, {
            vehicleID = vehicleID,
            vehicleName = vehicleConfig.name,
            vehicleClass = vehicleConfig.class,
            vehicleType = vehicleType,
            price = vehicleConfig.price,
            faction = faction,
            factionName = factionName
        })
    end
    
    print(player:Name() .. " вызвал " .. vehicleConfig.name .. " (" .. vehicleType .. ")")
    
    return true, vehicleConfig.name .. " успешно вызвана!"
end

-- Функция возврата техники
function PLUGIN:ReturnVehicle(vehicle, player)
    if not IsValid(vehicle) or not self.activeVehicles[vehicle] then
        return false, "Техника не найдена"
    end
    
    local vehicleInfo = self.activeVehicles[vehicle]

    -- Проверка: Можно ли вернуть технику по месту спавна (если точка сохранена)
    local maxDist = PLUGIN.config.returnSettings and PLUGIN.config.returnSettings.maxReturnDistance or 200
    if vehicleInfo.spawnPoint then
        local curPos = vehicle:GetPos()
        local dist = curPos:DistToSqr(vehicleInfo.spawnPoint)
        if dist > (maxDist * maxDist) and not player:IsAdmin() then
            return false, "Техника находится слишком далеко от точки возврата"
        end
    end
    
    -- Проверяем, может ли игрок вернуть эту технику
    if not player:IsAdmin() and player:SteamID() ~= vehicleInfo.ownerSteamID then
        return false, "Вы не можете вернуть чужую технику"
    end
    
    local faction = vehicleInfo.faction
    local vehicleConfig = vehicleInfo.vehicleConfig
    local refundAmount = math.floor(vehicleConfig.price * 0.8) -- Возвращаем 80% стоимости
    
    -- Возвращаем очки фракции
    self:AddFactionPoints(faction, refundAmount)
    
    -- Сбрасываем кд для владельца
    if IsValid(vehicleInfo.owner) then
        local character = vehicleInfo.owner:GetCharacter()
        if character then
            local vehiclesData = character:GetData("lvs_vehicles", {})
            vehiclesData[vehicleInfo.vehicleID] = nil
            character:SetData("lvs_vehicles", vehiclesData)
            
            vehicleInfo.owner:Notify("Вы вернули " .. vehicleConfig.name .. ". Возвращено " .. refundAmount .. " очков техники")
        end
    end
    
    -- Удаляем технику
    vehicle:Remove()
    self.activeVehicles[vehicle] = nil
    
    -- Уведомляем фракцию
    local returnMessage = player:Name() .. " вернул " .. vehicleConfig.name .. ". Возвращено " .. refundAmount .. " очков техники"
    self:NotifyFaction(faction, returnMessage)
    
    -- Логирование возврата техники
    local serverlogsPlugin = ix.plugin.list["serverlogs"]
    if (serverlogsPlugin) then
        local factionName = ix.faction.Get(faction).name or tostring(faction)
        local message = string.format("%s вернул технику '%s' (возврат: %d очков техники)", 
            player:Nick(), vehicleConfig.name, refundAmount)
        serverlogsPlugin:AddLog("VEHICLE_RETURN", message, player, {
            vehicleID = vehicleInfo.vehicleID,
            vehicleName = vehicleConfig.name,
            vehicleClass = vehicleConfig.class,
            refundAmount = refundAmount,
            faction = faction,
            factionName = factionName
        })
    end
    
    print(returnMessage)
    
    return true, vehicleConfig.name .. " успешно возвращена. Возвращено " .. refundAmount .. " очков"
end

-- Функция автоматической очистки уничтоженной техники
function PLUGIN:VehicleDestroyed(vehicle)
    if self.activeVehicles[vehicle] then
        self.activeVehicles[vehicle] = nil
    end
end

-- Функция синхронизации информации о технике
function PLUGIN:SyncVehicleInfo(vehicle)
    if not IsValid(vehicle) or not vehicle.lvsVehicleInfo then return end
    
    local info = vehicle.lvsVehicleInfo
    
    -- Отправляем информацию всем клиентам
    net.Start("LVS_SyncVehicleInfo")
        net.WriteEntity(vehicle)
        net.WriteString(info.ownerSteamID or "")
        net.WriteString(info.vehicleID or "")
        net.WriteString(info.vehicleType or "")
    net.Broadcast()
end

function PLUGIN:NotifyFaction(faction, message)
    for _, v in ipairs(player.GetAll()) do
        if v:Team() == faction then
            v:Notify(message)
        end
    end
end

util.AddNetworkString("LVS_SyncFactionPoints")
util.AddNetworkString("LVS_OpenGroundMenu")
util.AddNetworkString("LVS_OpenAirMenu")
util.AddNetworkString("LVS_RequestSpawn")
util.AddNetworkString("LVS_RequestReturn")
util.AddNetworkString("LVS_SyncVehicleInfo")
util.AddNetworkString("LVS_SyncVehicleModels")

net.Receive("LVS_RequestSpawn", function(len, player)
    local vehicleID = net.ReadString()
    local vehicleType = net.ReadString()
    local loadoutVariant = net.ReadUInt(8)
    
    print("[LVS] Запрос спавна от " .. player:Name() .. " - ID: " .. vehicleID .. ", Тип: " .. vehicleType .. ", LoadoutID: " .. loadoutVariant)
    
    local success, message = PLUGIN:SpawnVehicle(player, vehicleID, vehicleType, loadoutVariant)
    player:Notify(message)
end)

-- Обработка запроса на возврат техники
net.Receive("LVS_RequestReturn", function(len, player)
    local vehicleIndex = net.ReadUInt(16)
    -- Логирование для отладки
    print("[LVS] Received LVS_RequestReturn from ", player:Nick(), " (SteamID: ", player:SteamID(), ") with index:", vehicleIndex)
    local vehicle = Entity(vehicleIndex)
    if not IsValid(vehicle) then
        player:Notify("Техника не найдена (индекс: " .. tostring(vehicleIndex) .. ")")
        print("[LVS] Entity is not valid for index:", vehicleIndex)
        return
    end

    local success, message = PLUGIN:ReturnVehicle(vehicle, player)
    -- Сообщаем игроку подробное сообщение
    if success then
        player:Notify(message)
    else
        player:Notify(message or "Не удалось вернуть технику")
    end
end)

-- Хук для удаления уничтоженной техники
hook.Add("EntityRemoved", "LVS_VehicleCleanup", function(ent)
    if PLUGIN.activeVehicles[ent] then
        PLUGIN:VehicleDestroyed(ent)
    end
end)

-- Хук автоудаления обломков взорванной техники через 5 минут
local WRECK_LIFETIME = 300 -- 5 минут в секундах
hook.Add("OnEntityCreated", "LVS_WreckAutoRemove", function(ent)
    -- Даем энтити немного времени на инициализацию класса
    timer.Simple(0.1, function()
        if IsValid(ent) and ent:GetClass() == "lvs_destruction" then
            timer.Simple(WRECK_LIFETIME, function()
                if IsValid(ent) then
                    ent:Remove()
                    print("[LVS] Обломки уничтоженной техники очищены (прошло 5 минут)")
                end
            end)
        end
    end)
end)

-- Система автоудаления неиспользуемой техники (10 минут)
timer.Create("LVS_UnusedVehicleCleanup", 30, 0, function()
    local currentTime = CurTime()
    local idleLimit = 600 -- 10 минут

    for vehicle, info in pairs(PLUGIN.activeVehicles) do
        if not IsValid(vehicle) then
            PLUGIN.activeVehicles[vehicle] = nil
            continue
        end

        -- Если в технике есть кто-то, обновляем время использования
        local hasOccupant = false
        if IsValid(vehicle:GetDriver()) then
            hasOccupant = true
        else
            if istable(vehicle.pSeats) then
                for _, seat in pairs(vehicle.pSeats) do
                    if IsValid(seat) and IsValid(seat:GetDriver()) then
                        hasOccupant = true
                        break
                    end
                end
            end
        end

        if hasOccupant then
            info.lastUse = currentTime
        else
            -- Если техника не занята, проверяем время простоя
            if (currentTime - (info.lastUse or currentTime)) >= idleLimit then
                local faction = info.faction
                local vehicleConfig = info.vehicleConfig
                local refundAmount = vehicleConfig.price -- Возвращаем полную стоимость при автоудалении

                -- Возвращаем очки фракции
                PLUGIN:AddFactionPoints(faction, refundAmount)

                -- Сбрасываем кд для владельца
                if IsValid(info.owner) then
                    local character = info.owner:GetCharacter()
                    if character then
                        local vehiclesData = character:GetData("lvs_vehicles", {})
                        vehiclesData[info.vehicleID] = nil
                        character:SetData("lvs_vehicles", vehiclesData)
                        
                        info.owner:Notify("Ваша техника " .. vehicleConfig.name .. " была удалена из-за простоя. Очки возвращены.")
                    end
                end
                
                -- Удаляем технику
                vehicle:Remove()
                PLUGIN.activeVehicles[vehicle] = nil

                -- Уведомляем фракцию
                PLUGIN:NotifyFaction(faction, "Техника " .. vehicleConfig.name .. " удалена из-за 10-минутного простоя. Очки возвращены.")

                -- Логирование
                local serverlogsPlugin = ix.plugin.list["serverlogs"]
                if (serverlogsPlugin) then
                    local factionName = ix.faction.Get(faction).name or tostring(faction)
                    local message = string.format("Техника '%s' удалена автоматически (простой 10 мин). Возвращено %d очков.", 
                        vehicleConfig.name, refundAmount)
                    serverlogsPlugin:AddLog("VEHICLE_AUTO_REMOVE", message, nil, {
                        vehicleName = vehicleConfig.name,
                        refundAmount = refundAmount,
                        faction = faction
                    })
                end

                print("[LVS] Техника " .. vehicleConfig.name .. " удалена автоматически за простой.")
            end
        end
    end
end)

-- Команда для возврата техники
ix.command.Add("returnvehicle", {
    description = "Вернуть технику и получить часть очков обратно",
    arguments = {
        ix.type.number
    },
    OnRun = function(self, client, vehicleIndex)
        local vehicle = Entity(tonumber(vehicleIndex))
        
        if not IsValid(vehicle) then
            return "Техника с индексом " .. vehicleIndex .. " не найдена"
        end
        
        local success, message = PLUGIN:ReturnVehicle(vehicle, client)
        return message
    end
})

-- Команда для просмотра активной техники
ix.command.Add("listvehicles", {
    description = "Показать активную технику",
    adminOnly = true,
    OnRun = function(self, client)
        local count = 0
        local result = "Активная техника:\n"
        
        for vehicle, info in pairs(PLUGIN.activeVehicles) do
            if IsValid(vehicle) then
                count = count + 1
                local ownerName = IsValid(info.owner) and info.owner:Name() or "Неизвестно"
                result = result .. count .. ". " .. info.vehicleConfig.name .. " (ID: " .. vehicle:EntIndex() .. ") - Владелец: " .. ownerName .. "\n"
            else
                PLUGIN.activeVehicles[vehicle] = nil
            end
        end
        
        if count == 0 then
            return "Активной техники нет"
        end
        
        return result
    end
})

ix.command.Add("GiveVehiclePoints", {
    description = "Выдать очки техники фракции",
    adminOnly = true,
    arguments = {
        ix.type.string,
        ix.type.number
    },
    OnRun = function(self, client, factionName, amount)
        local targetFaction
        
        for factionID, config in pairs(PLUGIN:GetFactions()) do
            if string.lower(config.name) == string.lower(factionName) then
                targetFaction = factionID
                break
            end
        end
        
        if not targetFaction then
            return "Фракция не найдена. Доступные: Россия, Украина"
        end
        
        local newPoints = PLUGIN:AddFactionPoints(targetFaction, amount)
        local factionData = PLUGIN:GetFactions()[targetFaction]
        
        PLUGIN:NotifyFaction(targetFaction, "Администратор выдал " .. amount .. " очков техники фракции. Теперь: " .. newPoints)
        
        return "Выдано " .. amount .. " очков фракции " .. factionData.name .. ". Теперь: " .. newPoints
    end
})

ix.command.Add("SetVehiclePoints", {
    description = "Установить очки техники фракции",
    adminOnly = true,
    arguments = {
        ix.type.string,
        ix.type.number
    },
    OnRun = function(self, client, factionName, amount)
        local targetFaction
        
        for factionID, config in pairs(PLUGIN.config.factions) do
            if string.lower(config.name) == string.lower(factionName) then
                targetFaction = factionID
                break
            end
        end
        
        if not targetFaction then
            return "Фракция не найдена. Доступные: Россия, Украина"
        end
        
        PLUGIN.factionPoints[targetFaction] = amount
        PLUGIN:SyncFactionPoints(targetFaction)
        
        local factionData = PLUGIN:GetFactions()[targetFaction]
        PLUGIN:NotifyFaction(targetFaction, "Администратор установил очки техники на " .. amount)
        
        return "Установлено " .. amount .. " очков фракции " .. factionData.name
    end
})

ix.command.Add("CheckVehiclePoints", {
    description = "Проверить очки всех фракций",
    adminOnly = true,
    OnRun = function(self, client)
        local result = "Очки техники фракций:\n"
        
        for factionID, config in pairs(PLUGIN:GetFactions()) do
            local points = PLUGIN:GetFactionPoints(factionID)
            result = result .. config.name .. ": " .. points .. " очков\n"
        end
        
        return result
    end
})

ix.command.Add("ResetVehicleCooldowns", {
    description = "Сбросить кд техники для игрока",
    adminOnly = true,
    arguments = {
        ix.type.player
    },
    OnRun = function(self, client, target)
        local character = target:GetCharacter()
        if character then
            character:SetData("lvs_vehicles", {})
            target:Notify("Ваши кд техники были сброшены администратором")
            return "Кд техники сброшены для " .. target:Name()
        end
        
        return "Ошибка сброса кд"
    end
})

ix.command.Add("ResetAllVehicleCooldowns", {
    description = "Сбросить кд техники для всех игроков",
    adminOnly = true,
    OnRun = function(self, client)
        for _, ply in ipairs(player.GetAll()) do
            local character = ply:GetCharacter()
            if character then
                character:SetData("lvs_vehicles", {})
                ply:Notify("Кд техники сброшены администратором")
            end
        end
        
        return "Кд техники сброшены для всех игроков"
    end
})

function PLUGIN:InitializedPlugins()
    timer.Simple(5, function()
        for factionID, _ in pairs(self:GetFactions()) do
            self:SyncFactionPoints(factionID)
        end
        
        -- Синхронизируем существующую технику
        timer.Simple(2, function()
            for vehicle, _ in pairs(self.activeVehicles) do
                if IsValid(vehicle) then
                    self:SyncVehicleInfo(vehicle)
                else
                    self.activeVehicles[vehicle] = nil
                end
            end
        end)

        -- Подготовим таблицу моделей для клиентов: если в конфиге нет поля model, попробуем получить его из класса
        timer.Simple(1, function()
            local mapping = {}

            for factionID, factionConfig in pairs(self:GetFactions()) do
                mapping[factionID] = { ground = {}, air = {} }

                -- ground
                if factionConfig.groundVehicles then
                    for id, v in pairs(factionConfig.groundVehicles) do
                        local mdl = v.model
                        if not mdl or mdl == "" then
                            -- Попробуем создать временную сущность указанного класса, чтобы прочитать модель
                            if v.class then
                                local ok, ent = pcall(function() return ents.Create(v.class) end)
                                if ok and IsValid(ent) then
                                    mdl = ent:GetModel() or ""
                                    ent:Remove()
                                else
                                    mdl = ""
                                end
                            else
                                mdl = ""
                            end
                        end

                        mapping[factionID].ground[id] = mdl or ""
                    end
                end

                -- air
                if factionConfig.airVehicles then
                    for id, v in pairs(factionConfig.airVehicles) do
                        local mdl = v.model
                        if not mdl or mdl == "" then
                            if v.class then
                                local ok, ent = pcall(function() return ents.Create(v.class) end)
                                if ok and IsValid(ent) then
                                    mdl = ent:GetModel() or ""
                                    ent:Remove()
                                else
                                    mdl = ""
                                end
                            else
                                mdl = ""
                            end
                        end

                        mapping[factionID].air[id] = mdl or ""
                    end
                end
            end

            net.Start("LVS_SyncVehicleModels")
                net.WriteTable(mapping)
            net.Broadcast()
        end)
    end)
end

function PLUGIN:InitPostEntity()
    timer.Simple(10, function()
        for _, factionID in ipairs(ix.faction.indices) do
            local cur = self:GetFactionPoints(factionID) or 0
            if cur >= 50000 then -- If it's stuck on old limit/bug
                self.factionPoints[factionID] = 1000
                self:SyncFactionPoints(factionID)
            end
        end
    end)
end
