local PLUGIN = PLUGIN

util.AddNetworkString("ixAdminShopOpen")
util.AddNetworkString("ixAdminShopBuy")
util.AddNetworkString("ixAdminShopRetrieve")
util.AddNetworkString("ixAdminShopAdminSync")
util.AddNetworkString("ixAdminShopAdminAction")

function PLUGIN:Initialize()
    self.shopData = ix.data.Get("adminShop", {})
end

function PLUGIN:SaveShopData()
    ix.data.Set("adminShop", self.shopData)
end

function PLUGIN:PlayerLoaded(client)
    local steamID = client:SteamID()
    self.shopData[steamID] = self.shopData[steamID] or {points = 0, inventory = {}}
    
    client:SetNetVar("adminPoints", self.shopData[steamID].points)
    client:SetNetVar("adminInventory", self.shopData[steamID].inventory)
end

local playerMeta = debug.getregistry().Player

function playerMeta:SetAdminPoints(amount)
    amount = math.max(0, amount)
    self:SetNetVar("adminPoints", amount)
    
    local steamID = self:SteamID()
    PLUGIN.shopData[steamID] = PLUGIN.shopData[steamID] or {points = 0, inventory = {}}
    PLUGIN.shopData[steamID].points = amount
    PLUGIN:SaveShopData()
end

function playerMeta:GiveAdminPoints(amount)
    self:SetAdminPoints(self:GetAdminPoints() + amount)
end

function playerMeta:TakeAdminPoints(amount)
    self:SetAdminPoints(self:GetAdminPoints() - amount)
end

function playerMeta:SetAdminInventory(data)
    self:SetNetVar("adminInventory", data)
    
    local steamID = self:SteamID()
    PLUGIN.shopData[steamID] = PLUGIN.shopData[steamID] or {points = 0, inventory = {}}
    PLUGIN.shopData[steamID].inventory = data
    PLUGIN:SaveShopData()
end

ix.command.Add("AdminShop", {
    description = "Открыть магазин администратора.",
    OnRun = function(self, client)
        if (!client:IsAdmin() and !client:IsSuperAdmin() and !IsAdminRank(client:GetUserGroup())) then
            client:Notify("Эта команда доступна только администраторам.")
            return
        end
        net.Start("ixAdminShopOpen")
        net.Send(client)
    end
})

net.Receive("ixAdminShopBuy", function(len, client)
    local itemID = net.ReadString()
    local item = PLUGIN.Items[itemID]

    if (!item) then return end

    local points = client:GetAdminPoints()
    if (points < item.price) then
        client:Notify("У вас недостаточно очков!")
        return
    end

    if (itemID == "remove_warn") then
        local warnPlugin = ix.plugin.Get("warn")
        if (warnPlugin) then
            local steamID = client:SteamID()
            local warns = ix.data.Get("warns", {})
            local targetData = warns[steamID]

            if (targetData and targetData.count > 0) then
                targetData.count = targetData.count - 1
                table.insert(targetData.history, {
                    admin = "Admin Shop",
                    adminSteamID = "STEAM_0:0:0",
                    reason = "Покупка в магазине",
                    time = os.time(),
                    type = "remove"
                })
                ix.data.Set("warns", warns)
                warnPlugin.warns = warns
                client:TakeAdminPoints(item.price)
                client:Notify("Вы успешно сняли выговор!")
            else
                client:Notify("У вас нет активных выговоров для снятия!")
            end
        else
            client:Notify("Система выговоров не найдена!")
        end
    else
        -- Immediate delivery if class exists
        if (item.class) then
            client:GiveItem(item.class)
            client:TakeAdminPoints(item.price)
            client:Notify("Вы купили " .. item.name .. ". Предмет выдан!")
        else
            -- Fallback to inventory just in case (hidden)
            local inv = client:GetAdminInventory()
            local expireTime = 0
            if (item.duration) then
                expireTime = os.time() + (item.duration * 24 * 60 * 60)
            end

            table.insert(inv, {
                id = itemID,
                buyTime = os.time(),
                expireTime = expireTime,
                name = item.name,
                class = item.class
            })

            client:SetAdminInventory(inv)
            client:TakeAdminPoints(item.price)
            client:Notify("Вы купили " .. item.name .. ". Предмет добавлен в инвентарь (скрыто).")
        end
    end
end)

net.Receive("ixAdminShopRetrieve", function(len, client)
    local index = net.ReadUInt(16)
    local inv = client:GetAdminInventory()
    local itemData = inv[index]

    if (!itemData) then return end

    if (itemData.expireTime > 0 and os.time() > itemData.expireTime) then
        client:Notify("Срок действия предмета истек!")
        table.remove(inv, index)
        client:SetAdminInventory(inv)
        return
    end

    if (itemData.class) then
        client:GiveItem(itemData.class)
        client:Notify("Вы получили: " .. itemData.name)
    end
end)

local adminRanks = {
    ["super admin"] = true,
    ["superadmin"] = true,
    ["projectteam"] = true,
    ["teh.admin"] = true,
    ["curator"] = true,
    ["sudo-curator"] = true,
    ["asist-sudo"] = true,
    ["admin"] = true,
    ["st.admin"] = true,
    ["ivent"] = true,
    ["st.event"] = true,
    ["event"] = true,
    ["disp"] = true,
    ["assistant"] = true,
    ["prem"] = true,
    ["dsmoder"] = true
}

local function IsAdminRank(rank)
    if not rank or rank == "user" then return false end
    
    local lowerRank = string.lower(rank)
    
    -- Check exact match in the provided list
    if adminRanks[lowerRank] then return true end
    
    -- Keep generic string searches just in case
    if lowerRank == "founder" or lowerRank == "owner" or lowerRank == "manager" then return true end
    
    return false
end
