-- Define a table to store players' playtime
local playtime_data = {}

-- Function to initialize playtime for a player
local function init_playtime(player_name)
    if not playtime_data[player_name] then
        playtime_data[player_name] = {
            total_playtime = 0,
            last_login = os.time()
        }
    end
end

-- Function to update playtime for a player
local function update_playtime(player, dtime)
    local player_name = player:get_player_name()
    if player_name then
        init_playtime(player_name)
        -- Convert dtime from milliseconds to seconds
        dtime = dtime / 1000
        playtime_data[player_name].total_playtime = playtime_data[player_name].total_playtime + dtime
    end
end

-- Register callback to update playtime every 30 seconds
minetest.register_globalstep(function(dtime)
    local timer = 30 -- Update every 30 seconds
    for _, player in ipairs(minetest.get_connected_players()) do
        update_playtime(player, timer)
    end
end)

-- Function to handle /playtimes command
minetest.register_chatcommand("playtimes", {
    params = "[--top N] [--prefix prefix]",
    description = "Displays playtimes for players",
    privs = {},
    func = function(name, param)
        local top_count = tonumber(param:match("%-t%s*(%d+)")) or 0
        if top_count <= 0 then
            top_count = nil
        end
        
        local prefix = param:match("%-p%s*(%a+)")
        
        local output = "Playtimes:\n"
        
        -- Sort playtime data by total_playtime
        local sorted_players = {}
        for player_name, data in pairs(playtime_data) do
            if not prefix or player_name:lower():sub(1, #prefix) == prefix:lower() then
                table.insert(sorted_players, {name = player_name, playtime = data.total_playtime})
            end
        end
        table.sort(sorted_players, function(a, b) return a.playtime > b.playtime end)
        
        -- Display top N players or all players if N is not specified
        local count = 0
        for _, player_info in ipairs(sorted_players) do
            local total_seconds = math.floor(player_info.playtime)
            local hours = math.floor(total_seconds / 3600)
            local minutes = math.floor((total_seconds % 3600) / 60)
            local seconds = total_seconds % 60
            output = output .. player_info.name .. ": " .. hours .. " hours, " .. minutes .. " minutes, " .. seconds .. " seconds\n"
            count = count + 1
            if top_count and count >= top_count then
                break
            end
        end
        
        minetest.chat_send_player(name, output)
    end,
})

-- Load playtime data on server startup
local playtime_file = minetest.get_worldpath().."/playtime_data.json"
local file = io.open(playtime_file, "r")
if file then
    local content = file:read("*all")
    playtime_data = minetest.parse_json(content) or {}
    file:close()
end

-- Save playtime data on server shutdown
minetest.register_on_shutdown(function()
    local file = io.open(playtime_file, "w")
    if file then
        file:write(minetest.write_json(playtime_data))
        file:close()
    end
end)
