using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Networking;

#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif

public class GameLauncher : MonoBehaviour
{
    public enum GamePhase { Before, Shooting, After }

    [Serializable]
    public class GameConfigData
    {
        public string questionsUrl;
        
        // NOUVEAU SYSTÈME : Un seul fichier de dialogues
        public string dialoguesUrl;
        
        // ANCIEN SYSTÈME : Trois fichiers séparés (rétrocompatibilité)
        public string dialogueBeforeUrl;
        public string dialogueSuccessUrl;
        public string dialogueFailUrl;
    }
    
    [Serializable]
    public class GameConfigWrapper
    {
        public GameConfigData gameConfig;
    }

    void Awake()
    {
        DebugLogger.Log("═══════════════════════════════════════", "GameLauncher");
        DebugLogger.Log("GAMELAUNCHER AWAKE - Je suis vivant !", "GameLauncher");
        DebugLogger.Log("═══════════════════════════════════════", "GameLauncher");
    }

    private void Start()
    {
        string phase = PlayerPrefs.GetString("GamePhase", "Before");
        string levelType = PlayerPrefs.GetString("CurrentLevelType", "shooting");
        string levelId = PlayerPrefs.GetString("CurrentLevelId", "unknown");
        
        DebugLogger.LogInfo("═══════════════════════════════════════", "GameLauncher");
        DebugLogger.LogInfo("           GAME LAUNCHER START", "GameLauncher");
        DebugLogger.LogInfo("═══════════════════════════════════════", "GameLauncher");
        DebugLogger.LogInfo($"Phase actuelle: {phase}", "GameLauncher");
        DebugLogger.LogInfo($"Type de jeu: {levelType}", "GameLauncher");
        DebugLogger.LogInfo($"ID niveau: {levelId}", "GameLauncher");
        DebugLogger.LogInfo($"URL config: {PlayerPrefs.GetString("GameConfigUrl")}", "GameLauncher");
        DebugLogger.LogInfo("═══════════════════════════════════════", "GameLauncher");
        
        // NOUVEAU : Charger d'abord la config, puis agir selon la phase
        StartCoroutine(LoadConfigAndExecutePhase());
    }
    
    private IEnumerator LoadConfigAndExecutePhase()
    {
        string configUrl = PlayerPrefs.GetString("GameConfigUrl");
        string phase = PlayerPrefs.GetString("GamePhase", "Before");
        
        if (string.IsNullOrEmpty(configUrl))
        {
            DebugLogger.LogError("Aucune URL de config trouvée dans PlayerPrefs", "GameLauncher");
            yield break;
        }
        
        DebugLogger.LogInfo($"Chargement config depuis: {configUrl}", "GameLauncher");
        
        // Charger le JSON de configuration du jeu
        using (var www = UnityWebRequest.Get(configUrl))
        {
            yield return www.SendWebRequest();
            
            if (www.result != UnityWebRequest.Result.Success)
            {
                DebugLogger.LogError($"Erreur chargement config: {www.error}", "GameLauncher");
                yield break;
            }
            
            GameConfigData config = null;
            try
            {
                var wrapper = JsonUtility.FromJson<GameConfigWrapper>(www.downloadHandler.text);
                config = wrapper.gameConfig;
            }
            catch (Exception e)
            {
                DebugLogger.LogError($"Erreur parsing config: {e.Message}", "GameLauncher");
                yield break;
            }
            
            if (config == null)
            {
                DebugLogger.LogError("Config est null après parsing", "GameLauncher");
                yield break;
            }
            
            // Charger les questions (commun aux deux systèmes)
            string questionsUrl = string.IsNullOrEmpty(config.questionsUrl) ? "" : 
                GeneralConfigManager.Instance.GetQuestionsUrl(config.questionsUrl);
            PlayerPrefs.SetString("QuestionsUrl", questionsUrl);
            Debug.Log($"[GameLauncher] Questions URL: {questionsUrl}");
            
            // NOUVEAU SYSTÈME : Charger depuis un fichier de dialogues groupés
            if (!string.IsNullOrEmpty(config.dialoguesUrl))
            {
                Debug.Log($"[GameLauncher] Utilisation du NOUVEAU système de dialogues : {config.dialoguesUrl}");
                yield return StartCoroutine(LoadGroupedDialogues(config.dialoguesUrl, phase));
            }
            // ANCIEN SYSTÈME : Rétrocompatibilité avec 3 fichiers séparés
            else
            {
                Debug.Log($"[GameLauncher] Utilisation de l'ANCIEN système de dialogues (3 fichiers)");
                
                // Construire les URLs complètes via GeneralConfigManager
                string beforeUrl = string.IsNullOrEmpty(config.dialogueBeforeUrl) ? "" : 
                    GeneralConfigManager.Instance.GetDialogueUrl(config.dialogueBeforeUrl);
                string successUrl = string.IsNullOrEmpty(config.dialogueSuccessUrl) ? "" : 
                    GeneralConfigManager.Instance.GetDialogueUrl(config.dialogueSuccessUrl);
                string failUrl = string.IsNullOrEmpty(config.dialogueFailUrl) ? "" : 
                    GeneralConfigManager.Instance.GetDialogueUrl(config.dialogueFailUrl);
                
                // Stocker les URLs complètes de dialogue pour plus tard
                PlayerPrefs.SetString("DialogueBeforeUrl", beforeUrl);
                PlayerPrefs.SetString("DialogueSuccessUrl", successUrl);
                PlayerPrefs.SetString("DialogueFailUrl", failUrl);
                
                Debug.Log($"[GameLauncher] Before URL: {beforeUrl}");
                
                // Exécuter la phase appropriée
                switch (phase)
                {
                    case "Before":
                        StartBeforeDialogue(beforeUrl);
                        break;
                    case "Shooting":
                        StartGameBasedOnType();
                        break;
                    case "After":
                        StartAfterDialogue();
                        break;
                }
            }
        }
    }
    
    private void StartBeforeDialogue(string beforeUrl)
    {
        Debug.Log($"[GameLauncher] Démarrage dialogue BEFORE: {beforeUrl}");
        
        if (string.IsNullOrEmpty(beforeUrl))
        {
            Debug.Log("[GameLauncher] Pas de dialogue BEFORE, transition directe vers le jeu");
            PlayerPrefs.SetString("GamePhase", "Shooting");
            GoToGameScene();
            return;
        }
        
        // Configurer SubtitleManager avec le dialogue BEFORE
        ConfigureSubtitleManager(beforeUrl, () => {
            Debug.Log("[GameLauncher] Dialogue BEFORE terminé, transition vers le jeu");
            PlayerPrefs.SetString("GamePhase", "Shooting");
            GoToGameScene();
        });
    }

    private void GoToGameScene()
    {
        string levelType = PlayerPrefs.GetString("CurrentLevelType", "shooting");
        
        Debug.Log("═══════════════════════════════════════");
        Debug.Log("        TRANSITION VERS JEU");
        Debug.Log($"Type détecté: '{levelType}'");
        Debug.Log($"Est calculator ? {levelType.ToLowerInvariant() == "calculator"}");
        
        if (levelType.ToLowerInvariant() == "calculator")
        {
            Debug.Log("→ CHARGEMENT SCENE CALCULATOR");
            SceneTransitionManager.LoadSceneWithTransition("calculator");
            StartCoroutine(FallbackTransition("calculator"));
        }
        else
        {
            Debug.Log("→ CHARGEMENT SCENE SHOOTING");
            SceneTransitionManager.LoadSceneWithTransition("shooting");
            StartCoroutine(FallbackTransition("shooting"));
        }
        Debug.Log("═══════════════════════════════════════");
    }

    private IEnumerator FallbackTransition(string sceneName)
    {
        yield return new WaitForSeconds(2f);
        
        if (SceneManager.GetActiveScene().name != sceneName)
        {
            Debug.Log($"[GameLauncher] Transition réussie vers {sceneName}");
            yield break;
        }
        
        Debug.LogWarning($"[GameLauncher] Transition échouée, fallback vers {sceneName}");
        SceneManager.LoadScene(sceneName);
    }
    
    private void StartGameBasedOnType()
    {
        string levelType = PlayerPrefs.GetString("CurrentLevelType", "shooting");
        string configUrl = PlayerPrefs.GetString("GameConfigUrl");
        
        Debug.Log("═══════════════════════════════════════");
        Debug.Log("       DÉMARRAGE GAMEPLAY");
        Debug.Log("═══════════════════════════════════════");
        Debug.Log($"Type de jeu à lancer: '{levelType}'");
        Debug.Log($"Config URL: {configUrl}");
        
        if (levelType.ToLowerInvariant() == "shooting")
        {
            Debug.Log("→ INITIALISATION GAMEMANAGER (SHOOTING)");
            GameManager gm = FindFirstObjectByType<GameManager>();
            if (gm != null)
            {
                Debug.Log($"→ GameManager trouvé, chargement config: {configUrl}");
                gm.LoadGameFromURL(configUrl);
            }
            else
            {
                Debug.LogError("[GameLauncher] GameManager introuvable dans la scène shooting");
            }
        }
        else if (levelType.ToLowerInvariant() == "calculator")
        {
            Debug.Log("→ INITIALISATION CALCULATORGAMEMANAGER");
            Debug.Log($"[GameLauncher] Scène actuelle: {SceneManager.GetActiveScene().name}");
            
            CalculatorGameManager cm = FindFirstObjectByType<CalculatorGameManager>();
            if (cm != null)
            {
                Debug.Log($"→ CalculatorGameManager trouvé, chargement config: {configUrl}");
                cm.LoadGameFromURL(configUrl);
            }
            else
            {
                Debug.LogError("[GameLauncher] CalculatorGameManager introuvable dans la scène calculator");
                Debug.LogError($"[GameLauncher] Scène actuelle: {SceneManager.GetActiveScene().name}");
                
                // Essayer de trouver un GameManager normal comme fallback
                GameManager gm = FindFirstObjectByType<GameManager>();
                if (gm != null)
                {
                    Debug.LogWarning("[GameLauncher] Utilisation du GameManager normal comme fallback");
                    gm.LoadGameFromURL(configUrl);
                }
            }
        }
        else
        {
            Debug.LogError($"[GameLauncher] Type de jeu inconnu: '{levelType}'");
        }
        Debug.Log("═══════════════════════════════════════");
    }
    
    private void StartAfterDialogue()
    {
        string afterUrl = PlayerPrefs.GetString("NextDialogueUrl");
        Debug.Log($"[GameLauncher] Démarrage dialogue AFTER: {afterUrl}");
        
        if (!string.IsNullOrEmpty(afterUrl))
        {
            ConfigureSubtitleManager(afterUrl, () => {
                Debug.Log("[GameLauncher] Dialogue AFTER terminé, retour au menu");
                SceneManager.LoadScene("menu");
            });
        }
        else
        {
            Debug.Log("[GameLauncher] Pas de dialogue AFTER, retour direct au menu");
            SceneManager.LoadScene("menu");
        }
    }
    
    private IEnumerator LoadGroupedDialogues(string dialoguesFileName, string phase)
    {
        // Construire l'URL complète
        string dialoguesUrl = GeneralConfigManager.Instance.GetDialogueUrl(dialoguesFileName);
        Debug.Log($"[GameLauncher] Chargement dialogues groupés depuis: {dialoguesUrl}");
        
        using (UnityWebRequest www = UnityWebRequest.Get(dialoguesUrl))
        {
            yield return www.SendWebRequest();
            
            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError($"[GameLauncher] Erreur chargement dialogues groupés: {www.error}");
                // Fallback : continuer sans dialogues
                PlayerPrefs.SetString("DialogueBeforeUrl", "");
                PlayerPrefs.SetString("DialogueSuccessUrl", "");
                PlayerPrefs.SetString("DialogueFailUrl", "");
                
                if (phase == "Shooting")
                {
                    StartGameBasedOnType();
                }
                yield break;
            }
            
            try
            {
                // Parser le fichier de dialogues groupés
                DialoguesData dialoguesData = JsonUtility.FromJson<DialoguesData>(www.downloadHandler.text);
                
                // Stocker les dialogues en JSON dans PlayerPrefs pour utilisation ultérieure
                if (dialoguesData.dialogues.intro != null)
                {
                    string introJson = JsonUtility.ToJson(new { dialogue = dialoguesData.dialogues.intro });
                    PlayerPrefs.SetString("DialogueIntroJson", introJson);
                    Debug.Log("[GameLauncher] Dialogue INTRO stocké");
                }
                
                if (dialoguesData.dialogues.success != null)
                {
                    string successJson = JsonUtility.ToJson(new { dialogue = dialoguesData.dialogues.success });
                    PlayerPrefs.SetString("DialogueSuccessJson", successJson);
                    Debug.Log("[GameLauncher] Dialogue SUCCESS stocké");
                }
                
                if (dialoguesData.dialogues.fail != null)
                {
                    string failJson = JsonUtility.ToJson(new { dialogue = dialoguesData.dialogues.fail });
                    PlayerPrefs.SetString("DialogueFailJson", failJson);
                    Debug.Log("[GameLauncher] Dialogue FAIL stocké");
                }
                
                // Marquer qu'on utilise le nouveau système
                PlayerPrefs.SetString("DialogueSystemType", "grouped");
                
                // Exécuter la phase appropriée
                switch (phase)
                {
                    case "Before":
                        StartBeforeDialogueFromJson(dialoguesData.dialogues.intro);
                        break;
                    case "Shooting":
                        StartGameBasedOnType();
                        break;
                    case "After":
                        StartAfterDialogue();
                        break;
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"[GameLauncher] Erreur parsing dialogues groupés: {e.Message}");
            }
        }
    }
    
    private void StartBeforeDialogueFromJson(DialogueContent dialogueContent)
    {
        Debug.Log($"[GameLauncher] Démarrage dialogue BEFORE depuis dialogues groupés");
        
        if (dialogueContent == null || dialogueContent.lines == null || dialogueContent.lines.Count == 0)
        {
            Debug.Log("[GameLauncher] Pas de dialogue BEFORE, transition directe vers le jeu");
            PlayerPrefs.SetString("GamePhase", "Shooting");
            GoToGameScene();
            return;
        }
        
        // Configurer SubtitleManager avec le dialogue
        ConfigureSubtitleManagerWithContent(dialogueContent, () => {
            Debug.Log("[GameLauncher] Dialogue BEFORE terminé, transition vers le jeu");
            PlayerPrefs.SetString("GamePhase", "Shooting");
            GoToGameScene();
        });
    }
    
    private void ConfigureSubtitleManagerWithContent(DialogueContent dialogueContent, System.Action onComplete)
    {
        SubtitleManager subtitleManager = FindFirstObjectByType<SubtitleManager>();
        if (subtitleManager != null)
        {
            subtitleManager.OnDialogueComplete = onComplete;
            
            // Appliquer la config de dialogue globale si disponible
            if (LevelManager.Instance != null)
            {
                DialogueConfig globalConfig = LevelManager.Instance.GetDialogueConfig();
                if (globalConfig != null)
                {
                    Debug.Log("[GameLauncher] Application de la config dialogue globale");
                    subtitleManager.ApplyDialogueConfig(globalConfig);
                }
            }
            
            Debug.Log($"[GameLauncher] Chargement dialogue: {dialogueContent.title}");
            // TODO: Adapter SubtitleManager pour accepter DialogueContent directement
            // Pour l'instant, on continue d'utiliser LoadDialogueFromUrl avec le JSON stocké
            string dialogueJson = PlayerPrefs.GetString("DialogueIntroJson");
            if (!string.IsNullOrEmpty(dialogueJson))
            {
                subtitleManager.LoadDialogueFromJson(dialogueJson);
            }
        }
        else
        {
            Debug.LogError("[GameLauncher] SubtitleManager introuvable dans la scène Player");
            onComplete?.Invoke();
        }
    }
    
    private void ConfigureSubtitleManager(string dialogueUrl, System.Action onComplete)
    {
        SubtitleManager subtitleManager = FindFirstObjectByType<SubtitleManager>();
        if (subtitleManager != null)
        {
            subtitleManager.OnDialogueComplete = onComplete;
            
            // Appliquer la config de dialogue globale si disponible
            if (LevelManager.Instance != null)
            {
                DialogueConfig globalConfig = LevelManager.Instance.GetDialogueConfig();
                if (globalConfig != null)
                {
                    Debug.Log("[GameLauncher] Application de la config dialogue globale");
                    subtitleManager.ApplyDialogueConfig(globalConfig);
                }
            }
            
            Debug.Log($"[GameLauncher] Chargement dialogue depuis: {dialogueUrl}");
            subtitleManager.LoadDialogueFromUrl(dialogueUrl);
        }
        else
        {
            Debug.LogError("[GameLauncher] SubtitleManager introuvable dans la scène Player");
            onComplete?.Invoke();
        }
    }
}