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

public class SceneTransitionManager : MonoBehaviour
{
    private static SceneTransitionManager instance;
    private static GameObject transitionOverlay;
    private static bool isTransitionInProgress = false;
    private static string currentTargetScene = null;
    private Coroutine activeTransitionCoroutine;

    public static bool IsTransitionInProgress => isTransitionInProgress;
    
    /// <summary>
    /// Vérifie si l'overlay de transition est actuellement visible
    /// </summary>
    public static bool IsOverlayVisible => transitionOverlay != null;
    
    void Awake()
    {
        // Singleton pattern
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
    
    public static void LoadSceneWithTransition(string sceneName)
    {
        // Anti double-clic / anti courses : une seule transition à la fois
        if (isTransitionInProgress)
        {
            Debug.LogWarning($"[SceneTransitionManager] ⚠️ Transition déjà en cours vers '{currentTargetScene}', demande ignorée vers '{sceneName}'");
            return;
        }

        // Si l'instance n'existe pas, essayer de la trouver ou la créer
        if (instance == null)
        {
            Debug.LogWarning("[SceneTransitionManager] Instance introuvable, recherche dans la scène...");
            instance = FindFirstObjectByType<SceneTransitionManager>();
            
            if (instance == null)
            {
                Debug.LogWarning("[SceneTransitionManager] Instance toujours introuvable, création d'une nouvelle instance...");
                GameObject managerObj = new GameObject("SceneTransitionManager");
                instance = managerObj.AddComponent<SceneTransitionManager>();
                DontDestroyOnLoad(managerObj);
            }
        }
        
        if (instance != null)
        {
            instance.activeTransitionCoroutine = instance.StartCoroutine(instance.TransitionToScene(sceneName));
        }
        else
        {
            // Fallback ultime : charger directement la scène sans transition
            Debug.LogError("[SceneTransitionManager] Impossible de créer une instance, chargement direct de la scène");
            SceneManager.LoadScene(sceneName);
        }
    }
    
    IEnumerator TransitionToScene(string sceneName)
    {
        isTransitionInProgress = true;
        currentTargetScene = sceneName;

        // Vérifier que la scène existe
        if (!SceneExists(sceneName))
        {
            Debug.LogError($"[SceneTransitionManager] La scène '{sceneName}' n'existe pas !");
            CleanupOverlayImmediate();
            isTransitionInProgress = false;
            currentTargetScene = null;
            yield break;
        }
        
        // Créer écran noir IMMÉDIATEMENT
        CreatePersistentOverlay();
        
        // Charger la scène de façon asynchrone
        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
        
        if (asyncLoad == null)
        {
            Debug.LogError($"[SceneTransitionManager] Échec du chargement asynchrone de {sceneName}, tentative de chargement direct...");
            SceneManager.LoadScene(sceneName);
            CleanupOverlayImmediate();
            isTransitionInProgress = false;
            currentTargetScene = null;
            yield break;
        }
        
        // Attendre que la scène soit complètement chargée
        float timeout = 10f; // Timeout de 10 secondes
        float elapsed = 0f;
        
        while (!asyncLoad.isDone)
        {
            elapsed += Time.deltaTime;
            if (elapsed > timeout)
            {
                Debug.LogError($"[SceneTransitionManager] Timeout lors du chargement de {sceneName}, chargement direct...");
                SceneManager.LoadScene(sceneName);
                CleanupOverlayImmediate();
                isTransitionInProgress = false;
                currentTargetScene = null;
                yield break;
            }
            yield return null;
        }
        
        // Vérifier que la scène a bien été chargée
        yield return new WaitForSeconds(0.1f);
        if (SceneManager.GetActiveScene().name != sceneName)
        {
            Debug.LogWarning($"[SceneTransitionManager] La scène chargée ne correspond pas ({SceneManager.GetActiveScene().name} au lieu de {sceneName}), nouvelle tentative...");
            SceneManager.LoadScene(sceneName);
            CleanupOverlayImmediate();
            isTransitionInProgress = false;
            currentTargetScene = null;
            yield break;
        }
        
        // Attendre encore un peu pour que tout soit initialisé
        yield return new WaitForSeconds(0.5f);
        
        // Faire disparaître l'overlay
        if (transitionOverlay != null)
        {
            StartCoroutine(FadeOutOverlay());
        }

        // Déverrouiller (même si overlay est null)
        isTransitionInProgress = false;
        currentTargetScene = null;
        activeTransitionCoroutine = null;
    }
    
    private bool SceneExists(string sceneName)
    {
        for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
        {
            string scenePath = UnityEngine.SceneManagement.SceneUtility.GetScenePathByBuildIndex(i);
            string sceneNameInBuild = System.IO.Path.GetFileNameWithoutExtension(scenePath);
            if (sceneNameInBuild == sceneName)
            {
                return true;
            }
        }
        return false;
    }
    
    void CreatePersistentOverlay()
    {
        if (transitionOverlay != null)
        {
            Destroy(transitionOverlay);
        }
        
        // Créer un overlay qui survit au changement de scène
        // Utiliser un Canvas ScreenSpaceOverlay pour être indépendant de la caméra
        transitionOverlay = new GameObject("SceneTransitionOverlay");
        DontDestroyOnLoad(transitionOverlay);
        
        // Canvas en mode Overlay (indépendant de la caméra)
        Canvas canvas = transitionOverlay.AddComponent<Canvas>();
        canvas.renderMode = RenderMode.ScreenSpaceOverlay;
        canvas.sortingOrder = 32767; // Valeur maximale pour être au-dessus de tout
        
        // Ajouter un CanvasGroup pour le fade
        CanvasGroup canvasGroup = transitionOverlay.AddComponent<CanvasGroup>();
        canvasGroup.alpha = 1f;
        canvasGroup.blocksRaycasts = true;
        
        // Créer le panneau noir
        GameObject blackPanel = new GameObject("BlackPanel");
        blackPanel.transform.SetParent(transitionOverlay.transform, false);
        
        RectTransform rectTransform = blackPanel.AddComponent<RectTransform>();
        rectTransform.anchorMin = Vector2.zero;
        rectTransform.anchorMax = Vector2.one;
        rectTransform.sizeDelta = Vector2.zero;
        rectTransform.anchoredPosition = Vector2.zero;
        
        Image blackImage = blackPanel.AddComponent<Image>();
        blackImage.color = Color.black;
        blackImage.raycastTarget = true;
        
        Debug.Log("[SceneTransitionManager] ✅ Overlay Canvas créé (ScreenSpaceOverlay, sortingOrder: 32767)");
    }

    private void CleanupOverlayImmediate()
    {
        if (transitionOverlay == null) return;

        Debug.Log("[SceneTransitionManager] 🗑️ Nettoyage immédiat de l'overlay");
        Destroy(transitionOverlay);
        transitionOverlay = null;
    }
    
    IEnumerator FadeOutOverlay()
    {
        if (transitionOverlay == null) yield break;
        
        CanvasGroup canvasGroup = transitionOverlay.GetComponent<CanvasGroup>();
        if (canvasGroup == null)
        {
            // Fallback si pas de CanvasGroup
            Destroy(transitionOverlay);
            transitionOverlay = null;
            yield break;
        }
        
        Debug.Log("[SceneTransitionManager] 🎬 Début du fade out de l'overlay");
        
        float fadeTime = 0.3f; // Fade out rapide
        float elapsedTime = 0f;
        
        while (elapsedTime < fadeTime)
        {
            elapsedTime += Time.deltaTime;
            float alpha = 1f - (elapsedTime / fadeTime);
            canvasGroup.alpha = alpha;
            yield return null;
        }

        canvasGroup.alpha = 0f;
        Destroy(transitionOverlay);
        transitionOverlay = null;
        
        Debug.Log("[SceneTransitionManager] ✅ Overlay détruit après fade out");
    }
    
    /// <summary>
    /// Masque l'overlay de transition (appelé par les scènes quand elles sont prêtes)
    /// </summary>
    public static void HideTransitionOverlay()
    {
        if (instance != null && transitionOverlay != null)
        {
            instance.StartCoroutine(instance.FadeOutOverlay());
        }
    }
    
    /// <summary>
    /// Masque l'overlay immédiatement sans fade
    /// </summary>
    public static void HideTransitionOverlayImmediate()
    {
        if (instance != null)
        {
            instance.CleanupOverlayImmediate();
        }
        else if (transitionOverlay != null)
        {
            Destroy(transitionOverlay);
            transitionOverlay = null;
        }
    }
}