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

/// <summary>
/// Manager pour charger et gérer les paramètres généraux du projet
/// </summary>
public class GeneralConfigManager : MonoBehaviour
{
    public static GeneralConfigManager Instance { get; private set; }
    
    [Header("Configuration")]
    public string configFileName = "general-config.json";
    
    [Header("Debug")]
    public bool showDebugLogs = true;
    
    private GeneralConfig generalConfig;
    private bool isConfigLoaded = false;
    
    void Awake()
    {
        // Singleton pattern
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
            return;
        }
    }
    
    void Start()
    {
        StartCoroutine(LoadGeneralConfig());
    }
    
    /// <summary>
    /// Charge la configuration générale depuis le fichier JSON
    /// </summary>
    private IEnumerator LoadGeneralConfig()
    {
        string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, configFileName);
        
        if (showDebugLogs)
        {
            Debug.Log($"[GeneralConfigManager] Chargement de la configuration depuis: {filePath}");
            Debug.Log($"[GeneralConfigManager] Platform: {Application.platform}");
        }
        
        // DÉTECTION MAC AU RUNTIME (plus fiable que les defines de compilation)
        bool isMacOrIOS = Application.platform == RuntimePlatform.OSXEditor || 
                         Application.platform == RuntimePlatform.OSXPlayer ||
                         Application.platform == RuntimePlatform.IPhonePlayer;
        
        // FIX MAC : Utiliser File.ReadAllText sur Mac/iOS au lieu de UnityWebRequest
        // IMPORTANT : Aussi dans l'éditeur Mac car UnityWebRequest échoue avec file:///
        if (isMacOrIOS)
        {
            Debug.Log("[GeneralConfigManager] 🍎 Détection Mac/iOS - Utilisation de File.ReadAllText");
            
            if (System.IO.File.Exists(filePath))
            {
                try
                {
                    string jsonContent = System.IO.File.ReadAllText(filePath);
                    
                    if (showDebugLogs)
                    {
                        Debug.Log($"[GeneralConfigManager] Fichier lu: {jsonContent.Length} caractères");
                    }
                    
                    generalConfig = JsonUtility.FromJson<GeneralConfig>(jsonContent);
                    isConfigLoaded = true;
                    
                    if (showDebugLogs)
                    {
                        Debug.Log($"[GeneralConfigManager] ✅ Configuration chargée avec succès (Mac/iOS)!");
                        Debug.Log($"[GeneralConfigManager] Projet: {generalConfig.projectName} v{generalConfig.version}");
                        Debug.Log($"[GeneralConfigManager] Map par défaut: {generalConfig.defaultMapId}");
                        
                        // Vérifier que crosshairPath existe
                        if (generalConfig.assetsPaths != null)
                        {
                            if (!string.IsNullOrEmpty(generalConfig.assetsPaths.crosshairPath))
                            {
                                Debug.Log($"[GeneralConfigManager] ✅ crosshairPath: {generalConfig.assetsPaths.crosshairPath}");
                            }
                            else
                            {
                                Debug.LogWarning("[GeneralConfigManager] ⚠️ crosshairPath vide ou non défini");
                            }
                        }
                    }
                    
                    yield break; // Important : sortir de la coroutine
                }
                catch (System.Exception e)
                {
                    Debug.LogError($"[GeneralConfigManager] ❌ Erreur lors du parsing JSON (Mac/iOS): {e.Message}");
                    Debug.LogError($"[GeneralConfigManager] Stack trace: {e.StackTrace}");
                    LoadDefaultConfig();
                    yield break;
                }
            }
            else
            {
                Debug.LogError($"[GeneralConfigManager] ❌ Fichier introuvable sur Mac/iOS: {filePath}");
                Debug.LogError($"[GeneralConfigManager] Assurez-vous que {configFileName} est dans le dossier StreamingAssets");
                Debug.LogError($"[GeneralConfigManager] Chemin complet: {Application.streamingAssetsPath}");
                LoadDefaultConfig();
                yield break;
            }
        }
        
        // Code normal pour Windows/Android/autres plateformes (ou éditeur Mac)
        if (showDebugLogs)
        {
            Debug.Log("[GeneralConfigManager] Utilisation de UnityWebRequest");
        }
        
        UnityWebRequest request = UnityWebRequest.Get(filePath);
        request.timeout = 10; // Timeout de 10 secondes
        yield return request.SendWebRequest();
        
        if (request.result == UnityWebRequest.Result.Success)
        {
            try
            {
                generalConfig = JsonUtility.FromJson<GeneralConfig>(request.downloadHandler.text);
                isConfigLoaded = true;
                
                if (showDebugLogs)
                {
                    Debug.Log($"[GeneralConfigManager] Configuration chargée avec succès!");
                    Debug.Log($"[GeneralConfigManager] Projet: {generalConfig.projectName} v{generalConfig.version}");
                    Debug.Log($"[GeneralConfigManager] Map par défaut: {generalConfig.defaultMapId}");
                }
            }
            catch (System.Exception e)
            {
                Debug.LogError($"[GeneralConfigManager] Erreur lors du parsing JSON: {e.Message}");
                LoadDefaultConfig();
            }
        }
        else
        {
            Debug.LogError($"[GeneralConfigManager] Erreur lors du chargement: {request.error}");
            LoadDefaultConfig();
        }
        
        request.Dispose();
    }
    
    /// <summary>
    /// Charge une configuration par défaut en cas d'erreur
    /// </summary>
    private void LoadDefaultConfig()
    {
        generalConfig = new GeneralConfig
        {
            projectName = "Jeu de Tir QCM",
            version = "1.0.0",
            defaultMapId = "map_Q0J1",
            mapsRegistryUrl = "https://unjoursansassurance.studioplc.tech/demo_assets/json/maps-registry.json",
            assetsPaths = new AssetsPathsConfig
            {
                popupVideoPath = "https://unjoursansassurance.studioplc.tech/demo_assets/videos/",
                decoratorImagePath = "https://unjoursansassurance.studioplc.tech/demo_assets/images/",
                videoPath = "https://unjoursansassurance.studioplc.tech/demo_assets/videos/",
                backgroundImagePath = "https://unjoursansassurance.studioplc.tech/demo_assets/images/",
                backgroundVideoPath = "https://unjoursansassurance.studioplc.tech/demo_assets/videos/",
                uiPath = "https://unjoursansassurance.studioplc.tech/demo_assets/UI/",
                crosshairPath = "https://unjoursansassurance.studioplc.tech/demo_assets/images/crosshair/", // IMPORTANT pour le fix Mac
                gameAssetsPath = "https://unjoursansassurance.studioplc.tech/demo_assets/images/", // Pour gun, LEDs, etc.
                dialoguePath = "https://unjoursansassurance.studioplc.tech/demo_assets/dialogues/",
                questionsPath = "https://unjoursansassurance.studioplc.tech/demo_assets/questions/",
                mapsPath = "https://unjoursansassurance.studioplc.tech/demo_assets/json/maps/"
            },
            debug = new GeneralDebugConfig
            {
                showDebugZones = true,
                enableDebugLogs = true
            },
            ui = new GeneralUIConfig
            {
                loadingDelay = 0.5f,
                crosshairSortingOrder = 60000,
                gunSortingOrder = 60000
            },
            gameplay = new GeneralGameplayConfig
            {
                enableDirectClick = true,
                enableCrosshair = true
            },
            futureSettings = new GeneralFutureSettingsConfig
            {
                comment = "Configuration par défaut"
            }
        };
        
        isConfigLoaded = true;
        Debug.LogWarning("[GeneralConfigManager] Configuration par défaut chargée");
    }
    
    /// <summary>
    /// Obtient la configuration générale (attendre que soit chargée)
    /// </summary>
    public GeneralConfig GetConfig()
    {
        if (!isConfigLoaded)
        {
            Debug.LogWarning("[GeneralConfigManager] Configuration pas encore chargée, retour de la config par défaut");
            LoadDefaultConfig();
        }
        return generalConfig;
    }
    
    /// <summary>
    /// Obtient la map par défaut
    /// </summary>
    public string GetDefaultMapId()
    {
        return GetConfig().defaultMapId;
    }
    
    /// <summary>
    /// Obtient l'URL du registre des maps
    /// </summary>
    public string GetMapsRegistryUrl()
    {
        return ResolveStreamingAssetsPath(GetConfig().mapsRegistryUrl);
    }
    
    /// <summary>
    /// Convertit un chemin STREAMING_ASSETS/ en URL file:/// complète
    /// </summary>
    private string ResolveStreamingAssetsPath(string path)
    {
        if (string.IsNullOrEmpty(path))
            return path;
            
        if (path.StartsWith("STREAMING_ASSETS/"))
        {
            string relativePath = path.Substring("STREAMING_ASSETS/".Length);
            string fullPath = System.IO.Path.Combine(Application.streamingAssetsPath, relativePath);

            // WebGL: Application.streamingAssetsPath est déjà une URL accessible par le serveur (pas de file:///)
            // Éditeur/Standalone: on peut utiliser file:///
            fullPath = fullPath.Replace("\\", "/");

            #if UNITY_WEBGL && !UNITY_EDITOR
            return fullPath; // ex: /StreamingAssets/json/… servi par le serveur WebGL
            #else
            return "file:///" + fullPath;
            #endif
        }
        
        return path;
    }
    
    /// <summary>
    /// Vérifie si la configuration est chargée
    /// </summary>
    public bool IsConfigLoaded()
    {
        return isConfigLoaded;
    }
    
    /// <summary>
    /// Force le rechargement de la configuration
    /// </summary>
    public void ReloadConfig()
    {
        isConfigLoaded = false;
        StartCoroutine(LoadGeneralConfig());
    }
    
    // ==========================================
    // MÉTHODES UTILITAIRES POUR LES CHEMINS D'ASSETS
    // ==========================================
    
    /// <summary>
    /// Construit l'URL complète pour une vidéo de popup
    /// </summary>
    /// <param name="fileName">Nom du fichier (peut inclure un sous-dossier comme "focus/video.mp4")</param>
    /// <returns>URL complète</returns>
    public string GetPopupVideoUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.popupVideoPath))
        {
            Debug.LogWarning("[GeneralConfigManager] popupVideoPath non défini dans la config");
            return fileName;
        }
        
        return config.assetsPaths.popupVideoPath + fileName;
    }
    
    /// <summary>
    /// Construit l'URL complète pour une image décorative
    /// </summary>
    /// <param name="fileName">Nom du fichier (peut inclure un sous-dossier comme "personnages/image.png")</param>
    /// <returns>URL complète</returns>
    public string GetDecoratorImageUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.decoratorImagePath))
        {
            Debug.LogWarning("[GeneralConfigManager] decoratorImagePath non défini dans la config");
            return fileName;
        }
        
        return config.assetsPaths.decoratorImagePath + fileName;
    }
    
    /// <summary>
    /// Construit l'URL complète pour une vidéo générale
    /// </summary>
    /// <param name="fileName">Nom du fichier (peut inclure un sous-dossier comme "focus/video.mp4")</param>
    /// <returns>URL complète</returns>
    public string GetVideoUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.videoPath))
        {
            Debug.LogWarning("[GeneralConfigManager] videoPath non défini dans la config");
            return fileName;
        }
        
        return config.assetsPaths.videoPath + fileName;
    }
    
    /// <summary>
    /// Construit l'URL complète pour une image de fond
    /// </summary>
    /// <param name="fileName">Nom du fichier</param>
    /// <returns>URL complète</returns>
    public string GetBackgroundImageUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.backgroundImagePath))
        {
            Debug.LogWarning("[GeneralConfigManager] backgroundImagePath non défini dans la config");
            return fileName;
        }
        
        return config.assetsPaths.backgroundImagePath + fileName;
    }
    
    /// <summary>
    /// Construit l'URL complète pour une vidéo de fond
    /// </summary>
    /// <param name="fileName">Nom du fichier</param>
    /// <returns>URL complète</returns>
    public string GetBackgroundVideoUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.backgroundVideoPath))
        {
            Debug.LogWarning("[GeneralConfigManager] backgroundVideoPath non défini dans la config");
            return fileName;
        }
        
        return config.assetsPaths.backgroundVideoPath + fileName;
    }
    
    /// <summary>
    /// Construit l'URL complète pour un fichier UI
    /// </summary>
    /// <param name="fileName">Nom du fichier</param>
    /// <returns>URL complète</returns>
    public string GetUIUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.uiPath))
        {
            Debug.LogWarning("[GeneralConfigManager] uiPath non défini dans la config");
            return fileName;
        }
        
        return config.assetsPaths.uiPath + fileName;
    }
    
    /// <summary>
    /// Construit l'URL complète pour un crosshair (curseur de visée)
    /// </summary>
    /// <param name="fileName">Nom du fichier</param>
    /// <returns>URL complète</returns>
    public string GetCrosshairUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.crosshairPath))
        {
            // Fallback vers gameAssetsPath si crosshairPath n'est pas défini
            Debug.LogWarning("[GeneralConfigManager] crosshairPath non défini, utilisation de gameAssetsPath");
            return GetGameAssetsUrl(fileName);
        }
        
        return config.assetsPaths.crosshairPath + fileName;
    }
    
    /// <summary>
    /// Construit l'URL complète pour un asset de jeu (gun, crosshair, impact, etc.)
    /// </summary>
    /// <param name="fileName">Nom du fichier</param>
    /// <returns>URL complète</returns>
    public string GetGameAssetsUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.gameAssetsPath))
        {
            // Fallback vers uiPath si gameAssetsPath n'est pas défini
            Debug.LogWarning("[GeneralConfigManager] gameAssetsPath non défini, utilisation de uiPath");
            return GetUIUrl(fileName);
        }
        
        string fullUrl = config.assetsPaths.gameAssetsPath + fileName;
        return ResolveStreamingAssetsPath(fullUrl);
    }
    
    /// <summary>
    /// Construit l'URL complète pour un fichier de dialogue
    /// </summary>
    /// <param name="fileName">Nom du fichier</param>
    /// <returns>URL complète</returns>
    public string GetDialogueUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.dialoguePath))
        {
            Debug.LogWarning("[GeneralConfigManager] dialoguePath non défini dans la config");
            return fileName;
        }
        
        string fullUrl = config.assetsPaths.dialoguePath + fileName;
        return ResolveStreamingAssetsPath(fullUrl);
    }
    
    /// <summary>
    /// Construit l'URL complète pour un fichier de questions
    /// </summary>
    /// <param name="fileName">Nom du fichier</param>
    /// <returns>URL complète</returns>
    public string GetQuestionsUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.questionsPath))
        {
            Debug.LogWarning("[GeneralConfigManager] questionsPath non défini dans la config");
            return fileName;
        }
        
        string fullUrl = config.assetsPaths.questionsPath + fileName;
        return ResolveStreamingAssetsPath(fullUrl);
    }
    
    /// <summary>
    /// Construit l'URL complète pour un fichier de configuration de map
    /// </summary>
    /// <param name="fileName">Nom du fichier</param>
    /// <returns>URL complète</returns>
    public string GetMapConfigUrl(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
            
        var config = GetConfig();
        if (config.assetsPaths == null || string.IsNullOrEmpty(config.assetsPaths.mapsPath))
        {
            Debug.LogWarning("[GeneralConfigManager] mapsPath non défini dans la config");
            return fileName;
        }
        
        string fullUrl = config.assetsPaths.mapsPath + fileName;
        return ResolveStreamingAssetsPath(fullUrl);
    }
    
    /// <summary>
    /// Méthode générique pour construire une URL d'asset
    /// </summary>
    /// <param name="assetType">Type d'asset (popupVideo, decoratorImage, video, backgroundImage, backgroundVideo, ui, dialogue, questions, maps)</param>
    /// <param name="fileName">Nom du fichier</param>
    /// <returns>URL complète</returns>
    public string GetAssetUrl(string assetType, string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            return "";
            
        // Si le fichier contient déjà une URL complète, le retourner tel quel
        if (fileName.StartsWith("http://") || fileName.StartsWith("https://"))
            return fileName;
        
        switch (assetType.ToLower())
        {
            case "popupvideo":
                return GetPopupVideoUrl(fileName);
            case "decoratorimage":
                return GetDecoratorImageUrl(fileName);
            case "video":
                return GetVideoUrl(fileName);
            case "backgroundimage":
                return GetBackgroundImageUrl(fileName);
            case "backgroundvideo":
                return GetBackgroundVideoUrl(fileName);
            case "ui":
                return GetUIUrl(fileName);
            case "dialogue":
                return GetDialogueUrl(fileName);
            case "questions":
                return GetQuestionsUrl(fileName);
            case "maps":
                return GetMapConfigUrl(fileName);
            default:
                Debug.LogWarning($"[GeneralConfigManager] Type d'asset inconnu: {assetType}");
                return fileName;
        }
    }
    
    // ==========================================
    // GETTERS POUR LES VALEURS PAR DÉFAUT
    // ==========================================
    
    /// <summary>
    /// Obtient les assets par défaut
    /// </summary>
    public DefaultAssets GetDefaultAssets()
    {
        var config = GetConfig();
        return config.defaultAssets;
    }
    
    /// <summary>
    /// Obtient la palette de couleurs
    /// </summary>
    public ColorPalette GetColorPalette()
    {
        var config = GetConfig();
        return config.colorPalette;
    }
    
    /// <summary>
    /// Obtient la configuration popup par défaut
    /// </summary>
    public DefaultPopupConfig GetDefaultPopupConfig()
    {
        var config = GetConfig();
        return config.defaultPopupConfig;
    }
    
    /// <summary>
    /// Obtient la configuration header par défaut
    /// </summary>
    public DefaultHeaderConfig GetDefaultHeaderConfig()
    {
        var config = GetConfig();
        return config.defaultHeaderConfig;
    }
    
    /// <summary>
    /// Obtient les messages de feedback par défaut
    /// </summary>
    public DefaultFeedbackMessages GetDefaultFeedbackMessages()
    {
        var config = GetConfig();
        return config.defaultFeedbackMessages;
    }
    
    /// <summary>
    /// Obtient la configuration UI par défaut
    /// </summary>
    public DefaultUIConfig GetDefaultUIConfig()
    {
        var config = GetConfig();
        return config.defaultUIConfig;
    }
    
    /// <summary>
    /// Obtient la résolution par défaut
    /// </summary>
    public DefaultResolution GetDefaultResolution()
    {
        var config = GetConfig();
        return config.defaultResolution;
    }
    
    /// <summary>
    /// Obtient la configuration crosshair par défaut
    /// </summary>
    public DefaultCrosshairConfig GetDefaultCrosshairConfig()
    {
        var config = GetConfig();
        return config.defaultCrosshairConfig;
    }
    
    /// <summary>
    /// Obtient la configuration gun par défaut
    /// </summary>
    public DefaultGunConfig GetDefaultGunConfig()
    {
        var config = GetConfig();
        return config.defaultGunConfig;
    }
    
    /// <summary>
    /// Obtient la configuration zone decorator par défaut
    /// </summary>
    public DefaultZoneDecorator GetDefaultZoneDecorator()
    {
        var config = GetConfig();
        return config.defaultZoneDecorator;
    }
    
    /// <summary>
    /// Obtient les timings d'animations
    /// </summary>
    public AnimationTimings GetAnimationTimings()
    {
        var config = GetConfig();
        return config.animations;
    }
}
