local storage = core.get_mod_storage()

local function unlock_new_weapons() end
local function unlock_new_skills() end
local function initialise_xp() end
local function remove_deprecated_equipment() end

local p_data = {}     -- KEY: p_name, INDEX: {equip = {weapons = {...}, skill = s_name}, xp = {w1 = {..}, w2 = {..}, ...},
                                        -- weapons = {w_name = {var1 = true,var2 = true}, w_name = {..}},
                                        -- stats =  {(int) last_loaded, (int) weekly_time_spent_playing}}

local DEFAULT_WEAPONS = {"block_league:smg", "block_league:sword", "block_league:pixelgun"}
local DEFAULT_SKILL   = "block_league:hp"



-- non esporre
function block_league.load_player_data(p_name)
  -- primo accesso
  if storage:get_string(p_name) == "" then
    p_data[p_name] = {}
    p_data[p_name].stats = {last_loaded = os.time(), weekly_time_spent_playing = 0, has_skipped_tutorial = false}
    p_data[p_name].equip = { weapons = DEFAULT_WEAPONS, skill = DEFAULT_SKILL}
    p_data[p_name].exp = {_LV = 0}
    p_data[p_name].weapons = block_league.unlock_default_weapons(p_name)
    block_league.unlock_default_skills(p_name)  -- qua gestisce la mod `skills`

    for k, _ in pairs(block_league.get_weapons_supporting_xp()) do
      p_data[p_name].exp[k] = {lv = 0, xp = 0, stored = 0}
    end

    storage:set_string(p_name, core.serialize(p_data[p_name]))

  -- sennò carica
  else
    p_data[p_name] = core.deserialize(storage:get_string(p_name))

    remove_deprecated_equipment(p_name, p_data[p_name].equip)

    -- for players before the xp system was a thing
    if not p_data[p_name].exp then
      initialise_xp(p_name)
    end

    if not p_data[p_name].stats then
      p_data[p_name].stats = {last_loaded = os.time(), weekly_time_spent_playing = 0, has_skipped_tutorial = false}
    end

    if p_data[p_name].stats.has_skipped_tutorial == nil then
      p_data[p_name].stats.has_skipped_tutorial = false
    end

    -- same but for weaps and skills
    if not p_data[p_name].weapons then
      p_data[p_name].weapons = block_league.unlock_default_weapons(p_name)
    end

    -- nel caso la banca dati di skills sia stata azzerata
    if not next(p_name:get_unlocked_skills("block_league")) then
      block_league.unlock_default_skills(p_name)
    end

    unlock_new_weapons(p_name)
    unlock_new_skills(p_name)
  end

  -- riempio le rispettive tabelle lua
  block_league.load_equip(p_name, p_data[p_name].equip, p_data[p_name].weapons)
  block_league.load_xp(p_name, p_data[p_name].exp)
  block_league.load_stats(p_name, p_data[p_name].stats)
end



-- non esporre
function block_league.unload_player_data(p_name)
  block_league.unload_equip(p_name)
  block_league.unload_xp(p_name)
  block_league.unload_stats(p_name)
  p_data[p_name] = nil
end



-- meglio tenere `type` e `param`, dato che si allacceranno armi, abilità,
-- esperienza e valuta della mod
function block_league.update_storage(p_name, type, param, delete)  -- TODO: 'sto parametro `delete` così non è proprio il massimo
  if type == "equip_w" then
    p_data[p_name].equip.weapons = param
  elseif type == "equip_s" then
    p_data[p_name].equip.skill = param
  elseif type == "xp" then
    p_data[p_name].exp = param
  elseif type == "weapon" then
    if delete then
      p_data[p_name].weapons[param] = nil
    else
      p_data[p_name].weapons[param] = {}
    end
  elseif type == "skill" then
    p_data[p_name].skills[param] = {}
  elseif type == "weapon_var" then
    local w_data = string.split(param, "@") -- {"nome", "variante"}
    if delete then
      p_data[p_name].weapons[w_data[1]][w_data[2]] = nil
    else
      p_data[p_name].weapons[w_data[1]][w_data[2]] = true
    end
  elseif type == "skill_var" then
    local s_data = string.split(param, "@") -- {"nome", "variante"}
    if delete then
      p_data[p_name].skills[s_data[1]][s_data[2]] = nil
    else
      p_data[p_name].skills[s_data[1]][s_data[2]] = true
    end
  elseif type == "stats" then
    p_data[p_name].stats = param
  end

  storage:set_string(p_name, core.serialize(p_data[p_name]))
end



function block_league.try_to_load_player(p_name)
  if not core.get_player_by_name(p_name) and block_league.is_player_in_storage(p_name) then
    block_league.load_player_data(p_name)
  end
end



function block_league.is_player_in_storage(p_name)
  return storage:get_string(p_name) ~= ""
end





----------------------------------------------
---------------FUNZIONI LOCALI----------------
----------------------------------------------

function unlock_new_weapons(p_name)
  local to_update = false

  --if not block_league.has_weapon(p_name, w_name) then
    -- lancia p_data[p_name].exp[w_name] = {lv = 0, xp = 0, stored = 0} + block_league.set_xp
    --to_update = true
  --end

  if to_update then
    storage:set_string(p_name, core.serialize(p_data[p_name]))
  end
end



function unlock_new_skills(p_name)
  local skills = skills.get_unlocked_skills(p_name, "block_league")

  if not skills["block_league:invisibility"] then
    p_name:unlock_skill("block_league:invisibility")
  end
end



function initialise_xp(p_name)
  p_data[p_name].exp = {_LV = 0, weekly_amount = {}}
  for k, _ in pairs(block_league.get_weapons_supporting_xp()) do
    p_data[p_name].exp[k] = {lv = 0, xp = 0, stored = 0}
  end

  storage:set_string(p_name, core.serialize(p_data[p_name]))
end



function remove_deprecated_equipment(p_name, equip)
  local to_update = false

  for i, w_name in ipairs(equip.weapons) do
    if w_name == "block_league:kunai" then
      equip.weapons[i] = "block_league:sentry_gun"
      to_update = true
    end
  end

  if to_update then
    block_league.update_storage(p_name, "equip_w", equip.weapons)
  end
end