/*
 * leaderboard.h — global leaderboard client.
 *
 * Two flows:
 *
 *  1. submit_score() is called after each completed game (manage.cpp). It
 *     POSTs the run's s_hiscore_t to leaderboard_url + "/api/scores". The
 *     game-over screen polls submission() to render the in-flight UI.
 *
 *  2. fetch_board() is called when the in-game leaderboard browser opens.
 *     It GETs the top N for the current board. The browser state polls
 *     browse() to render the list.
 *
 * Both flows are no-ops when prefs->global_leaderboard is 0, or when the
 * board name is empty, or when the URL is empty.
 */
#ifndef KOBO_LEADERBOARD_H
#define KOBO_LEADERBOARD_H

#include "score.h"

#define LEADERBOARD_BROWSE_MAX 50
#define LEADERBOARD_NAME_MAX   32

enum leaderboard_status_t {
    LB_IDLE = 0,
    LB_INFLIGHT,
    LB_DONE,
    LB_FAILED,    // server error, network error, or feature disabled
    LB_OFFLINE    // transport failure (status 0)
};

struct leaderboard_submission_t {
    leaderboard_status_t status;
    int rank;       // valid when status == LB_DONE
    int total;      // valid when status == LB_DONE
};

struct leaderboard_entry_t {
    char         name[LEADERBOARD_NAME_MAX];
    unsigned int score;
    int          end_scene;
};

struct leaderboard_browse_t {
    leaderboard_status_t status;
    int count;
    int total;
    leaderboard_entry_t entries[LEADERBOARD_BROWSE_MAX];
    char board[LEADERBOARD_NAME_MAX];
};

namespace leaderboard {
    // Called from manage.cpp after scorefile.record(). Safe to call always;
    // it self-checks prefs and silently no-ops if disabled.
    void submit_score(const s_hiscore_t *hi);

    // Called from the browser state on enter. Replaces previous results.
    void fetch_board();

    // State accessors — game UI reads these every frame.
    const leaderboard_submission_t *submission();
    const leaderboard_browse_t     *browse();

    // Reset submission state to LB_IDLE (e.g. when starting a new game).
    void reset_submission();
}

#endif // KOBO_LEADERBOARD_H
