local PLUGIN = PLUGIN

-- Хранение выбранного loadout для каждой техники
local selectedLoadouts = {}

-- Цветовая схема (такая же как в арсенале)
local COLOR_BG_DARK = Color(3, 5, 4)
local COLOR_BG_MEDIUM = Color(8, 12, 10)
local COLOR_BG_LIGHT = Color(12, 18, 14)
local COLOR_PRIMARY = Color(27, 94, 32)
local COLOR_PRIMARY_DARK = Color(15, 60, 18)
local COLOR_ACCENT = Color(56, 102, 35)
local COLOR_TEXT_PRIMARY = Color(165, 214, 167)
local COLOR_TEXT_SECONDARY = Color(102, 187, 106)
local COLOR_DANGER = Color(136, 14, 14)
local COLOR_WARNING = Color(191, 130, 0)
local COLOR_BORDER = Color(15, 60, 18, 60)

-- Вспомогательная функция для рисования кругов
if not draw.Circle then
    function draw.Circle(x, y, radius, color)
        local segmentCount = math.max(16, radius)
        surface.SetDrawColor(color or color_white)
        
        local circle = {}
        for i = 0, segmentCount do
            local angle = math.rad((i / segmentCount) * 360)
            table.insert(circle, {
                x = x + math.cos(angle) * radius,
                y = y + math.sin(angle) * radius
            })
        end
        surface.DrawPoly(circle)
    end
end

if not surface.DrawCircle then
    function surface.DrawCircle(x, y, radius, color)
        draw.Circle(x, y, radius, color)
    end
end

PLUGIN.clientFactionPoints = {}
PLUGIN.selectedLoadouts = {} -- Глобальное хранилище выбранных loadout'ов

-- Проверка доступности техники для игрока
function PLUGIN:CanPlayerAccessVehicle(vehicleConfig)
    local character = LocalPlayer():GetCharacter()
    if not character then return false end
    
    local playerSubdivision = character:GetPodr()
    
    -- Если нет ограничений по подразделениям - доступно всем
    if not vehicleConfig.allowedPodr or not istable(vehicleConfig.allowedPodr) then
        return true
    end
    
    -- Проверяем доступность для подразделения игрока
    return vehicleConfig.allowedPodr[playerSubdivision] ~= nil
end

function PLUGIN:GetFactions()
    if not self.cachedFactions then
        if not self.config then
            -- Fallback to global if self.config is missing for some reason
            self.config = PLUGIN.config or {}
        end
        if not self.config or not istable(self.config) then
            self.cachedFactions = {}
        else
            self.cachedFactions = self.config.getFactions and self.config.getFactions() or self.config.factions or {}
        end
    end
    return self.cachedFactions
end

-- Сетевые сообщения
net.Receive("LVS_SyncFactionPoints", function()
    local faction = net.ReadUInt(8)
    local points = net.ReadUInt(32)
    PLUGIN.clientFactionPoints[faction] = points
end)

-- Открытие меню наземной техники
net.Receive("LVS_OpenGroundMenu", function()
    PLUGIN:OpenVehicleMenu("ground")
end)

-- Открытие меню воздушной техники  
net.Receive("LVS_OpenAirMenu", function()
    PLUGIN:OpenVehicleMenu("air")
end)

local function UpdateVehicleInfo(vehicleConfig, vehicleID, infoContent, modelPanel, vehicleName, vehicleDesc, vehiclePrice, vehicleCooldown, spawnBtn, factionPoints, vehicleType, returnBtn, loadoutPanel, updateLoadoutCallback)
    if not vehicleConfig then return end
    
    -- Инициализируем выбранный loadout если его нет (дефолтный = 1)
    if not PLUGIN.selectedLoadouts[vehicleID] then
        PLUGIN.selectedLoadouts[vehicleID] = 1
    end
    
    local faction = LocalPlayer():Team()
    local factions = PLUGIN:GetFactions()
    local factionConfig = factions and factions[faction]
    local character = LocalPlayer():GetCharacter()
    local playerSubdivision = character and character:GetPodr() or 1
    
    -- Проверяем доступность по подразделению
    local canSpawnBySubdivision = true
    local subdivisionMessage = ""
    
    -- Проверяем разрешенные подразделения и специализации
    if vehicleConfig.allowedPodr and istable(vehicleConfig.allowedPodr) then
        local playerSpec = character and character:GetSpec() or 1
        local podrConfig = vehicleConfig.allowedPodr[playerSubdivision]
        
        if podrConfig == nil then
            -- Подразделение не в списке
            canSpawnBySubdivision = false
        elseif podrConfig == true then
            -- Разрешено всем специализациям этого подразделения
            canSpawnBySubdivision = true
        elseif istable(podrConfig) then
            -- Проверяем специализацию
            canSpawnBySubdivision = table.HasValue(podrConfig, playerSpec)
        end
        
        if not canSpawnBySubdivision then
            -- Получаем названия разрешенных подразделений и специализаций
            local podrNames = {}
            local factionTable = ix.faction.Get(faction)
            
            if factionTable and factionTable.Podr and factionTable.Spec then
                for podrID, config in pairs(vehicleConfig.allowedPodr) do
                    local podrData = factionTable.Podr[podrID]
                    if podrData and podrData.name then
                        if config == true then
                            table.insert(podrNames, podrData.name)
                        elseif istable(config) then
                            local specNames = {}
                            for _, specID in ipairs(config) do
                                local specData = factionTable.Spec[specID]
                                if specData and specData.name then
                                    table.insert(specNames, specData.name)
                                end
                            end
                            if #specNames > 0 then
                                table.insert(podrNames, podrData.name .. " (" .. table.concat(specNames, ", ") .. ")")
                            end
                        end
                    end
                end
            end
            
            if #podrNames > 0 then
                subdivisionMessage = "Только: " .. table.concat(podrNames, "; ")
            else
                subdivisionMessage = "Недоступно для вашего подразделения"
            end
        end
    end
    
    -- Показываем элементы
    modelPanel:SetVisible(true)
    vehicleName:SetVisible(true)
    vehicleDesc:SetVisible(true)
    vehiclePrice:SetVisible(true)
    vehicleCooldown:SetVisible(true)
    spawnBtn:SetVisible(true)
    returnBtn:SetVisible(true)
    
    -- Устанавливаем модель
    modelPanel:SetModel(vehicleConfig.model)
    
    local ent = modelPanel.Entity
    if IsValid(ent) then
        local center = ent:OBBCenter()
        local distance = ent:BoundingRadius() * 1.5
        modelPanel:SetLookAt(center)
        modelPanel:SetCamPos(center + Vector(distance, distance, distance))
        modelPanel:SetFOV(50)
    end
    
    -- Устанавливаем текстовую информацию
    vehicleName:SetText(vehicleConfig.name)
    vehicleDesc:SetText(vehicleConfig.description)
    vehiclePrice:SetText("Стоимость: " .. vehicleConfig.price .. " очков техники")
    
    -- Проверяем кд и доступность
    local vehiclesData = character and character:GetData("lvs_vehicles", {}) or {}
    local lastSpawn = vehiclesData[vehicleID]
    local cooldown = lastSpawn and lastSpawn > os.time() and (lastSpawn - os.time()) or 0
    
    -- Проверяем, есть ли активная техника этого типа
    local hasActiveVehicle = PLUGIN:HasActiveVehicle(vehicleID, vehicleType)
    local refundAmount = math.floor(vehicleConfig.price * 0.8)
    
    -- Настраиваем кнопку возврата
    if hasActiveVehicle then
        returnBtn:SetEnabled(true)
        returnBtn:SetText("")
        returnBtn.Paint = function(s, w, h)
            local col = s:IsHovered() and Color(185, 60, 60) or Color(165, 85, 60)
            draw.RoundedBox(6, 0, 0, w, h, col)
            
            if s:IsHovered() then
                surface.SetDrawColor(255, 255, 255, 30)
                draw.RoundedBox(6, 2, 2, w-4, h-4, Color(255, 255, 255, 30))
            end
            
            surface.SetDrawColor(COLOR_BG_DARK)
            surface.DrawOutlinedRect(0, 0, w, h, 2)
            draw.SimpleText("◄ ВЕРНУТЬ (" .. refundAmount .. " очков)", "ixSmallFont", w/2, h/2, COLOR_TEXT_PRIMARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        end
        -- Отправляем запрос на возврат техники при нажатии кнопки
        returnBtn.DoClick = function()
            local veh = PLUGIN:GetActiveVehicle(vehicleID, vehicleType)
            if IsValid(veh) then
                net.Start("LVS_RequestReturn")
                    net.WriteUInt(veh:EntIndex(), 16)
                net.SendToServer()
            else
                LocalPlayer():Notify("Активная техника не найдена")
            end
        end
    else
        returnBtn:SetEnabled(false)
        returnBtn:SetText("")
        returnBtn.Paint = function(s, w, h)
            draw.RoundedBox(6, 0, 0, w, h, Color(60, 60, 60))
            surface.SetDrawColor(COLOR_BG_DARK)
            surface.DrawOutlinedRect(0, 0, w, h, 2)
            draw.SimpleText("НЕТ АКТИВНОЙ ТЕХНИКИ", "ixSmallFont", w/2, h/2, COLOR_TEXT_SECONDARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        end
    end
    
    if not canSpawnBySubdivision then
        vehicleCooldown:SetText(subdivisionMessage)
        vehicleCooldown:SetTextColor(COLOR_DANGER)
        spawnBtn:SetEnabled(false)
        spawnBtn:SetText("")
        spawnBtn.Paint = function(s, w, h)
            draw.RoundedBox(6, 0, 0, w, h, Color(60, 60, 60))
            surface.SetDrawColor(COLOR_BG_DARK)
            surface.DrawOutlinedRect(0, 0, w, h, 2)
            draw.SimpleText("НЕДОСТУПНО", "ixSmallFont", w/2, h/2, COLOR_TEXT_SECONDARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        end
    elseif cooldown > 0 then
        local minutes = math.floor(cooldown / 60)
        local seconds = math.floor(cooldown % 60)
        vehicleCooldown:SetText("Перезарядка: " .. string.format("%02d:%02d", minutes, seconds))
        vehicleCooldown:SetTextColor(COLOR_WARNING)
        spawnBtn:SetEnabled(false)
        spawnBtn:SetText("")
        spawnBtn.Paint = function(s, w, h)
            draw.RoundedBox(6, 0, 0, w, h, Color(60, 60, 60))
            surface.SetDrawColor(COLOR_BG_DARK)
            surface.DrawOutlinedRect(0, 0, w, h, 2)
            draw.SimpleText("В КД", "ixSmallFont", w/2, h/2, COLOR_TEXT_SECONDARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        end
    elseif factionPoints < vehicleConfig.price then
        vehicleCooldown:SetText("Недостаточно очков техники")
        vehicleCooldown:SetTextColor(COLOR_WARNING)
        spawnBtn:SetEnabled(false)
        spawnBtn:SetText("")
        spawnBtn.Paint = function(s, w, h)
            draw.RoundedBox(6, 0, 0, w, h, Color(60, 60, 60))
            surface.SetDrawColor(COLOR_BG_DARK)
            surface.DrawOutlinedRect(0, 0, w, h, 2)
            draw.SimpleText("НЕТ ОЧКОВ", "ixSmallFont", w/2, h/2, COLOR_TEXT_SECONDARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        end
    else
        vehicleCooldown:SetText("Готов к вызову")
        vehicleCooldown:SetTextColor(COLOR_ACCENT)
        spawnBtn:SetEnabled(true)
        spawnBtn:SetText("")
        spawnBtn.Paint = function(s, w, h)
            local col = s:IsHovered() and COLOR_ACCENT or COLOR_PRIMARY
            draw.RoundedBox(6, 0, 0, w, h, col)
            
            if s:IsHovered() then
                surface.SetDrawColor(255, 255, 255, 30)
                draw.RoundedBox(6, 2, 2, w-4, h-4, Color(255, 255, 255, 30))
            end
            
            surface.SetDrawColor(COLOR_BG_DARK)
            surface.DrawOutlinedRect(0, 0, w, h, 2)
            draw.SimpleText("ВЫЗВАТЬ ТЕХНИКУ ►", "ixSmallFont", w/2, h/2, COLOR_TEXT_PRIMARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        end
        spawnBtn.DoClick = function()
            local loadoutID = PLUGIN.selectedLoadouts[vehicleID] or 1
            
            print("[LVS] Запрос спавна техники " .. vehicleConfig.name .. " с loadout ID: " .. loadoutID)
            PLUGIN:RequestSpawnVehicle(vehicleID, vehicleType, loadoutID)
        end
    end
    
    -- Обновляем панель loadout если она передана
    if IsValid(loadoutPanel) and updateLoadoutCallback then
        updateLoadoutCallback(vehicleConfig, vehicleID, loadoutPanel)
    end
end


function PLUGIN:GetActiveVehicle(vehicleID, vehicleType)
    local ply = LocalPlayer()
    if not IsValid(ply) then return nil end

    for _, ent in ipairs(ents.GetAll()) do
        if IsValid(ent) then
            local nwID = ent:GetNWString("LVS_VehicleID", "")
            local nwType = ent:GetNWString("LVS_VehicleType", "")
            local nwOwner = ent:GetNWString("LVS_OwnerSteamID", "")

            if nwID == tostring(vehicleID) and nwType == tostring(vehicleType) then
                if ply:IsAdmin() or ply:SteamID() == nwOwner then
                    return ent
                end
            end
        end
    end

    return nil
end

-- Функция обновления кд
function PLUGIN:UpdateVehicleCooldown(panel, vehicleID)
    local character = LocalPlayer():GetCharacter()
    if not character then return end
    
    local vehicles = character:GetData("lvs_vehicles", {})
    local lastSpawn = vehicles[vehicleID]
    
    if lastSpawn and lastSpawn > os.time() then
        panel.cooldown = lastSpawn - os.time()
        
        timer.Create("LVS_Cooldown_" .. vehicleID, 1, 0, function()
            if not IsValid(panel) then
                timer.Remove("LVS_Cooldown_" .. vehicleID)
                return
            end
            
            panel.cooldown = panel.cooldown - 1
            if panel.cooldown <= 0 then
                panel.cooldown = 0
                timer.Remove("LVS_Cooldown_" .. vehicleID)
            end
        end)
    else
        panel.cooldown = 0
    end
end

-- Основная функция создания меню в стиле Military RP
function PLUGIN:OpenVehicleMenu(vehicleType)
    -- Если окно уже открыто — закроем старое, чтобы не было дубликатов
    if IsValid(PLUGIN._vehicleMenuFrame) then
        PLUGIN._vehicleMenuFrame:Remove()
        PLUGIN._vehicleMenuFrame = nil
    end

    local scrW, scrH = ScrW(), ScrH()
    local faction = LocalPlayer():Team()
    local factions = PLUGIN:GetFactions()
    local factionConfig = factions and factions[faction]
    
    if not factionConfig then
        return
    end
    
    local vehicles = vehicleType == "ground" and factionConfig.groundVehicles or factionConfig.airVehicles
    
    -- Фильтруем технику по доступности
    local availableVehicles = {}
    for vehicleID, vehicleConfig in pairs(vehicles) do
        if self:CanPlayerAccessVehicle(vehicleConfig) then
            availableVehicles[vehicleID] = vehicleConfig
        end
    end
    
    -- Если нет доступной техники - не открываем меню
    if table.Count(availableVehicles) == 0 then
        LocalPlayer():Notify("Техника вам не доступна")
        return
    end
    
    local frame = vgui.Create("DFrame")
    frame:SetSize(scrW, scrH)
    frame:SetPos(0, 0)
    frame:SetTitle("")
    frame:SetDraggable(false)
    frame:ShowCloseButton(false)
    frame:MakePopup()
    
    local factionPoints = self.clientFactionPoints[faction] or 0
    
    -- Градиентный фон с зеленым оттенком
    frame.Paint = function(s, w, h)
        -- Основной фон
        surface.SetDrawColor(COLOR_BG_DARK)
        surface.DrawRect(0, 0, w, h)
        
        -- Градиент сверху
        local gradHeight = 300
        for i = 0, gradHeight do
            local alpha = (1 - i/gradHeight) * 40
            surface.SetDrawColor(COLOR_PRIMARY.r, COLOR_PRIMARY.g, COLOR_PRIMARY.b, alpha)
            surface.DrawRect(0, i, w, 1)
        end
        
        -- Верхняя панель
        surface.SetDrawColor(COLOR_BG_MEDIUM)
        surface.DrawRect(0, 0, w, 100)
        
        -- Акцентная линия
        surface.SetDrawColor(COLOR_PRIMARY)
        surface.DrawRect(0, 100, w, 3)
        
        -- Декоративные элементы
        surface.SetDrawColor(COLOR_BORDER)
        for i = 0, w, 200 do
            surface.DrawRect(i, 0, 1, 100)
        end
        
        -- Заголовок
        local title = vehicleType == "ground" and "◆ НАЗЕМНАЯ ТЕХНИКА ◆" or "◆ ВОЗДУШНАЯ ТЕХНИКА ◆"
        local subtitle = vehicleType == "ground" and "СИСТЕМА ВЫЗОВА ТЕХНИКИ" or "СИСТЕМА ВЫЗОВА АВИАЦИИ"
        draw.SimpleText(title, "ixMenuButtonFont", w/2, 35, COLOR_ACCENT, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        draw.SimpleText(subtitle, "ixSmallFont", w/2, 68, COLOR_TEXT_SECONDARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
    end

    -- Кнопка закрытия
    local closeBtn = vgui.Create("DButton", frame)
    closeBtn:SetText("")
    closeBtn:SetSize(42, 42)
    closeBtn:SetPos(scrW - 60, 18)
    closeBtn.Paint = function(s, w, h)
        local col = s:IsHovered() and COLOR_DANGER or Color(COLOR_DANGER.r * 0.7, COLOR_DANGER.g * 0.7, COLOR_DANGER.b * 0.7)
        
        draw.RoundedBox(4, 0, 0, w, h, col)
        surface.SetDrawColor(COLOR_BG_DARK)
        surface.DrawOutlinedRect(0, 0, w, h, 2)
        
        surface.SetDrawColor(COLOR_TEXT_PRIMARY)
        surface.DrawLine(w*0.3, h*0.3, w*0.7, h*0.7)
        surface.DrawLine(w*0.7, h*0.3, w*0.3, h*0.7)
        
        if s:IsHovered() then
            surface.SetDrawColor(255, 255, 255, 30)
            draw.RoundedBox(4, 0, 0, w, h, Color(255, 255, 255, 30))
        end
    end
    closeBtn.DoClick = function()
        frame:Close()
    end

    -- Панель информации об очках
    local infoPanel = vgui.Create("DPanel", frame)
    infoPanel:SetSize(300, 70)
    infoPanel:SetPos(40, 115)
    infoPanel.Paint = function(s, w, h)
        draw.RoundedBox(8, 0, 0, w, h, COLOR_BG_LIGHT)
        surface.SetDrawColor(COLOR_PRIMARY)
        surface.DrawOutlinedRect(0, 0, w, h, 2)
        
        draw.SimpleText("ОЧКИ ТЕХНИКИ", "ixSmallFont", 20, 12, COLOR_TEXT_SECONDARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
        draw.SimpleText(factionPoints, "ixMenuButtonFont", 20, 32, COLOR_ACCENT, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
        
        -- Иконка
        surface.SetDrawColor(COLOR_PRIMARY)
        draw.NoTexture()
        surface.DrawCircle(w - 35, h/2, 12, COLOR_PRIMARY)
    end

    local colWidth = (scrW - 120) / 2
    local startY = 205

    -- Панель списка техники
    local vehiclesPanel = vgui.Create("DPanel", frame)
    vehiclesPanel:SetSize(colWidth, scrH - startY - 40)
    vehiclesPanel:SetPos(40, startY)
    vehiclesPanel.Paint = function(s, w, h)
        draw.RoundedBox(8, 0, 0, w, h, COLOR_BG_MEDIUM)
        surface.SetDrawColor(COLOR_BORDER)
        surface.DrawOutlinedRect(0, 0, w, h, 2)
    end

    local vehiclesHeader = vgui.Create("DPanel", vehiclesPanel)
    vehiclesHeader:SetSize(vehiclesPanel:GetWide(), 45)
    vehiclesHeader:SetPos(0, 0)
    vehiclesHeader.Paint = function(s, w, h)
        draw.RoundedBoxEx(8, 0, 0, w, h, COLOR_PRIMARY_DARK, true, true, false, false)
        
        draw.SimpleText("▣ ДОСТУПНАЯ ТЕХНИКА", "ixSmallFont", 15, h/2, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
        
        surface.SetDrawColor(COLOR_ACCENT)
        surface.DrawRect(0, h-2, w, 2)
    end

    -- Панель информации о технике
    local infoPanel2 = vgui.Create("DPanel", frame)
    infoPanel2:SetSize(colWidth, scrH - startY - 40)
    infoPanel2:SetPos(scrW - colWidth - 40, startY)
    infoPanel2.Paint = function(s, w, h)
        draw.RoundedBox(8, 0, 0, w, h, COLOR_BG_MEDIUM)
        surface.SetDrawColor(COLOR_BORDER)
        surface.DrawOutlinedRect(0, 0, w, h, 2)
    end

    local infoHeader = vgui.Create("DPanel", infoPanel2)
    infoHeader:SetSize(infoPanel2:GetWide(), 45)
    infoHeader:SetPos(0, 0)
    infoHeader.Paint = function(s, w, h)
        draw.RoundedBoxEx(8, 0, 0, w, h, COLOR_PRIMARY_DARK, true, true, false, false)
        
        draw.SimpleText("⬢ ИНФОРМАЦИЯ", "ixSmallFont", 15, h/2, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
        
        surface.SetDrawColor(COLOR_ACCENT)
        surface.DrawRect(0, h-2, w, 2)
    end

    -- Список техники
    local vehiclesScroll = vgui.Create("DScrollPanel", vehiclesPanel)
    vehiclesScroll:SetSize(vehiclesPanel:GetWide() - 20, vehiclesPanel:GetTall() - 60)
    vehiclesScroll:SetPos(10, 50)
    
    local sbar = vehiclesScroll:GetVBar()
    sbar:SetHideButtons(true)
    function sbar:Paint(w, h)
        draw.RoundedBox(4, 0, 0, w, h, COLOR_BG_DARK)
    end
    function sbar.btnGrip:Paint(w, h)
        draw.RoundedBox(4, 0, 0, w, h, COLOR_PRIMARY)
    end

    -- Панель информации
    local infoContent = vgui.Create("DPanel", infoPanel2)
    infoContent:SetSize(infoPanel2:GetWide() - 20, infoPanel2:GetTall() - 60)
    infoContent:SetPos(10, 50)
    infoContent.selectedVehicle = nil
    infoContent.Paint = function(s, w, h)
        draw.RoundedBox(6, 0, 0, w, h, COLOR_BG_LIGHT)
        
        if not s.selectedVehicle then
            draw.SimpleText("⚠ ВЫБЕРИТЕ ТЕХНИКУ", "ixSmallFont", w/2, h/2, COLOR_TEXT_SECONDARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        end
    end

    -- Модель техники
    local modelPanel = vgui.Create("DModelPanel", infoContent)
    modelPanel:SetSize(400, 200)
    modelPanel:SetPos(10, 10)
    modelPanel:SetVisible(false)

    -- Информация о технике
    local vehicleName = vgui.Create("DLabel", infoContent)
    vehicleName:SetFont("ixSmallFont")
    vehicleName:SetTextColor(color_white)
    vehicleName:SetPos(10, 220)
    vehicleName:SetSize(400, 20)
    vehicleName:SetVisible(false)

    local vehicleDesc = vgui.Create("DLabel", infoContent)
    vehicleDesc:SetFont("ixSmallFont")
    vehicleDesc:SetTextColor(Color(200, 200, 200))
    vehicleDesc:SetPos(10, 245)
    vehicleDesc:SetSize(400, 40)
    vehicleDesc:SetVisible(false)

    local vehiclePrice = vgui.Create("DLabel", infoContent)
    vehiclePrice:SetFont("ixSmallFont")
    vehiclePrice:SetTextColor(color_white)
    vehiclePrice:SetPos(10, 290)
    vehiclePrice:SetSize(400, 20)
    vehiclePrice:SetVisible(false)

    local vehicleCooldown = vgui.Create("DLabel", infoContent)
    vehicleCooldown:SetFont("ixSmallFont")
    vehicleCooldown:SetTextColor(color_white)
    vehicleCooldown:SetPos(10, 315)
    vehicleCooldown:SetSize(400, 20)
    vehicleCooldown:SetVisible(false)

    -- Кнопка вызова
    local spawnBtn = vgui.Create("DButton", infoContent)
    spawnBtn:SetSize(200, 35)
    spawnBtn:SetPos(10, 350)
    spawnBtn:SetText("")
    spawnBtn:SetVisible(false)

    -- Кнопка возврата
    local returnBtn = vgui.Create("DButton", infoContent)
    returnBtn:SetSize(200, 35)
    returnBtn:SetPos(220, 350)
    returnBtn:SetText("")
    returnBtn:SetVisible(false)

    -- Используем глобальное хранилище selectedLoadouts
    local selectedLoadouts = PLUGIN.selectedLoadouts
    
    -- Создаем панель выбора loadout (скрыта по умолчанию)
    local loadoutPanel = vgui.Create("DPanel", infoContent)
    loadoutPanel:SetSize(infoContent:GetWide() - 20, 120)
    loadoutPanel:SetPos(10, 400)
    loadoutPanel:SetVisible(false)
    loadoutPanel.Paint = function(s, w, h)
        draw.RoundedBox(6, 0, 0, w, h, ColorAlpha(COLOR_BG_DARK, 200))
        surface.SetDrawColor(COLOR_PRIMARY)
        surface.DrawOutlinedRect(0, 0, w, h, 2)
        
        draw.SimpleText("⚙ ВООРУЖЕНИЕ:", "ixSmallFont", 10, 8, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
    end
    
    -- Функция обновления панели loadout
    local function UpdateLoadoutPanel(vehicleConfig, vehicleID, panel)
        if not IsValid(panel) then return end

        for _, child in pairs(panel:GetChildren()) do
            child:Remove()
        end

        local loadoutConfig = vehicleConfig.loadout
        if not istable(loadoutConfig) or table.Count(loadoutConfig) == 0 then
            panel:SetVisible(false)
            return
        end

        panel:SetVisible(true)

        local btnWidth = 130
        local btnHeight = 80
        local gap = 10
        local startX = 10
        local startY = 30

        -- соберём пары в массив и отсортируем по ID, чтобы кнопки шли в правильном порядке
        local entries = {}
        for loadoutName, loadoutID in pairs(loadoutConfig) do
            if isnumber(loadoutID) then
                table.insert(entries, {name = loadoutName, id = loadoutID})
            end
        end
        table.sort(entries, function(a, b) return a.id < b.id end)

        -- вставим пустые слоты для пропущенных ID, чтобы кнопки располагались на своих позициях
        local filled = {}
        local nextIdx = 1
        local maxID = entries[#entries] and entries[#entries].id or 0
        for id = 1, maxID do
            if entries[nextIdx] and entries[nextIdx].id == id then
                table.insert(filled, entries[nextIdx])
                nextIdx = nextIdx + 1
            else
                table.insert(filled, {name = "", id = id})
            end
        end

        for idx, entry in ipairs(filled) do
            local btn = vgui.Create("DButton", panel)
            btn:SetSize(btnWidth, btnHeight)
            btn:SetPos(startX + (idx - 1) * (btnWidth + gap), startY)
            btn:SetText("")
            btn.variantIndex = idx
            btn.loadoutID = entry.id
            btn.loadoutName = tostring(entry.name)

            btn.Paint = function(s, w, h)
                local isSelected = PLUGIN.selectedLoadouts[vehicleID] == s.loadoutID
                local bgColor = isSelected and COLOR_PRIMARY or COLOR_BG_MEDIUM

                if s:IsHovered() and not isSelected then
                    bgColor = ColorAlpha(COLOR_PRIMARY, 100)
                end

                draw.RoundedBox(4, 0, 0, w, h, bgColor)

                if isSelected then
                    surface.SetDrawColor(COLOR_ACCENT)
                    surface.DrawOutlinedRect(0, 0, w, h, 3)
                else
                    surface.SetDrawColor(COLOR_BORDER)
                    surface.DrawOutlinedRect(0, 0, w, h, 1)
                end

                draw.SimpleText(s.loadoutName or ("Вариант " .. s.variantIndex), "ixSmallFont", w/2, 12, COLOR_TEXT_PRIMARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP)
                draw.SimpleText("ID: " .. tostring(s.loadoutID), "DermaDefault", w/2, 50, COLOR_TEXT_SECONDARY, TEXT_ALIGN_CENTER)

                if isSelected then
                    draw.SimpleText("✓", "ixMenuButtonFont", w/2, h - 20, COLOR_ACCENT, TEXT_ALIGN_CENTER)
                end
            end

            btn.DoClick = function()
                print("[LVS] Пользователь выбрал loadout '" .. btn.loadoutName .. "' (ID=" .. btn.loadoutID .. ") для " .. vehicleConfig.name)
                PLUGIN.selectedLoadouts[vehicleID] = btn.loadoutID

                for _, child in pairs(panel:GetChildren()) do
                    child:Remove()
                end

                UpdateLoadoutPanel(vehicleConfig, vehicleID, panel)
            end
        end
    end

    -- Привяжем frame к плагину, чтобы можно было предотвращать дубликаты
    PLUGIN._vehicleMenuFrame = frame

    -- Функция создания строки техники
    local function CreateVehicleRow(parent, vehicleID, vehicleConfig)
        local row = vgui.Create("DButton", parent)
        row:SetSize(parent:GetWide() - 10, 70)
        row:SetText("")
        row.vehicleID = vehicleID
        row.vehicleConfig = vehicleConfig
        
        local isHovered = false
        row.Paint = function(s, w, h)
            local isSelected = infoContent.selectedVehicle == vehicleID
            local canAfford = factionPoints >= vehicleConfig.price
            local cooldown = s.cooldown or 0
            local hasActive = PLUGIN:HasActiveVehicle(vehicleID, vehicleType)
            
            -- Фон строки
            local bgColor = isSelected and COLOR_PRIMARY_DARK or COLOR_BG_LIGHT
            if isHovered and not isSelected then
                bgColor = Color(bgColor.r + 10, bgColor.g + 15, bgColor.b + 10)
            end
            draw.RoundedBox(6, 0, 0, w, h, bgColor)
            
            -- Боковая полоска
            local statusColor = hasActive and Color(56, 142, 200) or (canAfford and COLOR_PRIMARY or COLOR_DANGER)
            draw.RoundedBoxEx(6, 0, 0, 5, h, statusColor, true, false, true, false)
            
            -- Рамка
            surface.SetDrawColor(isSelected and COLOR_ACCENT or COLOR_BORDER)
            surface.DrawOutlinedRect(0, 0, w, h, 2)
            
            -- Акцентная линия при наведении
            if isHovered then
                surface.SetDrawColor(COLOR_ACCENT)
                surface.DrawRect(5, h-3, w-10, 3)
            end
            
            -- Название техники
            draw.SimpleText(vehicleConfig.name, "ixSmallFont", 15, 12, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT)
            
            -- Цена
            local priceColor = canAfford and COLOR_ACCENT or COLOR_WARNING
            draw.SimpleText(vehicleConfig.price .. " очков", "ixSmallFont", 15, 35, priceColor, TEXT_ALIGN_LEFT)
            
            -- Статус
            local statusText = ""
            local statusTextColor = COLOR_TEXT_SECONDARY
            
            if hasActive then
                statusText = "● АКТИВНА"
                statusTextColor = Color(100, 180, 255)
            elseif cooldown > 0 then
                local minutes = math.floor(cooldown / 60)
                local seconds = math.floor(cooldown % 60)
                statusText = "КД: " .. string.format("%02d:%02d", minutes, seconds)
                statusTextColor = COLOR_WARNING
            elseif not canAfford then
                statusText = "НЕТ ОЧКОВ"
                statusTextColor = COLOR_WARNING
            else
                statusText = "● ГОТОВ"
                statusTextColor = COLOR_ACCENT
            end
            
            draw.SimpleText(statusText, "ixSmallFont", w - 15, h/2, statusTextColor, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
        end
        
        row.OnCursorEntered = function() isHovered = true end
        row.OnCursorExited = function() isHovered = false end
        
        row.DoClick = function(s)
            infoContent.selectedVehicle = vehicleID
            UpdateVehicleInfo(vehicleConfig, vehicleID, infoContent, modelPanel, vehicleName, vehicleDesc, vehiclePrice, vehicleCooldown, spawnBtn, factionPoints, vehicleType, returnBtn, loadoutPanel, UpdateLoadoutPanel)
        end
        
        -- Обновляем кд
        PLUGIN:UpdateVehicleCooldown(row, vehicleID)
        
        return row
    end

    -- Создаем строки с техникой (только доступной)
    for vehicleID, vehicleConfig in SortedPairsByMemberValue(availableVehicles, "price") do
        local row = CreateVehicleRow(vehiclesScroll, vehicleID, vehicleConfig)
        row:Dock(TOP)
        row:DockMargin(0, 0, 0, 5)
    end

    -- Функция обновления интерфейса
    local function UpdateInterface()
        if not IsValid(frame) then return end
        
        local currentPoints = PLUGIN.clientFactionPoints[faction] or 0
        factionPoints = currentPoints
        
        -- Обновляем отображение очков
        if IsValid(pointsPanel) then
            pointsPanel.Paint = function(s, w, h)
                surface.SetDrawColor(Color(23, 23, 23))
                surface.DrawRect(0, 0, w, h)
                surface.SetDrawColor(Color(1, 67, 29))
                surface.DrawOutlinedRect(0, 0, w, h, 1)
                
                draw.SimpleText("ОЧКИ ТЕХНИКИ", "ixSmallFont", w/2, 11, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
                draw.SimpleText(currentPoints, "ixSmallFont", w/2, 28, Color(100, 255, 100), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
            end
        end
        
        -- Обновляем информацию о выбранной технике
        if infoContent.selectedVehicle then
            local vehicleConfig = availableVehicles[infoContent.selectedVehicle]
            if vehicleConfig then
                UpdateVehicleInfo(vehicleConfig, infoContent.selectedVehicle, infoContent, modelPanel, vehicleName, vehicleDesc, vehiclePrice, vehicleCooldown, spawnBtn, currentPoints, vehicleType, returnBtn)
            end
        end
    end

    -- Таймер для обновления интерфейса
    timer.Create("LVS_InterfaceUpdate_" .. vehicleType, 1, 0, function()
        if not IsValid(frame) then
            timer.Remove("LVS_InterfaceUpdate_" .. vehicleType)
            return
        end
        UpdateInterface()
    end)

    -- Автоматически выбираем первую технику
    timer.Simple(0.1, function()
        if IsValid(vehiclesScroll) and vehiclesScroll:GetCanvas():GetChildren()[1] then
            local firstRow = vehiclesScroll:GetCanvas():GetChildren()[1]
            if firstRow.DoClick then
                firstRow:DoClick()
            end
        end
    end)

    frame.OnCursorEntered = function(s)
        s:MoveToFront()
    end
    
    frame.OnClose = function()
        timer.Remove("LVS_InterfaceUpdate_" .. vehicleType)
        if PLUGIN._vehicleMenuFrame == frame then
            PLUGIN._vehicleMenuFrame = nil
        end
    end
end

-- Запрос спавна техники
function PLUGIN:RequestSpawnVehicle(vehicleID, vehicleType, loadoutVariant)
    print("[LVS] Отправка запроса спавна на сервер - vehicleID: " .. vehicleID .. ", loadoutVariant: " .. (loadoutVariant or 0))
    net.Start("LVS_RequestSpawn")
        net.WriteString(vehicleID)
        net.WriteString(vehicleType)
        net.WriteUInt(loadoutVariant or 0, 8)
    net.SendToServer()
end

-- Запрос возврата техники
function PLUGIN:RequestReturnVehicle(vehicleID, vehicleType)
    local vehicle = self:GetActiveVehicle(vehicleID, vehicleType)
    
    if IsValid(vehicle) then
        net.Start("LVS_RequestReturn")
            net.WriteUInt(vehicle:EntIndex(), 16)
        net.SendToServer()
    else
        LocalPlayer():Notify("Активная техника не найдена")
    end
end

net.Receive("LVS_SyncVehicleInfo", function()
    local vehicle = net.ReadEntity()
    local ownerSteamID = net.ReadString()
    local vehicleID = net.ReadString()
    local vehicleType = net.ReadString()
    
    if IsValid(vehicle) then
        vehicle.lvsVehicleInfo = {
            ownerSteamID = ownerSteamID,
            vehicleID = vehicleID,
            vehicleType = vehicleType
        }
    end
end)

-- Получаем таблицу моделей от сервера и подставляем в конфиг при отсутствии
net.Receive("LVS_SyncVehicleModels", function()
    local mapping = net.ReadTable()
    if not istable(mapping) then return end

    for factionID, data in pairs(mapping) do
        local factionConfig = PLUGIN:GetFactions()[factionID]
        if not factionConfig then continue end

        if istable(data.ground) then
            for id, mdl in pairs(data.ground) do
                if factionConfig.groundVehicles and factionConfig.groundVehicles[id] then
                    if not factionConfig.groundVehicles[id].model or factionConfig.groundVehicles[id].model == "" then
                        factionConfig.groundVehicles[id].model = mdl
                    end
                end
            end
        end

        if istable(data.air) then
            for id, mdl in pairs(data.air) do
                if factionConfig.airVehicles and factionConfig.airVehicles[id] then
                    if not factionConfig.airVehicles[id].model or factionConfig.airVehicles[id].model == "" then
                        factionConfig.airVehicles[id].model = mdl
                    end
                end
            end
        end
    end
end)
