using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;

/// <summary>
/// Gestionnaire unifié pour les transitions de scènes avec écran de chargement
/// Peut utiliser soit l'écran de chargement intégré, soit une scène dédiée
/// </summary>
public class UnifiedLoadingManager : MonoBehaviour
{
    [Header("Configuration")]
    [SerializeField] private bool useDedicatedLoadingScene = false;
    [SerializeField] private string loadingSceneName = "LoadingScene";
    [SerializeField] private float minimumLoadingTime = 1.0f;
    
    [Header("Messages par contexte")]
    [SerializeField] private string gameLoadingMessage = "Chargement du jeu...";
    [SerializeField] private string mapLoadingMessage = "Chargement de la carte...";
    [SerializeField] private string videoLoadingMessage = "Chargement de la vidéo...";
    [SerializeField] private string menuLoadingMessage = "Retour au menu...";
    
    private static UnifiedLoadingManager instance;
    private LoadingScreenManager loadingScreenManager;
    
    public static UnifiedLoadingManager Instance => instance;
    
    void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
            
            // Trouver le LoadingScreenManager
            loadingScreenManager = FindFirstObjectByType<LoadingScreenManager>();
            if (loadingScreenManager == null)
            {
                Debug.LogWarning("LoadingScreenManager non trouvé - certaines fonctionnalités peuvent être limitées");
            }
        }
        else
        {
            Destroy(gameObject);
        }
    }
    
    /// <summary>
    /// Charge une scène avec l'écran de chargement approprié
    /// </summary>
    public static void LoadScene(string sceneName, LoadingContext context = LoadingContext.General, bool useDedicatedScene = false)
    {
        if (instance != null)
        {
            instance.StartCoroutine(instance.LoadSceneCoroutine(sceneName, context, useDedicatedScene));
        }
        else
        {
            Debug.LogError("UnifiedLoadingManager instance non trouvée !");
            SceneManager.LoadScene(sceneName);
        }
    }
    
    /// <summary>
    /// Charge une scène avec un message de chargement personnalisé
    /// </summary>
    public static void LoadScene(string sceneName, string loadingMessage, bool useDedicatedScene = false)
    {
        if (instance != null)
        {
            instance.StartCoroutine(instance.LoadSceneWithMessageCoroutine(sceneName, loadingMessage, useDedicatedScene));
        }
        else
        {
            Debug.LogError("UnifiedLoadingManager instance non trouvée !");
            SceneManager.LoadScene(sceneName);
        }
    }
    
    /// <summary>
    /// Affiche l'écran de chargement pour une opération en cours
    /// </summary>
    public static void ShowLoading(string message = null, LoadingContext context = LoadingContext.General)
    {
        if (instance != null && instance.loadingScreenManager != null)
        {
            if (string.IsNullOrEmpty(message))
            {
                message = instance.GetContextMessage(context);
            }
            
            instance.loadingScreenManager.ShowLoading(message);
        }
    }
    
    /// <summary>
    /// Cache l'écran de chargement
    /// </summary>
    public static void HideLoading()
    {
        if (instance != null && instance.loadingScreenManager != null)
        {
            instance.loadingScreenManager.HideLoading();
        }
    }
    
    /// <summary>
    /// Cache l'écran de chargement après un délai
    /// </summary>
    public static void HideLoadingAfterDelay(float delay)
    {
        if (instance != null && instance.loadingScreenManager != null)
        {
            instance.loadingScreenManager.HideLoadingAfterDelay(delay);
        }
    }
    
    IEnumerator LoadSceneCoroutine(string sceneName, LoadingContext context, bool useDedicatedScene)
    {
        string loadingMessage = GetContextMessage(context);
        
        if (useDedicatedScene || useDedicatedLoadingScene)
        {
            // Utiliser la scène de chargement dédiée
            PlayerPrefs.SetString("LoadingTargetScene", sceneName);
            PlayerPrefs.SetString("LoadingMessage", loadingMessage);
            PlayerPrefs.SetFloat("MinimumLoadingTime", minimumLoadingTime);
            SceneManager.LoadScene(loadingSceneName);
        }
        else
        {
            // Utiliser l'écran de chargement intégré
            if (loadingScreenManager != null)
            {
                loadingScreenManager.ShowLoading(loadingMessage, true);
            }
            
            // Charger la scène de façon asynchrone
            AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
            
            // Attendre que la scène soit chargée
            while (!asyncLoad.isDone)
            {
                yield return null;
            }
            
            // Attendre un peu pour que tout soit initialisé
            yield return new WaitForSeconds(0.5f);
            
            // Masquer l'écran de chargement
            if (loadingScreenManager != null)
            {
                loadingScreenManager.HideLoading();
            }
        }
    }
    
    IEnumerator LoadSceneWithMessageCoroutine(string sceneName, string loadingMessage, bool useDedicatedScene)
    {
        if (useDedicatedScene || useDedicatedLoadingScene)
        {
            // Utiliser la scène de chargement dédiée
            PlayerPrefs.SetString("LoadingTargetScene", sceneName);
            PlayerPrefs.SetString("LoadingMessage", loadingMessage);
            PlayerPrefs.SetFloat("MinimumLoadingTime", minimumLoadingTime);
            SceneManager.LoadScene(loadingSceneName);
        }
        else
        {
            // Utiliser l'écran de chargement intégré
            if (loadingScreenManager != null)
            {
                loadingScreenManager.ShowLoading(loadingMessage, true);
            }
            
            // Charger la scène de façon asynchrone
            AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
            
            // Attendre que la scène soit chargée
            while (!asyncLoad.isDone)
            {
                yield return null;
            }
            
            // Attendre un peu pour que tout soit initialisé
            yield return new WaitForSeconds(0.5f);
            
            // Masquer l'écran de chargement
            if (loadingScreenManager != null)
            {
                loadingScreenManager.HideLoading();
            }
        }
    }
    
    string GetContextMessage(LoadingContext context)
    {
        switch (context)
        {
            case LoadingContext.Game:
                return gameLoadingMessage;
            case LoadingContext.Map:
                return mapLoadingMessage;
            case LoadingContext.Video:
                return videoLoadingMessage;
            case LoadingContext.Menu:
                return menuLoadingMessage;
            default:
                return "Chargement en cours...";
        }
    }
    
    /// <summary>
    /// Méthodes de convenance pour les cas d'usage courants
    /// </summary>
    public static void LoadGameScene(string sceneName) => LoadScene(sceneName, LoadingContext.Game);
    public static void LoadMapScene(string sceneName) => LoadScene(sceneName, LoadingContext.Map);
    public static void LoadVideoScene(string sceneName) => LoadScene(sceneName, LoadingContext.Video);
    public static void LoadMenuScene(string sceneName) => LoadScene(sceneName, LoadingContext.Menu);
    
    /// <summary>
    /// Force l'utilisation de la scène de chargement dédiée pour la prochaine transition
    /// </summary>
    public static void UseDedicatedLoadingScene(bool use = true)
    {
        if (instance != null)
        {
            instance.useDedicatedLoadingScene = use;
        }
    }
}

/// <summary>
/// Contexte de chargement pour personnaliser les messages
/// </summary>
public enum LoadingContext
{
    General,
    Game,
    Map,
    Video,
    Menu
}
