using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

/// <summary>
/// Manager singleton pour stocker les données du jeu récupérées depuis l'API
/// Endpoint: /api/ujsa/games/{gameId}?difficulty={difficulty}
/// </summary>
public class GameDataManager : MonoBehaviour
{
    private static GameDataManager _instance;
    public static GameDataManager Instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject go = new GameObject("GameDataManager");
                _instance = go.AddComponent<GameDataManager>();
                DontDestroyOnLoad(go);
            }
            return _instance;
        }
    }

    // Données du jeu en cours
    public APIGameData CurrentGameData { get; private set; }
    public int CurrentGameId { get; private set; } // ID du jeu pour l'API answers
    public bool IsLoading { get; private set; }
    public bool HasData => CurrentGameData != null;

    void Awake()
    {
        if (_instance == null)
        {
            _instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else if (_instance != this)
        {
            Destroy(gameObject);
        }
    }

    /// <summary>
    /// Charge les données d'un jeu depuis l'API
    /// </summary>
    /// <param name="gameId">ID du jeu</param>
    /// <param name="difficulty">Niveau de difficulté (défaut: "Débutant")</param>
    /// <param name="onSuccess">Callback appelé en cas de succès</param>
    /// <param name="onError">Callback appelé en cas d'erreur</param>
    public void LoadGameData(int gameId, string difficulty = "Débutant", System.Action<APIGameData> onSuccess = null, System.Action<string> onError = null)
    {
        StartCoroutine(LoadGameDataCoroutine(gameId, difficulty, onSuccess, onError));
    }

    private IEnumerator LoadGameDataCoroutine(int gameId, string difficulty, System.Action<APIGameData> onSuccess, System.Action<string> onError)
    {
        IsLoading = true;
        CurrentGameData = null;
        CurrentGameId = gameId; // Stocker l'ID du jeu pour l'API answers

        // Construire l'URL de l'API
        string apiUrl = GeneralConfigManager.Instance?.GetGameConfigApiUrl(gameId, difficulty);
        
        if (string.IsNullOrEmpty(apiUrl))
        {
            Debug.LogError("[GameDataManager] ❌ Impossible de construire l'URL de l'API games");
            IsLoading = false;
            onError?.Invoke("URL API non disponible");
            yield break;
        }

        Debug.Log($"[GameDataManager] 🎮 Chargement des données du jeu {gameId} (difficulté: {difficulty})...");
        Debug.Log($"[GameDataManager] 🌐 URL: {apiUrl}");

        // Récupérer le token d'authentification
        string token = UserDataManager.Instance?.token;

        using (UnityWebRequest www = UnityWebRequest.Get(apiUrl))
        {
            // Ajouter l'authentification Bearer Token
            if (!string.IsNullOrEmpty(token))
            {
                www.SetRequestHeader("Authorization", $"Bearer {token}");
                Debug.Log($"[GameDataManager] ✅ Token ajouté à la requête");
            }
            else
            {
                Debug.LogWarning("[GameDataManager] ⚠️ Pas de token - requête sans authentification");
            }

            yield return www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError($"[GameDataManager] ❌ Erreur de chargement: {www.error}");
                Debug.LogError($"[GameDataManager] Code HTTP: {www.responseCode}");
                if (!string.IsNullOrEmpty(www.downloadHandler?.text))
                {
                    Debug.LogError($"[GameDataManager] Réponse: {www.downloadHandler.text}");
                }
                IsLoading = false;
                onError?.Invoke(www.error);
                yield break;
            }

            string jsonData = www.downloadHandler.text;
            Debug.Log($"[GameDataManager] ✅ Données reçues ({jsonData.Length} caractères)");
            // Afficher les 1000 premiers caractères pour éviter la troncature
            string jsonPreview = jsonData.Length > 1000 ? jsonData.Substring(0, 1000) + "..." : jsonData;
            Debug.Log($"[GameDataManager] 📋 JSON (aperçu): {jsonPreview}");

            try
            {
                APIGameResponse response = JsonUtility.FromJson<APIGameResponse>(jsonData);

                if (response != null && response.status == "success" && response.data != null)
                {
                    CurrentGameData = response.data;
                    
                    Debug.Log($"[GameDataManager] ✅ Données du jeu parsées avec succès");
                    Debug.Log($"[GameDataManager] 📊 Background: {CurrentGameData.background?.type} - {CurrentGameData.background?.url}");
                    Debug.Log($"[GameDataManager] 📊 Questions: {CurrentGameData.questions?.Length ?? 0}");
                    Debug.Log($"[GameDataManager] 📊 Zones: {CurrentGameData.zones?.Length ?? 0}");
                    Debug.Log($"[GameDataManager] 📊 Dialogues:");
                    Debug.Log($"[GameDataManager]    - Intro: {(CurrentGameData.dialogues?.intro != null ? "✅ " + (CurrentGameData.dialogues.intro.lines?.Length ?? 0) + " lignes" : "❌")}");
                    Debug.Log($"[GameDataManager]    - Success: {(CurrentGameData.dialogues?.success != null ? "✅ " + (CurrentGameData.dialogues.success.lines?.Length ?? 0) + " lignes" : "❌")}");
                    Debug.Log($"[GameDataManager]    - Fail: {(CurrentGameData.dialogues?.fail != null ? "✅ " + (CurrentGameData.dialogues.fail.lines?.Length ?? 0) + " lignes" : "❌")}");

                    IsLoading = false;
                    onSuccess?.Invoke(CurrentGameData);
                }
                else
                {
                    Debug.LogError($"[GameDataManager] ❌ Réponse API invalide");
                    Debug.LogError($"[GameDataManager] Status: {response?.status}");
                    Debug.LogError($"[GameDataManager] Message: {response?.message}");
                    IsLoading = false;
                    onError?.Invoke(response?.message ?? "Réponse API invalide");
                }
            }
            catch (System.Exception e)
            {
                Debug.LogError($"[GameDataManager] ❌ Erreur de parsing: {e.Message}");
                Debug.LogError($"[GameDataManager] Stack: {e.StackTrace}");
                IsLoading = false;
                onError?.Invoke($"Erreur de parsing: {e.Message}");
            }
        }
    }

    /// <summary>
    /// Efface les données du jeu en cours
    /// </summary>
    public void ClearGameData()
    {
        CurrentGameData = null;
        CurrentGameId = 0;
        Debug.Log("[GameDataManager] 🗑️ Données du jeu effacées");
    }

    /// <summary>
    /// Récupère les questions du jeu en cours au format compatible avec le système existant
    /// </summary>
    public Question[] GetQuestionsForGame()
    {
        if (CurrentGameData?.questions == null) return null;

        Question[] questions = new Question[CurrentGameData.questions.Length];
        
        for (int i = 0; i < CurrentGameData.questions.Length; i++)
        {
            var apiQ = CurrentGameData.questions[i];
            questions[i] = new Question
            {
                id = apiQ.id,
                question = apiQ.question,
                explanation = apiQ.explanation ?? "",
                points = 1, // Par défaut 1 point par question
                answerCount = apiQ.answers?.Length ?? 0,
                answers = new System.Collections.Generic.List<Answer>()
            };

            if (apiQ.answers != null)
            {
                for (int j = 0; j < apiQ.answers.Length; j++)
                {
                    var apiA = apiQ.answers[j];
                    questions[i].answers.Add(new Answer
                    {
                        id = apiA.id, // ID de l'option pour l'API answers
                        text = apiA.text,
                        isCorrect = apiA.is_correct,
                        zoneId = apiA.zoneId ?? $"zone{j + 1}", // Utiliser zoneId de l'API ou générer
                        choiceIndex = j
                    });
                }
            }
        }

        return questions;
    }
}

