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

public class ParametresTab : SettingsTab
{
    public Toggle soundToggle;
    public TextMeshProUGUI soundLabel;
    public Button quitButton;
    public Button logoutButton;

    // Infos utilisateur (déplacées depuis l'onglet DEBUG)
    [HideInInspector] public GameObject userInfoSection;
    [HideInInspector] public TextMeshProUGUI emailInfoText;
    [HideInInspector] public TextMeshProUGUI playTimeInfoText;
    private Coroutine playTimeRefreshCoroutine;
    
    [HideInInspector] public GameObject buttonToRefresh1;
    [HideInInspector] public GameObject buttonToRefresh2;
    
    private List<Texture2D> dynamicTextures = new List<Texture2D>(); // Garder trace des textures créées
    
    protected override void Awake()
    {
        base.Awake();
        tabName = "PARAMETRES";
        tabOrder = 3;
        
        Debug.Log("[ParametresTab] Awake: Configuration des parametres...");
        
        if (soundToggle != null)
        {
            bool soundEnabled = PlayerPrefs.GetInt("SoundEnabled", 1) == 1;
            soundToggle.isOn = soundEnabled;
            soundToggle.onValueChanged.AddListener(OnSoundToggleChanged);
            UpdateSoundLabel(soundEnabled);
        }
    }
    
    void Start()
    {
        // Configurer les boutons dans Start() pour être sûr que tout est initialisé
        Debug.Log($"[ParametresTab] Start: Configuration des boutons - quitButton={quitButton != null}, logoutButton={logoutButton != null}");
        
        if (quitButton != null)
        {
            quitButton.onClick.RemoveAllListeners();
            quitButton.onClick.AddListener(OnQuitClicked);
            quitButton.interactable = true;
            Debug.Log("[ParametresTab] Bouton Quit configuré");
        }
        else
        {
            Debug.LogWarning("[ParametresTab] quitButton est null !");
        }
        
        if (logoutButton != null)
        {
            logoutButton.onClick.RemoveAllListeners();
            logoutButton.onClick.AddListener(OnLogoutClicked);
            logoutButton.interactable = true;
            
            // S'assurer que l'Image du bouton peut recevoir les clics
            Image buttonImage = logoutButton.GetComponent<Image>();
            if (buttonImage != null)
            {
                buttonImage.raycastTarget = true;
            }
            
            Debug.Log("[ParametresTab] Bouton Logout configuré et interactable");
        }
        else
        {
            Debug.LogWarning("[ParametresTab] logoutButton est null !");
        }
        
        // Plus besoin de rafraîchir les sprites - ils sont créés directement avec la bonne taille
    }
    
    // Méthode RefreshButtonSprites supprimée - plus nécessaire car les sprites sont créés directement avec la bonne taille
    
    Sprite CreateGradientSpriteWithBorder(int width, int height, float radius, Color startColor, Color endColor, Color borderColor, float borderWidth)
    {
        Texture2D texture = new Texture2D(width, height);
        Color[] pixels = new Color[width * height];

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                float alpha = 1f;
                bool isBorder = false;
                
                // Vérifier si on est dans la bordure
                if (x < borderWidth || x >= width - borderWidth || y < borderWidth || y >= height - borderWidth)
                {
                    isBorder = true;
                }

                // Coins arrondis
                float distanceFromCorner = float.MaxValue;
                
                // Coin supérieur gauche
                if (x < radius && y > height - radius)
                {
                    float dx = radius - x;
                    float dy = (height - radius) - y;
                    distanceFromCorner = Mathf.Sqrt(dx * dx + dy * dy);
                    if (distanceFromCorner > radius) alpha = 0f;
                    else if (distanceFromCorner > radius - borderWidth) isBorder = true;
                }
                // Coin supérieur droit
                else if (x > width - radius && y > height - radius)
                {
                    float dx = x - (width - radius);
                    float dy = (height - radius) - y;
                    distanceFromCorner = Mathf.Sqrt(dx * dx + dy * dy);
                    if (distanceFromCorner > radius) alpha = 0f;
                    else if (distanceFromCorner > radius - borderWidth) isBorder = true;
                }
                // Coin inférieur gauche
                else if (x < radius && y < radius)
                {
                    float dx = radius - x;
                    float dy = radius - y;
                    distanceFromCorner = Mathf.Sqrt(dx * dx + dy * dy);
                    if (distanceFromCorner > radius) alpha = 0f;
                    else if (distanceFromCorner > radius - borderWidth) isBorder = true;
                }
                // Coin inférieur droit
                else if (x > width - radius && y < radius)
                {
                    float dx = x - (width - radius);
                    float dy = radius - y;
                    distanceFromCorner = Mathf.Sqrt(dx * dx + dy * dy);
                    if (distanceFromCorner > radius) alpha = 0f;
                    else if (distanceFromCorner > radius - borderWidth) isBorder = true;
                }

                Color pixelColor;
                if (isBorder && alpha > 0)
                {
                    pixelColor = borderColor;
                }
                else
                {
                    // Dégradé vertical (du bas vers le haut)
                    float t = (float)y / height;
                    pixelColor = Color.Lerp(endColor, startColor, t);
                }
                
                pixelColor.a *= alpha;
                pixels[y * width + x] = pixelColor;
            }
        }

        texture.SetPixels(pixels);
        texture.Apply();
        
        dynamicTextures.Add(texture); // Ajouter pour le nettoyage

        return Sprite.Create(texture, new Rect(0, 0, width, height), new Vector2(0.5f, 0.5f), 100f);
    }
    
    void OnDestroy()
    {
        Debug.Log("[ParametresTab] 🧹 OnDestroy - Nettoyage des ressources");
        CleanupResources();
    }
    
    protected override void OnDisable()
    {
        base.OnDisable();
        Debug.Log("[ParametresTab] 🧹 OnDisable - Nettoyage pour éviter fuite mémoire WebGL");

        if (playTimeRefreshCoroutine != null)
        {
            StopCoroutine(playTimeRefreshCoroutine);
            playTimeRefreshCoroutine = null;
        }

        CleanupResources();
    }
    
    void CleanupResources()
    {
        // Nettoyer les textures dynamiques
        foreach (Texture2D tex in dynamicTextures)
        {
            if (tex != null)
            {
                Destroy(tex);
            }
        }
        dynamicTextures.Clear();
        
        #if UNITY_WEBGL && !UNITY_EDITOR
        // Forcer le garbage collector en WebGL
        System.GC.Collect();
        Debug.Log("[ParametresTab] 🧹 GC forcé pour WebGL");
        #endif
    }
    
    protected override void OnEnable()
    {
        base.OnEnable();
        Debug.Log("[ParametresTab] OnEnable: Parametres visibles");

        RefreshUserInfo();
        if (playTimeRefreshCoroutine != null) StopCoroutine(playTimeRefreshCoroutine);
        playTimeRefreshCoroutine = StartCoroutine(RefreshPlayTimeLoop());
    }

    private System.Collections.IEnumerator RefreshPlayTimeLoop()
    {
        while (isActiveAndEnabled)
        {
            RefreshUserInfo();
            yield return new WaitForSeconds(1f);
        }
    }

    private void RefreshUserInfo()
    {
        var udm = UserDataManager.Instance;
        bool loggedIn = udm != null && udm.IsLoggedIn();

        if (userInfoSection != null)
        {
            userInfoSection.SetActive(true);
        }

        if (emailInfoText != null)
        {
            emailInfoText.gameObject.SetActive(loggedIn);
            if (loggedIn)
            {
                string mail = string.IsNullOrEmpty(udm.email) ? "" : udm.email;
                emailInfoText.text = $"<b>Email :</b> {mail}";
            }
        }

        if (playTimeInfoText != null)
        {
            float seconds = udm != null ? udm.playTime : 0f;
            string formatted = udm != null ? udm.FormatPlayTime(seconds) : "00:00";
            playTimeInfoText.text = $"<b>Temps de jeu :</b> {formatted}";
        }
    }
    
    void OnSoundToggleChanged(bool isOn)
    {
        Debug.Log($"[ParametresTab] Son change a: {isOn}");
        PlayerPrefs.SetInt("SoundEnabled", isOn ? 1 : 0);
        PlayerPrefs.Save();
        AudioListener.volume = isOn ? 1f : 0f;
        UpdateSoundLabel(isOn);
    }
    
    void UpdateSoundLabel(bool isOn)
    {
        if (soundLabel != null)
        {
            soundLabel.text = isOn ? "Son active" : "Son coupe";
        }
    }
    
    void OnQuitClicked()
    {
        Debug.Log("[ParametresTab] Retour au menu général (scène Main)...");
        StartCoroutine(QuitAndLoadMainScene());
    }
    
    private IEnumerator QuitAndLoadMainScene()
    {
        // Fermer le panneau des paramètres (nettoie les ressources)
        if (SettingsManager.Instance != null)
        {
            SettingsManager.Instance.CloseSettings();
        }
        
        // 🧹 CORRECTION OOM WebGL: Nettoyer la mémoire avant de charger la scène
#if UNITY_WEBGL && !UNITY_EDITOR
        Debug.Log("[ParametresTab] 🧹 WebGL - Nettoyage mémoire avant rechargement...");
        
        // Purger les caches persistants
        try { if (RemoteSpriteCache.GetExisting() != null) RemoteSpriteCache.GetExisting().ClearAll(); } catch { }
        try { if (GameDataManager.Instance != null) GameDataManager.Instance.ClearAssetCache(); } catch { }
        
        // Attendre un frame pour que les Destroy() prennent effet
        yield return null;
        yield return new WaitForEndOfFrame();
        
        // Libérer les assets non référencés
        yield return Resources.UnloadUnusedAssets();
        try { System.GC.Collect(); } catch { }
        
        yield return null;
        Debug.Log("[ParametresTab] ✅ Nettoyage mémoire WebGL terminé");
#else
        yield return null;
#endif
        
        // Toujours aller vers la scène Main, même si on était sur la scène Map
        Debug.Log("[ParametresTab] 🚀 Chargement de la scène main...");
        SceneManager.LoadScene("main");
    }
    
    void OnLogoutClicked()
    {
        Debug.Log("[ParametresTab] ========== DÉCONNEXION DÉCLENCHÉE ==========");
        StartCoroutine(LogoutAndLoadMainScene());
    }
    
    private IEnumerator LogoutAndLoadMainScene()
    {
        // Effacer toutes les PlayerPrefs
        PlayerPrefs.DeleteAll();
        PlayerPrefs.Save();
        Debug.Log("[ParametresTab] ✅ Toutes les PlayerPrefs effacées");
        
        // Déconnecter l'utilisateur
        if (UserDataManager.Instance != null)
        {
            UserDataManager.Instance.Logout();
            Debug.Log("[ParametresTab] ✅ UserDataManager.Logout() appelé");
        }
        else
        {
            Debug.LogWarning("[ParametresTab] UserDataManager.Instance est null !");
        }
        
        // Fermer le panneau des paramètres
        if (SettingsManager.Instance != null)
        {
            SettingsManager.Instance.CloseSettings();
            Debug.Log("[ParametresTab] ✅ Panel des paramètres fermé");
        }
        else
        {
            Debug.LogWarning("[ParametresTab] SettingsManager.Instance est null !");
        }

        // WebGL + iframe : si le token parent est encore présent, la scène Main n'affiche PAS la popup
        // (elle attend l'auth iframe ou considère qu'un token est "en cours").
        // On purge donc explicitement le token postMessage + pending token, et on reset l'état de l'iframe auth.
        #if UNITY_WEBGL && !UNITY_EDITOR
        try
        {
            if (PostMessageBridge.Instance != null && PostMessageBridge.Instance.IsInIframe)
            {
                // Demander au parent de purger SON token aussi (sinon il peut le renvoyer au reload)
                PostMessageBridge.Instance.NotifyLogout();
                PostMessageBridge.Instance.ClearToken();
                PostMessageBridge.Instance.ClearPendingToken();
            }

            var iframeAuth = FindFirstObjectByType<IframeAuthManager>();
            if (iframeAuth != null)
            {
                iframeAuth.ResetAuthState();
            }
        }
        catch (System.Exception e)
        {
            Debug.LogWarning($"[ParametresTab] ⚠️ Exception purge iframe auth: {e.Message}");
        }
        #endif

        // Forcer l'affichage de la popup de login sur la scène main (même en iframe)
        // afin de ne pas rester dans un état où la popup est supprimée à cause d'un token résiduel.
        PlayerPrefs.SetInt("ForceShowLoginPopup", 1);
        PlayerPrefs.Save();
        
        // 🧹 CORRECTION OOM WebGL: Nettoyer la mémoire avant de charger la scène
#if UNITY_WEBGL && !UNITY_EDITOR
        Debug.Log("[ParametresTab] 🧹 WebGL - Nettoyage mémoire avant rechargement...");
        
        // Purger les caches persistants
        try { if (RemoteSpriteCache.GetExisting() != null) RemoteSpriteCache.GetExisting().ClearAll(); } catch { }
        try { if (GameDataManager.Instance != null) GameDataManager.Instance.ClearAssetCache(); } catch { }
        
        // Attendre un frame pour que les Destroy() prennent effet
        yield return null;
        yield return new WaitForEndOfFrame();
        
        // Libérer les assets non référencés
        yield return Resources.UnloadUnusedAssets();
        try { System.GC.Collect(); } catch { }
        
        yield return null;
        Debug.Log("[ParametresTab] ✅ Nettoyage mémoire WebGL terminé");
#else
        yield return null;
#endif
        
        // Recharger la scène main
        Debug.Log("[ParametresTab] 🚀 Rechargement de la scène main...");
        SceneManager.LoadScene("main");
    }
}
