local meta = FindMetaTable("Player")
local start_xp = SuR.Config.Start_Level_XP
local lvl_mult = SuR.Config.Level_Progress_Mult

file.CreateDir("surrounded/level/")

function meta:SetPlayerClass(id)
    id = id or "survivor"
    self:SetNWString("PlayerClass", id)

    local lvl, xp = unpack(self.LevelTab[id])
    local class = self:GetPlayerClass()
    self:SetLevel(lvl)
    self:AddXP(xp)
end

function meta:SetLevel(lvl)
    if !isnumber(lvl) or lvl < 1 then return end

    self:SetNWFloat("PlayerLevel", math.min(lvl, 21))
    self:SetNWFloat("PlayerXP", 0)

    local class = self:GetPlayerClass()
    local lvl, cur_xp = self:GetLevel()
    self.LevelTab[class] = {lvl, cur_xp}
end

function meta:AddXP(num)
    if !isnumber(num) or self:GetLevel() >= 21 then return end

    local lvl, cur_xp = self:GetLevel()
    self:SetNWFloat("PlayerXP", math.max(cur_xp+num, 0))

    local need = self:GetXPToLevel()
    if need == 0 then
        self:SetLevel(lvl+1)
    end

    local class = self:GetPlayerClass()
    local lvl, cur_xp = self:GetLevel()
    self.LevelTab[class] = {lvl, cur_xp}
end

function meta:LoadLevelProgress()
    local id = self:SteamID64()
    local f = file.Read("surrounded/level/"..id..".json", "DATA")
    local tab = {
        ["survivor"] = {1, 0},
        ["scout"] = {1, 0},
        ["medic"] = {1, 0},
        ["engineer"] = {1, 0},
        ["marksman"] = {1, 0},
        ["berserker"] = {1, 0},
        ["demoman"] = {1, 0},
        cur_class = "survivor"
    }
    if isstring(f) then
        f = util.JSONToTable(f)
        tab = f
    end
    self.LevelTab = tab
    self:SetPlayerClass(tab.cur_class)
end

function meta:SaveLevelProgress()
    local id = self:SteamID64()
    local lvl, cur_xp = self:GetLevel()
    local tab = {}
    for k, v in pairs(self.LevelTab) do
        tab[k] = v
    end
    tab.cur_class = self:GetPlayerClass()

    file.Write("surrounded/level/"..id..".json", util.TableToJSON(tab, true))
end

hook.Add("PlayerDisconnected", "SuR.SaveProgress", function(ply)
    ply:SaveLevelProgress()
end)

hook.Add("ShutDown", "SuR.SaveProgress", function()
    for _, ply in ipairs(player.GetAll()) do
        ply:SaveLevelProgress()
    end
end)

concommand.Add("sur_selectclass", function(ply, cmd, args)
    local str = args[1]
	if not str or ply:Alive() then return end
    if not SuR.Config.ClassIcons[str] then return end

    ply:SetPlayerClass(str)
end)

net.Receive("SuR.OpenClassMenu", function(len, ply)
    net.Start("SuR.OpenClassMenu")
    net.WriteTable(ply.LevelTab)
    net.Send(ply)
end)