local menuFrame = nil
local factions = {}

local function GetPlayerBySteamID(steamID)
    for _, ply in ipairs(player.GetAll()) do
        if ply:SteamID() == steamID then
            return ply
        end
    end
    return nil
end

local function GetDisplayName(input)
    if isstring(input) then
        return input
    elseif istable(input) then
        return input[1] or tostring(input)
    else
        return tostring(input)
    end
end

local selectedPlayer = nil
local selectedFaction = nil
local selectedPodr = nil
local selectedSpec = nil
local selectedRank = nil

local playerButtons = {}
local factionButtons = {}
local podrButtons = {}
local specButtons = {}
local rankButtons = {}

local originalPlayers = {}

net.Receive("ixWhitelistMenuOpen", function()
    if menuFrame and menuFrame:IsValid() then menuFrame:Close() end
    net.Start("ixWhitelistMenuDataRequest")
    net.SendToServer()
end)

net.Receive("ixWhitelistMenuData", function()
    if menuFrame and menuFrame:IsValid() then menuFrame:Close() end

    originalPlayers = net.ReadTable()
    factions = net.ReadTable()

    selectedPlayer = nil
    selectedFaction = nil
    selectedPodr = nil
    selectedSpec = nil
    selectedRank = nil

    playerButtons = {}
    factionButtons = {}
    podrButtons = {}
    specButtons = {}
    rankButtons = {}

    local scrW, scrH = ScrW(), ScrH()
    
    menuFrame = vgui.Create("DFrame")
    menuFrame:SetSize(900, 650)
    menuFrame:SetPos(scrW/2 - 450, scrH/2 - 325)
    menuFrame:SetTitle("")
    menuFrame:SetDraggable(false)
    menuFrame:ShowCloseButton(false)
    menuFrame:MakePopup()
    menuFrame.Paint = function(s, w, h)
        -- Фон
        surface.SetDrawColor(Color(13, 13, 13, 240))
        surface.DrawRect(0, 0, w, h)
        
        -- Обводка
        surface.SetDrawColor(Color(1, 67, 29))
        surface.DrawOutlinedRect(0, 0, w, h, 2)
        
        -- Верхняя панель
        surface.SetDrawColor(Color(1, 67, 29))
        surface.DrawRect(0, 0, w, 40)
        
        -- Заголовок
        draw.SimpleText("МЕНЕДЖЕР ВАЙТЛИСТА", "ixMenuButtonFont", w/2, 20, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
    end

    local closeBtn = vgui.Create("DButton", menuFrame)
    closeBtn:SetText("")
    closeBtn:SetSize(30, 30)
    closeBtn:SetPos(menuFrame:GetWide() - 40, 5)
    closeBtn.Paint = function(s, w, h)
        surface.SetDrawColor(Color(200, 50, 50))
        surface.DrawRect(0, 0, w, h)
        surface.SetDrawColor(Color(29, 29, 29))
        surface.DrawOutlinedRect(0, 0, w, h, 2)
        draw.SimpleText("×", "ixSmallFont", w/2, h/2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        
        if s:IsHovered() then
            surface.SetDrawColor(Color(255, 255, 255, 30))
            surface.DrawRect(0, 0, w, h)
        end
    end
    closeBtn.DoClick = function()
        menuFrame:Close()
    end

    local function CreateRow(parent, text, onSelect, data, buttonGroup)
        local btn = parent:Add("DButton")
        btn:SetText("")
        btn:SetTall(30)
        btn:SetFont("ixSmallFont")

        btn.Paint = function(s, w, h)
            if s.isSelected then
                surface.SetDrawColor(Color(1, 67, 29, 200))
                surface.DrawRect(0, 0, w, h)
            else
                surface.SetDrawColor(Color(23, 23, 23))
                surface.DrawRect(0, 0, w, h)
            end
            
            surface.SetDrawColor(Color(1, 67, 29))
            surface.DrawOutlinedRect(0, 0, w, h, 1)

            local textColor = s.isSelected and color_white or Color(200, 200, 200)
            draw.SimpleText(text, "ixSmallFont", 8, h/2, textColor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
            
            if s:IsHovered() and not s.isSelected then
                surface.SetDrawColor(Color(255, 255, 255, 20))
                surface.DrawRect(0, 0, w, h)
            end
        end

        btn.DoClick = function()
            for _, otherBtn in ipairs(buttonGroup) do
                if otherBtn ~= btn then
                    otherBtn.isSelected = false
                end
            end
            btn.isSelected = true
            if onSelect then onSelect(data) end
        end

        btn:DockMargin(2, 2, 2, 2)
        btn:Dock(TOP)

        table.insert(buttonGroup, btn)
        return btn
    end

    local colWidth = 160
    local colSpacing = 10
    local colX = 20
    local headerHeight = 30
    local scrollHeight = 500
    local totalHeight = headerHeight + scrollHeight
    local startY = 60
    local buttonHeight = 40

    local function CreateColumnPanel(name, x)
        local panel = vgui.Create("DPanel", menuFrame)
        panel:SetSize(colWidth, totalHeight)
        panel:SetPos(x, startY)
        panel.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)
        end

        local header = vgui.Create("DLabel", panel)
        header:SetText(name)
        header:SetPos(0, 5)
        header:SetSize(colWidth, 20)
        header:SetFont("ixSmallFont")
        header:SetTextColor(color_white)
        header:SetContentAlignment(5)

        local scroll = vgui.Create("DScrollPanel", panel)
        scroll:SetSize(colWidth - 4, scrollHeight)
        scroll:SetPos(2, headerHeight)

        return scroll
    end

    -- Панель игроков с поиском
    local playerPanel = vgui.Create("DPanel", menuFrame)
    playerPanel:SetSize(colWidth, totalHeight)
    playerPanel:SetPos(colX, startY)
    playerPanel.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)
    end

    local playerHeader = vgui.Create("DLabel", playerPanel)
    playerHeader:SetText("ИГРОКИ")
    playerHeader:SetPos(0, 5)
    playerHeader:SetSize(colWidth, 20)
    playerHeader:SetFont("ixSmallFont")
    playerHeader:SetTextColor(color_white)
    playerHeader:SetContentAlignment(5)

    local searchBox = vgui.Create("DTextEntry", playerPanel)
    searchBox:SetPos(5, 30)
    searchBox:SetSize(colWidth - 10, 25)
    searchBox:SetPlaceholderText("Поиск...")
    searchBox:SetFont("ixSmallFont")
    searchBox:SetUpdateOnType(true)
    searchBox.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)
        s:DrawTextEntryText(color_white, Color(30, 130, 255), color_white)
    end

    local playerScroll = vgui.Create("DScrollPanel", playerPanel)
    playerScroll:SetSize(colWidth - 4, scrollHeight - 40)
    playerScroll:SetPos(2, 60)

    -- Создаем колонки
    local factionScroll = CreateColumnPanel("ФРАКЦИИ", colX + (colWidth + colSpacing) * 1)
    local podrScroll = CreateColumnPanel("ПОДРАЗДЕЛЕНИЯ", colX + (colWidth + colSpacing) * 2)
    local specScroll = CreateColumnPanel("СПЕЦИАЛИЗАЦИИ", colX + (colWidth + colSpacing) * 3)
    local rankScroll = CreateColumnPanel("ЗВАНИЯ", colX + (colWidth + colSpacing) * 4)

    local function UpdatePlayerList(filterText)
        playerScroll:Clear()
        playerButtons = {}

        local lowerFilter = string.lower(filterText or "")

        for _, p in ipairs(originalPlayers) do
            if filterText == "" or string.find(string.lower(p.name), lowerFilter, 1, true) then
                CreateRow(playerScroll, p.name, function(data)
                    selectedPlayer = data
                    factionScroll:Clear()
                    podrScroll:Clear()
                    specScroll:Clear()
                    rankScroll:Clear()
                    selectedFaction = nil
                    selectedPodr = nil
                    selectedSpec = nil
                    selectedRank = nil

                    factionButtons = {}
                    podrButtons = {}
                    specButtons = {}
                    rankButtons = {}

                    for id, f in pairs(factions) do
                        CreateRow(factionScroll, GetDisplayName(f.name), function(factionData)
                            selectedFaction = factionData
                            local f = factions[factionData.id]

                            podrScroll:Clear()
                            specScroll:Clear()
                            rankScroll:Clear()
                            selectedPodr = nil
                            selectedSpec = nil
                            selectedRank = nil

                            podrButtons = {}
                            specButtons = {}
                            rankButtons = {}

                            for podId, podr in pairs(f.Podr) do
                                CreateRow(podrScroll, podr.name, function(podrData)
                                    selectedPodr = podrData
                                    local f2 = factions[selectedFaction.id]
                                    
                                    -- Update specialties
                                    specScroll:Clear()
                                    selectedSpec = nil
                                    specButtons = {}
                                    for specId, spec in pairs(f2.Spec) do
                                        if spec.podr == podrData.id then
                                            CreateRow(specScroll, spec.name, function(specData)
                                                selectedSpec = specData
                                            end, { id = specId }, specButtons)
                                        end
                                    end

                                    -- Update ranks based on subdivision
                                    rankScroll:Clear()
                                    selectedRank = nil
                                    rankButtons = {}
                                    local targetRanks = (f2.Podr[podrData.id] and f2.Podr[podrData.id].ranks) or f2.Ranks
                                    if targetRanks then
                                        local keys = {}
                                        for k in pairs(targetRanks) do table.insert(keys, k) end
                                        table.sort(keys)
                                        for _, rankId in ipairs(keys) do
                                            local rank = targetRanks[rankId]
                                            CreateRow(rankScroll, GetDisplayName(rank[1]), function(rankData)
                                                selectedRank = rankData
                                            end, { id = rankId }, rankButtons)
                                        end
                                    end
                                end, { id = podId }, podrButtons)
                            end

                            local factionRanks = f.Ranks
                            if factionRanks then
                                local keys = {}
                                for k in pairs(factionRanks) do table.insert(keys, k) end
                                table.sort(keys)
                                for _, rankId in ipairs(keys) do
                                    local rank = factionRanks[rankId]
                                    CreateRow(rankScroll, GetDisplayName(rank[1]), function(rankData)
                                        selectedRank = rankData
                                    end, { id = rankId }, rankButtons)
                                end
                            end
                        end, { id = id }, factionButtons)
                    end
                end, { steamID = p.steamID }, playerButtons)
            end
        end
    end

    searchBox.OnValueChange = function(_, value)
        UpdatePlayerList(value)
    end

    UpdatePlayerList("")

    -- Кнопка назначения
    local applyBtn = vgui.Create("DButton", menuFrame)
    applyBtn:SetText("")
    applyBtn:SetSize(200, 40)
    applyBtn:SetPos(menuFrame:GetWide()/2 - 100, startY + totalHeight + 10)
    applyBtn.Paint = function(s, w, h)
        surface.SetDrawColor(Color(1, 67, 29))
        surface.DrawRect(0, 0, w, h)
        surface.SetDrawColor(Color(29, 29, 29))
        surface.DrawOutlinedRect(0, 0, w, h, 2)
        draw.SimpleText("НАЗНАЧИТЬ", "ixSmallFont", w/2, h/2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
        
        if s:IsHovered() then
            surface.SetDrawColor(Color(255, 255, 255, 30))
            surface.DrawRect(0, 0, w, h)
        end
    end
    applyBtn.DoClick = function()
        if not (selectedPlayer and selectedFaction and selectedPodr and selectedSpec and selectedRank) then
            LocalPlayer():Notify("Выберите все поля!")
            return
        end

        net.Start("ixWhitelistMenuApply")
        net.WriteString(selectedPlayer.steamID)
        net.WriteUInt(selectedFaction.id, 16)
        net.WriteUInt(selectedPodr.id, 8)
        net.WriteUInt(selectedSpec.id, 8)
        net.WriteUInt(selectedRank.id, 8)
        net.SendToServer()

        menuFrame:Close()
        LocalPlayer():Notify("Вайтлист успешно назначен!")
    end

    -- Статус выбора
    local statusPanel = vgui.Create("DPanel", menuFrame)
    statusPanel:SetSize(400, 30)
    statusPanel:SetPos(menuFrame:GetWide()/2 - 200, startY + totalHeight - 553.5)
    statusPanel.Paint = function(s, w, h)
        local statusText = "Выберите игрока и все параметры"
        local statusColor = Color(200, 200, 200)
        
        if selectedPlayer and selectedFaction and selectedPodr and selectedSpec and selectedRank then
            statusText = "Готово к назначению"
            statusColor = Color(84, 147, 90)
        end
        
        draw.SimpleText(statusText, "ixSmallFont", w/2, h/2, statusColor, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
    end

    menuFrame.OnCursorEntered = function(s)
        s:MoveToFront()
    end
end)
