using System;

namespace CoolGameX
{
    /// <summary>How chatty the SDK is in the Unity console.</summary>
    public enum CGXLogLevel { None = 0, Errors = 1, Warnings = 2, Info = 3, Verbose = 4 }

    /// <summary>
    /// Who measures playtime. <c>Auto</c> lets the Cool GameX launcher do it when the
    /// game was started from the launcher (it times the process exactly) and has the
    /// SDK do it otherwise — so minutes are never counted twice.
    /// </summary>
    public enum PlaytimeTracking { Auto = 0, Always = 1, Never = 2 }

    /// <summary>When the F8 debug overlay is available.</summary>
    public enum DebugOverlayMode { Never = 0, EditorOnly = 1, EditorAndDevelopmentBuilds = 2, Always = 3 }

    /// <summary>
    /// When to draw the SDK's own in-game "achievement unlocked" toasts. The launcher
    /// already shows a popup over the game, so by default the SDK only does it when
    /// the game wasn't started from the launcher (e.g. in the Editor).
    /// </summary>
    public enum ToastMode { Never = 0, WhenNotLaunchedFromLauncher = 1, Always = 2 }

    /// <summary>Leaderboard ordering. Descending = highest score wins.</summary>
    public enum SortOrder { Descending = 0, Ascending = 1 }

    /// <summary>The signed-in player.</summary>
    [Serializable]
    public class PlayerProfile
    {
        public string id;
        public string username;
        public string avatar_url;
        /// <summary>The game this session is scoped to (game tokens only).</summary>
        public string gameSlug;
        /// <summary>"game" for a launcher/editor session token, "account" for a raw login token.</summary>
        public string tokenType;
        public long expiresAt;
    }

    /// <summary>An achievement definition, plus the player's unlock state when known.</summary>
    [Serializable]
    public class AchievementInfo
    {
        public string slug;
        public string name;
        public string description;
        public int points;
        public bool is_hidden;
        public string icon_url;
        public bool unlocked;
        /// <summary>ISO-8601 timestamp, or empty.</summary>
        public string unlocked_at;
    }

    /// <summary>Result of an achievement unlock.</summary>
    public struct UnlockResult
    {
        /// <summary>The unlock was recorded (or safely queued to sync later).</summary>
        public bool Success;
        /// <summary>True only the first time the player gets it.</summary>
        public bool NewlyUnlocked;
        /// <summary>The device was offline — the unlock was saved and will sync automatically.</summary>
        public bool Queued;
        /// <summary>Error message when <see cref="Success"/> is false.</summary>
        public string Error;
    }

    /// <summary>A named player stat.</summary>
    [Serializable]
    public class StatEntry
    {
        public string key;
        public int value;
    }

    /// <summary>Result of submitting a leaderboard score.</summary>
    public struct SubmitResult
    {
        public bool Success;
        /// <summary>The submitted score beat the player's previous best.</summary>
        public bool Improved;
        /// <summary>The score now on the board for this player (their best, by default).</summary>
        public long Score;
        /// <summary>1-based rank on the board.</summary>
        public int Rank;
        public string Error;
    }

    [Serializable]
    public class LeaderboardEntry
    {
        public int rank;
        public string user_id;
        public string username;
        public string avatar_url;
        public long score;
        public string metadata;
        public string updated_at;
    }

    [Serializable]
    public class LeaderboardInfo
    {
        public string slug;
        public string name;
        /// <summary>"desc" or "asc".</summary>
        public string sort;
    }

    [Serializable]
    public class LeaderboardRank
    {
        public int rank;
        public long score;
    }

    /// <summary>A page of leaderboard entries.</summary>
    [Serializable]
    public class LeaderboardPage
    {
        public LeaderboardInfo board;
        /// <summary>Total players on the board (top lists only).</summary>
        public int total;
        /// <summary>The player's own rank (around-me lists only; rank 0 when not on the board).</summary>
        public LeaderboardRank me;
        public LeaderboardEntry[] entries = Array.Empty<LeaderboardEntry>();
        /// <summary>False when the request failed — see <see cref="CoolAPI.LastError"/>.</summary>
        [NonSerialized] public bool ok;
    }

    /// <summary>A cloud save slot (without its data).</summary>
    [Serializable]
    public class SaveSlot
    {
        public string key;
        public int size;
        public string updated_at;
    }
}
