if not SERVER then return end
zrmine = zrmine or {}
zrmine.lvlsys = zrmine.lvlsys or {}

-- Admin
function zrmine.lvlsys.FindPlayerByName(name)
    local pls = player.GetAll()
    local foundply = nil

    --Find by Partial Nick
    for k, v in pairs(pls) do
        if string.find(string.lower(v:Name()), string.lower(name)) ~= nil and v:IsPlayer() then
            foundply = v
        end
    end

    return foundply
end

function zrmine.lvlsys.AdminReset(ply, text, team)
    local atext = string.lower(text)
    local size = string.len(string.lower(atext))

    if (string.sub(atext, 1, 18) == "!zrms_lvlsys_reset" and (size >= 18)) then
        if not zrmine.f.IsAdmin(ply) then
            zrmine.f.Notify(ply, zrmine.language.Cmd_NoPermission, 1)

            return
        end

        local searchPlayer = string.sub(text, 20, size)
        local foundply = zrmine.lvlsys.FindPlayerByName(searchPlayer)

        if (IsValid(foundply) and foundply:IsPlayer()) then
            zrmine.lvlsys.PlayerReset(foundply)
            zrmine.f.Notify(ply, "You reseted " .. foundply:Name() .. " Level!", 0)
        else
            zrmine.f.Notify(ply, "No Valid Player Found!", 1)
        end
    end
end

hook.Add("PlayerSay", "zrmine.lvlsys.AdminReset_id", zrmine.lvlsys.AdminReset)

function zrmine.lvlsys.AdminGiveXP(ply, text, team)
    local atext = string.lower(text)
    local size = string.len(atext)

    if (string.sub(atext, 1, 12) == "!zrms_givexp" and (size >= 12)) then
        if not zrmine.f.IsAdmin(ply) then
            zrmine.f.Notify(ply, zrmine.language.Cmd_NoPermission, 1)

            return
        end

        local foundply = ply:GetEyeTrace().Entity
        local giveXP = tonumber(string.sub(atext, 13, size))

        if (giveXP == nil or giveXP <= 0) then
            zrmine.f.Notify(ply, "Not a valid number!", 1)

            return
        end

        if (not IsValid(foundply) or not foundply:IsPlayer()) then
            zrmine.f.Notify(ply, "No Valid Player Found!", 1)

            return
        end

        zrmine.lvlsys.AddXP(foundply, giveXP)
        zrmine.f.Notify(ply, "You gave " .. foundply:Nick() .. " " .. giveXP .. " XP!", 0)
    end
end

hook.Add("PlayerSay", "zrmine.lvlsys.GiveXP_id", zrmine.lvlsys.AdminGiveXP)

function zrmine.lvlsys.AdminGiveSelfXP(ply, text, team)
    local atext = string.lower(text)
    local size = string.len(atext)

    if (string.sub(atext, 1, 16) == "!zrms_giveselfxp" and (size >= 16)) then
        if not zrmine.f.IsAdmin(ply) then
            zrmine.f.Notify(ply, zrmine.language.Cmd_NoPermission, 1)

            return
        end

        local foundply = ply
        local giveXP = tonumber(string.sub(text, 17, size))

        if (giveXP == nil or giveXP <= 0) then
            zrmine.f.Notify(ply, "Not a valid number!", 1)

            return
        end

        if (not IsValid(foundply) or not foundply:IsPlayer()) then
            zrmine.f.Notify(ply, "No Valid Player Found!", 1)

            return
        end

        zrmine.lvlsys.AddXP(foundply, giveXP)
        zrmine.f.Notify(ply, "You gave yourself " .. giveXP .. " XP!", 0)
    end
end

hook.Add("PlayerSay", "zrmine.lvlsys.GiveSelfXP_id", zrmine.lvlsys.AdminGiveSelfXP)

function zrmine.lvlsys.AdminGiveLvl(ply, text, team)
    local atext = string.lower(text)
    local size = string.len(atext)

    if (string.sub(text, 1, 13) == "!zrms_givelvl" and (size >= 13)) then
        if not zrmine.f.IsAdmin(ply) then
            zrmine.f.Notify(ply, zrmine.language.Cmd_NoPermission, 1)

            return
        end

        local foundply = ply:GetEyeTrace().Entity
        local AddLvl = tonumber(string.sub(atext, 14, size))

        if (AddLvl == nil or AddLvl <= 0) then
            zrmine.f.Notify(ply, "Not a valid number!", 1)

            return
        end

        if (not IsValid(foundply) or not foundply:IsPlayer()) then
            zrmine.f.Notify(ply, "No Valid Player Found!", 1)

            return
        end

        zrmine.lvlsys.AddLvl(foundply, tonumber(AddLvl))
        zrmine.f.Notify(ply, "You gave " .. foundply:Nick() .. " " .. AddLvl .. " Level!", 0)
    end
end

hook.Add("PlayerSay", "zrmine.lvlsys.GiveLVL_id", zrmine.lvlsys.AdminGiveLvl)

function zrmine.lvlsys.AdminGiveSelfLvl(ply, text, team)
    local atext = string.lower(text)
    local size = string.len(atext)

    if (string.sub(atext, 1, 17) == "!zrms_giveselflvl" and (size >= 17)) then
        if not zrmine.f.IsAdmin(ply) then
            zrmine.f.Notify(ply, zrmine.language.Cmd_NoPermission, 1)

            return
        end

        local foundply = ply
        local AddLvl = tonumber(string.sub(atext, 18, size))

        if (AddLvl == nil or AddLvl <= 0) then
            zrmine.f.Notify(ply, "Not a valid number!", 1)

            return
        end

        if (not IsValid(foundply) or not foundply:IsPlayer()) then
            zrmine.f.Notify(ply, "No Valid Player Found!", 1)

            return
        end

        zrmine.lvlsys.AddLvl(foundply, tonumber(AddLvl))
        zrmine.f.Notify(ply, "You gave yourself " .. AddLvl .. " Level!", 0)
    end
end

hook.Add("PlayerSay", "zrmine.lvlsys.GiveSelfLVL_id", zrmine.lvlsys.AdminGiveSelfLvl)

-- Level Up
function zrmine.lvlsys.LevelUpCheck(ply)
    local PlyLvl = ply.zrms.lvl
    local PlyXP = ply.zrms.xp

    if (zrmine.config.Pickaxe_Lvl[PlyLvl + 1] and PlyXP >= zrmine.config.Pickaxe_Lvl[PlyLvl].NextXP) then
        zrmine.lvlsys.AddLvl(ply, 1)
        zrmine.lvlsys.SetXP(ply, zrmine.lvlsys.HasXP(ply) - zrmine.config.Pickaxe_Lvl[PlyLvl].NextXP)
        zrmine.f.Notify(ply, zrmine.language.LvlSys_LvlUp, 0)
    end

    zrmine.lvlsys.SwepUpdate(ply)
end

-- XP
function zrmine.lvlsys.AddXP(ply, amount)
    if (amount ~= nil) then
        ply.zrms.xp = ((ply.zrms.xp or 0) + amount)
    else
        ply.zrms.xp = ply.zrms.xp or 0
    end

    zrmine.data.DataChanged(ply)
    zrmine.lvlsys.LevelUpCheck(ply)
end

function zrmine.lvlsys.SetXP(ply, amount)
    if (amount ~= nil) then
        ply.zrms.xp = amount
    end

    zrmine.lvlsys.SwepUpdate(ply)
    zrmine.data.DataChanged(ply)
    zrmine.lvlsys.LevelUpCheck(ply)
end

function zrmine.lvlsys.HasXP(ply)
    local xp = (ply.zrms.xp or 0)

    return xp
end

-- Lvl
function zrmine.lvlsys.AddLvl(ply, amount)
    local setAmount = ((ply.zrms.lvl or 0) + amount)

    if (setAmount > (table.Count(zrmine.config.Pickaxe_Lvl) - 1)) then
        setAmount = table.Count(zrmine.config.Pickaxe_Lvl) - 1
    end

    if (amount ~= nil) then
        ply.zrms.lvl = setAmount
    else
        ply.zrms.lvl = amount
    end

    if (ply.zrms.lvl >= (table.Count(zrmine.config.Pickaxe_Lvl) - 1)) then
        zrmine.f.Notify(ply, zrmine.language.LvlSys_LvlMax, 0)
    end

    zrmine.lvlsys.SwepUpdate(ply)
    zrmine.data.DataChanged(ply)
end

function zrmine.lvlsys.SetLvl(ply, amount)
    if (amount ~= nil) then
        ply.zrms.lvl = amount
    else
        ply.zrms.lvl = 0
    end

    zrmine.lvlsys.SwepUpdate(ply)
    zrmine.data.DataChanged(ply)
end

function zrmine.lvlsys.ReturnLvl(ply)
    local lvl = (ply.zrms.lvl or 0)

    return lvl
end

function zrmine.lvlsys.PlayerReset(ply)
    zrmine.lvlsys.SetXP(ply, 0)
    zrmine.lvlsys.SetLvl(ply, 0)
    zrmine.lvlsys.SwepUpdate(ply)
    zrmine.f.Notify(ply, zrmine.language.LvlSys_LvlReset, 1)
end

function zrmine.lvlsys.SwepUpdate(ply)
    if (ply:HasWeapon("zrms_pickaxe")) then
        ply:GetWeapon("zrms_pickaxe"):UpdateLvlVar()
    end
end
