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

namespace CoolGameX
{
    /// <summary>
    /// Drop-in component — the zero-code way to wire a game into Cool GameX.
    ///
    /// 1. Create an empty GameObject, add this component.
    /// 2. Set "Game Slug" (and your server URL).
    /// 3. Done — it initializes the SDK, logs in with the launcher token, and
    ///    tracks playtime automatically.
    ///
    /// To unlock an achievement from anywhere:
    /// <code>CoolGameXManager.Unlock("speed_runner");</code>
    /// </summary>
    [AddComponentMenu("Cool GameX/Cool GameX Manager")]
    [DisallowMultipleComponent]
    public class CoolGameXManager : MonoBehaviour
    {
        [Header("Config")]
        [Tooltip("Must match the game's slug in Cool GameX.")]
        public string gameSlug = "your-game-slug";

        [Tooltip("Your backend URL. http://localhost:4000 while developing.")]
        public string serverUrl = "http://localhost:4000";

        [Header("Playtime")]
        [Tooltip("Automatically start/stop a playtime session with the game.")]
        public bool trackPlaytime = true;

        [Tooltip("Report playtime every N minutes so it survives a crash. 0 = off.")]
        public int heartbeatMinutes = 5;

        [Header("Editor testing only")]
        [Tooltip("Paste a JWT from 'node scripts/get-token.js'. Leave blank in builds.")]
        [TextArea]
        public string editorTestToken = "";

        /// <summary>Raised when an achievement unlocks for the first time (slug).</summary>
        public static event Action<string> AchievementUnlocked;

        public static CoolGameXManager Instance { get; private set; }
        public static bool Ready { get; private set; }

        private float _heartbeat;

        async void Awake()
        {
            if (Instance != null) { Destroy(gameObject); return; }
            Instance = this;
            DontDestroyOnLoad(gameObject);

            await CoolAPI.Initialize(gameSlug, serverUrl);
            CoolAPI.Achievements.OnAchievementUnlocked += HandleUnlocked;

            // Verify we can reach the server (sets CoolAPI.IsConnected).
            await CoolAPI.CheckConnection();
            if (!CoolAPI.IsConnected)
                Debug.LogWarning($"[CoolAPI] Can't reach the server at {serverUrl}.");

            string token = CoolAPI.IsAuthenticated ? CoolAPI.Token : editorTestToken?.Trim();
            if (!string.IsNullOrEmpty(token))
            {
                Ready = await CoolAPI.Auth.LoginWithToken(token);
                Debug.Log(Ready ? "[CoolAPI] Ready." : $"[CoolAPI] Login failed: {CoolAPI.LastError}");
            }
            else
            {
                Debug.Log("[CoolAPI] No token (running outside the launcher).");
            }

            if (trackPlaytime) CoolAPI.Playtime.StartSession();
        }

        void Update()
        {
            if (!trackPlaytime || heartbeatMinutes <= 0 || !Ready) return;
            _heartbeat += Time.unscaledDeltaTime;
            if (_heartbeat >= heartbeatMinutes * 60f)
            {
                _heartbeat = 0f;
                _ = CoolAPI.Playtime.ReportMinutes(heartbeatMinutes);
            }
        }

        async void OnApplicationQuit()
        {
            if (trackPlaytime) await CoolAPI.Playtime.EndSession();
        }

        private void HandleUnlocked(string slug) => AchievementUnlocked?.Invoke(slug);

        // ---- Static helpers ------------------------------------------------

        /// <summary>Unlock an achievement by slug. Fire-and-forget.</summary>
        public static void Unlock(string achievementSlug)
        {
            if (Instance == null)
            {
                Debug.LogWarning("[CoolAPI] No CoolGameXManager in the scene.");
                return;
            }
            _ = CoolAPI.Achievements.Unlock(achievementSlug);
        }

        /// <summary>Unlock an achievement and await the detailed result.</summary>
        public static Task<UnlockResult> UnlockAsync(string achievementSlug)
            => CoolAPI.Achievements.UnlockDetailed(achievementSlug);

        /// <summary>Set a numeric stat to an exact value. Fire-and-forget.</summary>
        public static void SetStat(string key, int value)
        {
            if (Instance == null) { Debug.LogWarning("[CoolAPI] No CoolGameXManager in the scene."); return; }
            _ = CoolAPI.Stats.Set(key, value);
        }

        /// <summary>Increment a numeric stat by <paramref name="amount"/>. Fire-and-forget.</summary>
        public static void AddStat(string key, int amount = 1)
        {
            if (Instance == null) { Debug.LogWarning("[CoolAPI] No CoolGameXManager in the scene."); return; }
            _ = CoolAPI.Stats.Add(key, amount);
        }
    }
}
