local S = core.get_translator("block_league")

local function check_last_login_weekly_time() end
local function seconds_to_clock() end
local function get_weekly_time(p_name) end

local stats = {}      -- KEY: p_name; VAL: {(int) weekly_time_spent_playing}
local WEEKLY_PLAYING_TIME_LIMIT = block_league.WEEKLY_PLAYING_TIME_LIMIT



-- non esporre
function block_league.load_stats(p_name, p_stats)
  check_last_login_weekly_time(p_stats)

  p_stats.last_loaded = os.time()
  stats[p_name] = p_stats

  block_league.update_storage(p_name, "stats", stats[p_name])
end



-- non esporre
function block_league.unload_stats(p_name)
  stats[p_name] = nil
end



-- non esporre
function block_league.update_weekly_time(ar_mode, p_name, amount)
  if ar_mode == 0 then return end -- non contare il tutorial

  stats[p_name].weekly_time_spent_playing = stats[p_name].weekly_time_spent_playing + amount
  block_league.update_storage(p_name, "stats", stats[p_name])
end



-- non esporre
function block_league.print_server_xp_stats(p_name)
  local lvls = {}
  local lvls_sum = 0
  local maxed_weaps = {}
  local MAX_LV = block_league.get_weapons_max_lv()
  local weaps_supporting_xp = {}
  local weekly_time = {}
  local weekly_time_sum = 0

  for w_name, _ in pairs(block_league.get_weapons_supporting_xp()) do
    maxed_weaps[w_name] = 0
    weaps_supporting_xp[#weaps_supporting_xp+1] = w_name
  end

  for pl_name in core.get_auth_handler().iterate() do
    local p_lv = block_league.get_player_level(pl_name)

    if p_lv then
      local has_played_once = false
      for _, w_name in ipairs(block_league.get_equipped_weapons(pl_name, true)) do
        if block_league.get_xp(pl_name, w_name) ~= 0 then
          has_played_once = true
          break
        end
      end

      if has_played_once then
        for _, w_name in ipairs(weaps_supporting_xp) do
          if block_league.get_weapon_lv(pl_name, w_name) == MAX_LV then
            maxed_weaps[w_name] = maxed_weaps[w_name] + 1
          end
        end

        lvls[#lvls+1] = {name = pl_name, lv = p_lv}
        lvls_sum = lvls_sum + p_lv

        local p_weekly_playing_time = get_weekly_time(pl_name)

        if p_weekly_playing_time > 0 then
          weekly_time[#weekly_time+1] = {name = pl_name, amount = p_weekly_playing_time}
          weekly_time_sum = weekly_time_sum + p_weekly_playing_time
        end
      end
    end

    -- evita di sovraccaricare la RAM
    if not core.get_player_by_name(pl_name) then
      block_league.unload_player_data(pl_name)
    end
  end

  -- idem, per skills
  skills.for_each_player_in_db(function() end)

  table.sort(lvls, function(a,b) return a.lv > b.lv end)
  table.sort(weekly_time, function(a,b) return a.amount > b.amount end)

  local lvls_entries = #lvls

  core.chat_send_player(p_name, "\n" .. S("Unique players: @1", lvls_entries) .. "\n"
                                        .. S("Average level: @1", lvls_sum / lvls_entries)
                                        .. "\n--------" .. S("Highest levels") .. "--------")

  for i = 1, math.min(lvls_entries, 10) do
    core.chat_send_player(p_name, i .. ". " .. lvls[i].name .. " (lv. " .. lvls[i].lv .. ")")
  end

  core.chat_send_player(p_name, "---------------------------")
  core.chat_send_player(p_name, "--------" .. S("Maxed weapons") .. "--------")

  for w_name, amnt in pairs(maxed_weaps) do
    core.chat_send_player(p_name, string.sub(w_name, 14, -1) .. " = " .. amnt)
  end

  core.chat_send_player(p_name, "---------------------------")

  local weekly_time_entries = #weekly_time
  local exceeded_playtime = 0

  for _, data in ipairs(weekly_time) do
    if data.amount <= WEEKLY_PLAYING_TIME_LIMIT then break end
    exceeded_playtime = exceeded_playtime + 1
  end

  core.chat_send_player(p_name, S("Average weekly playtime: @1", seconds_to_clock(weekly_time_sum / weekly_time_entries)) .. "\n"
                                .. S("Exceeded weekly playtimes: @1", exceeded_playtime)
                                .. "\n--------" .. S("Highest weekly playtimes") .. "--------")

  for i = 1, math.min(weekly_time_entries, 10) do
    core.chat_send_player(p_name, i .. ". " .. weekly_time[i].name .. " (" .. seconds_to_clock(weekly_time[i].amount) .. ")")
  end

  core.chat_send_player(p_name, "---------------------------\n")
end



function block_league.print_player_stats(p_name)
  block_league.try_to_load_player(p_name)

  if not stats[p_name] then
    return false, S("There is no player in memory called @1!", p_name)
  end

  local output = {
    "\n---------------------------",
    S("Player: @1", p_name),
    S("Level: @1", block_league.get_player_level(p_name)),
    S("Weekly time spent playing: @1", seconds_to_clock(stats[p_name].weekly_time_spent_playing)),
    "---------------------------\n"
  }

  return true, table.concat(output, "\n")
end



function block_league.has_exceeded_weekly_time(p_name)
  block_league.try_to_load_player(p_name)

  if not stats[p_name] then return end

  return stats[p_name].weekly_time_spent_playing > WEEKLY_PLAYING_TIME_LIMIT
end



function block_league.has_skipped_tutorial(p_name)
  block_league.try_to_load_player(p_name)

  if not stats[p_name] then return end

  return stats[p_name].has_skipped_tutorial
end



function block_league.set_tutorial_skip(p_name)
  block_league.try_to_load_player(p_name)

  if not stats[p_name] then return end

  stats[p_name].has_skipped_tutorial = true
  block_league.update_storage(p_name, "stats", stats[p_name])
end





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

function check_last_login_weekly_time(p_stats)
  local last_thursday = (os.date("*t").wday - 5) % 7

  local last_thursday_timestamp = os.time() - (last_thursday * 24 * 60 * 60)
  local last_thursday_midnight = os.date("*t", last_thursday_timestamp)

  last_thursday_midnight.hour = 0
  last_thursday_midnight.min = 0
  last_thursday_midnight.sec = 0

  block_league.print_debug(dump(os.date(nil, os.time(last_thursday_midnight))) .. " | " .. dump(os.date(nil, p_stats.last_loaded)))

  -- controllo se è passato un giovedì dall'ultimo accesso
  if p_stats.last_loaded < os.time(last_thursday_midnight) then
    p_stats.weekly_time_spent_playing = 0
  end
end



function seconds_to_clock(seconds)
  seconds = tonumber(seconds)

  if seconds <= 0 then
    return "00:00:00";
  else
    local hours = string.format("%02.f", math.floor(seconds/3600));
    local mins = string.format("%02.f", math.floor(seconds/60 - (hours * 60)));
    local secs = string.format("%02.f", math.floor(seconds - hours * 3600 - mins * 60));
    return hours..":"..mins..":"..secs
  end
end



function get_weekly_time(p_name)
  block_league.try_to_load_player(p_name)

  return stats[p_name] and stats[p_name].weekly_time_spent_playing
end