local PLUGIN = PLUGIN

function PLUGIN:HUDPaint()
    local client = LocalPlayer()
    if not IsValid(client) then return end

    if not client:IsAdminMode() then return end

    local scrW, scrH = ScrW(), ScrH()
    local w, h = 220, 36
    local x, y = scrW / 2 - w / 2, 20

    surface.SetDrawColor(13, 13, 13, 220)
    surface.DrawRect(x, y, w, h)

    surface.SetDrawColor(200, 80, 80, 255)
    surface.DrawOutlinedRect(x, y, w, h, 2)

    draw.SimpleText("ADMIN MODE", "ixMenuButtonFont", scrW / 2, y + h / 2,
        Color(255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end

surface.CreateFont("AdminESPFontSmall", {
    font = "Arial",
    size = 12,
    weight = 500
})

CLIENT_ADMIN_GROUPS = CLIENT_ADMIN_GROUPS or {}

local function Draw3DBox(ent, color)
    local mins, maxs = ent:OBBMins(), ent:OBBMaxs()
    local corners = {
        Vector(mins.x, mins.y, mins.z),
        Vector(mins.x, maxs.y, mins.z),
        Vector(maxs.x, maxs.y, mins.z),
        Vector(maxs.x, mins.y, mins.z),

        Vector(mins.x, mins.y, maxs.z),
        Vector(mins.x, maxs.y, maxs.z),
        Vector(maxs.x, maxs.y, maxs.z),
        Vector(maxs.x, mins.y, maxs.z),
    }

    local lines = {
        {1,2},{2,3},{3,4},{4,1},
        {5,6},{6,7},{7,8},{8,5},
        {1,5},{2,6},{3,7},{4,8}
    }

    cam.Start3D()
        render.SetColorMaterial()
        for _, l in ipairs(lines) do
            render.DrawLine(
                ent:LocalToWorld(corners[l[1]]),
                ent:LocalToWorld(corners[l[2]]),
                color, true
            )
        end
    cam.End3D()
end

local function CanSeeESP()
    local client = LocalPlayer()
    if not IsValid(client) then return false end
    if not client:IsAdminMode() then return false end

    local group = client:GetUserGroup()
    if not CLIENT_ADMIN_GROUPS[group] then return false end

    return true
end

hook.Add("HUDPaint", "AdminMode_ESP", function()
    if not CanSeeESP() then return end

    local client = LocalPlayer()

    for _, ply in ipairs(player.GetAll()) do
        if ply ~= client and ply:Alive() then

            local distance = client:GetPos():Distance(ply:GetPos())

            Draw3DBox(ply, Color(255, 60, 60))

            local char = ply:GetCharacter()
            local top = (ply:GetPos() + Vector(0,0,85)):ToScreen()
            local bottom = (ply:GetPos() + Vector(0,0,5)):ToScreen()

            local faction = "Неизвестно"
            local podr = "Неизвестно"
            local spec = "Неизвестно"
            local rank = "Неизвестно"

            local samGroup = ply:GetUserGroup()
            local samName = samGroup

            if sam and sam.ranks and sam.ranks[samGroup] and sam.ranks[samGroup].Name then
                samName = sam.ranks[samGroup].Name
            end

            if char then
                local factionID = char:GetFaction()
                local factionTable = ix.faction.indices[factionID]

                if factionTable and factionTable.name then
                    faction = factionTable.name
                end

                if factionTable and factionTable.Podr and char.GetPodr then
                    local id = char:GetPodr()
                    if factionTable.Podr[id] and factionTable.Podr[id].name then
                        podr = factionTable.Podr[id].name
                    end
                end

                if factionTable and factionTable.Spec and char.GetSpec then
                    local id = char:GetSpec()
                    if factionTable.Spec[id] and factionTable.Spec[id].name then
                        spec = factionTable.Spec[id].name
                    end
                end

                if factionTable and factionTable.Ranks and char.GetRank then
                    local id = char:GetRank()
                    if factionTable.Ranks[id] and factionTable.Ranks[id][1] then
                        rank = factionTable.Ranks[id][1]
                    end
                end
            end

            local steamid = ply:SteamID()
            local hp = ply:Health()
            local armor = ply:Armor()
            local wep = IsValid(ply:GetActiveWeapon()) and ply:GetActiveWeapon():GetClass() or "—"

            local topLines = {}

            if distance > 500 then
                -- Издалека: только ник
                topLines = { ply:Name() }
            elseif distance > 200 then
                -- Средняя дальность: ник + фракция + SteamID
                topLines = {
                    ply:Name(),
                    "" .. faction,
                    "" .. steamid
                }
            else
                -- Близко: вся информация
                topLines = {
                    ply:Name(),
                    "" .. faction,
                    "" .. podr,
                    "" .. spec,
                    "" .. rank,
                    "" .. samName,
                    "" .. steamid
                }
            end

            local y = top.y
            for _, text in ipairs(topLines) do
                surface.SetDrawColor(0, 0, 0, 160)
                surface.DrawRect(top.x - 50, y - 5, 100, 12)

                draw.SimpleText(text, "AdminESPFontSmall", top.x, y,
                    Color(255,255,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)

                y = y + 15
            end

            -- Нижняя информация всегда показывается близко
            if distance <= 200 then
                local bottomLines = {
                    "HP: " .. hp,
                    "Armor: " .. armor,
                    "Weapon: " .. wep
                }

                local y2 = bottom.y
                for _, text in ipairs(bottomLines) do
                    surface.SetDrawColor(0, 0, 0, 160)
                    surface.DrawRect(bottom.x - 40, y2 - 5, 80, 10)

                    draw.SimpleText(text, "AdminESPFontSmall", bottom.x, y2,
                        Color(255,255,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)

                    y2 = y2 + 12
                end
            end
        end
    end
end)
