using System;
using System.Threading.Tasks;
using UnityEngine;

namespace CoolGameX
{
    /// <summary>
    /// Per-player, per-game numeric stats — e.g. enemies killed, levels cleared,
    /// coins collected, a high score. Stats are stored on the Cool GameX backend
    /// and persist across machines.
    /// <code>
    /// await CoolAPI.Stats.Add("enemies_killed", 1);
    /// await CoolAPI.Stats.Set("high_score", 9001);
    /// int kills = await CoolAPI.Stats.Get("enemies_killed");
    /// </code>
    /// </summary>
    public class Stats
    {
        [Serializable] private class ValueResponse { public string key; public int value; }

        /// <summary>Sets a stat to an exact value. Returns true on success.</summary>
        public async Task<bool> Set(string key, int value)
        {
            if (string.IsNullOrEmpty(key)) { Debug.LogWarning("[CoolAPI] Stats.Set: empty key."); return false; }
            var json = $"{{\"gameSlug\":\"{Escape(CoolAPI.GameSlug)}\",\"key\":\"{Escape(key)}\",\"value\":{value}}}";
            var res = await Net.PostJson("/api/stats/set", json);
            return res.Success;
        }

        /// <summary>
        /// Increments a stat by <paramref name="amount"/> (default 1) and returns
        /// the new total (or -1 if the call failed).
        /// </summary>
        public async Task<int> Add(string key, int amount = 1)
        {
            if (string.IsNullOrEmpty(key)) { Debug.LogWarning("[CoolAPI] Stats.Add: empty key."); return -1; }
            var json = $"{{\"gameSlug\":\"{Escape(CoolAPI.GameSlug)}\",\"key\":\"{Escape(key)}\",\"amount\":{amount}}}";
            var res = await Net.PostJson("/api/stats/add", json);
            if (!res.Success) return -1;
            try { return JsonUtility.FromJson<ValueResponse>(res.Body)?.value ?? 0; }
            catch { return 0; }
        }

        /// <summary>Reads a single stat. Returns 0 if it has never been set.</summary>
        public async Task<int> Get(string key)
        {
            if (string.IsNullOrEmpty(key)) return 0;
            var res = await Net.Get(
                $"/api/stats?gameSlug={Uri.EscapeDataString(CoolAPI.GameSlug)}&key={Uri.EscapeDataString(key)}",
                auth: true);
            if (!res.Success) return 0;
            try { return JsonUtility.FromJson<ValueResponse>(res.Body)?.value ?? 0; }
            catch { return 0; }
        }

        /// <summary>
        /// Returns the raw JSON of all stats for this game:
        /// <c>{"stats":[{"key":"...","value":0}, ...]}</c>. Parse with your JSON
        /// library of choice.
        /// </summary>
        public async Task<string> GetAllJson()
        {
            var res = await Net.Get(
                $"/api/stats?gameSlug={Uri.EscapeDataString(CoolAPI.GameSlug)}", auth: true);
            return res.Success ? res.Body : null;
        }

        private static string Escape(string s) =>
            s?.Replace("\\", "\\\\").Replace("\"", "\\\"") ?? "";
    }
}
