using UnityEngine;
using TMPro;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class ScoresTab : SettingsTab
{
    // Références UI
    private GameObject leftSection;
    private GameObject rightSection;
    
    // Badges débloqués (completion = 100)
    private List<BadgeData> unlockedBadges = new List<BadgeData>();
    private int currentBadgeIndex = 0;
    
    // Super-badge
    private SuperBadge currentSuperBadge;
    
    // Navigation
    private GameObject leftArrow;
    private GameObject rightArrow;
    private GameObject badgesContainer;
    
    // Partie gauche - DDA
    private GameObject ddaClockImage;
    private QuestUserProgress currentInProgressQuest; // Quête en cours (0 < completion < 100)
    
    // Resources dynamiques (pour le nettoyage WebGL)
    private readonly RuntimeResourceTracker resourceTracker = new RuntimeResourceTracker();
    
    // Liste des images en attente de chargement
    private List<PendingImageLoad> pendingImageLoads = new List<PendingImageLoad>();
    
    // Flags de chargement
    private bool isLoadingData = false;
    private bool hasLoadedData = false; // Pour éviter de recharger à chaque activation de l'onglet
    
    // Config
    private GeneralConfig generalConfig;
    private ScoresTabConfig config;
    
    // Structure pour les chargements d'images en attente
    private class PendingImageLoad
    {
        public Image image;
        public string url;
        public bool needsCanvasGroupReveal;
    }
    
    protected override void Awake()
    {
        base.Awake();
        tabName = "SCORES";
        tabOrder = 0;
        
        // Charger la config
        if (GeneralConfigManager.Instance != null)
        {
            generalConfig = GeneralConfigManager.Instance.GetConfig();
            config = generalConfig?.scoresTabConfig;
            
            if (config == null)
            {
                Debug.LogWarning("[ScoresTab] ⚠️ scoresTabConfig non trouvé dans general-config.json");
            }
        }
        
        // Créer le contenu de l'onglet
        CreateInterface();
    }
    
    protected override void OnEnable()
    {
        base.OnEnable();
        
        // Charger les images en attente
        if (pendingImageLoads.Count > 0)
        {
            StartCoroutine(LoadAllPendingImages());
        }
        
        // Charger les données SEULEMENT la première fois
        if (!isLoadingData && !hasLoadedData)
        {
            StartCoroutine(LoadDataAfterFrame());
        }
    }
    
    private IEnumerator LoadDataAfterFrame()
    {
        yield return null; // Attendre une frame pour s'assurer que le GameObject est actif
        
        if (gameObject.activeInHierarchy)
        {
            LoadData();
        }
    }
    
    private IEnumerator LoadAllPendingImages()
    {
        Debug.Log($"[ScoresTab] 🖼️ Chargement de {pendingImageLoads.Count} images en attente");
        
        foreach (var pending in pendingImageLoads)
        {
            if (pending.image != null)
            {
                yield return StartCoroutine(LoadImageFromUrl(pending.url, pending.image, pending.needsCanvasGroupReveal));
            }
        }
        
        pendingImageLoads.Clear();
    }
    
    private IEnumerator LoadImageFromUrl(string url, Image targetImage, bool needsCanvasGroupReveal)
    {
        Debug.Log($"[ScoresTab] 🖼️ Chargement depuis: {url}");
        
        using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(url))
        {
            yield return www.SendWebRequest();
            
            if (www.result == UnityWebRequest.Result.Success)
            {
                Texture2D texture = DownloadHandlerTexture.GetContent(www);
                if (texture != null)
                {
                    Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100f);
                    TrackDynamic(texture, sprite);
                    
                    if (targetImage != null)
                    {
                        targetImage.sprite = sprite;
                        
                        // Afficher l'image si elle était masquée
                        if (needsCanvasGroupReveal)
                        {
                            Color opaqueColor = targetImage.color;
                            opaqueColor.a = 1f;
                            targetImage.color = opaqueColor;
                        }
                        
                        Debug.Log($"[ScoresTab] ✅ Image chargée avec succès ({texture.width}x{texture.height})");
                    }
                }
                else
                {
                    Debug.LogError($"[ScoresTab] ❌ Texture null pour {url}");
                }
            }
            else
            {
                Debug.LogError($"[ScoresTab] ❌ Erreur de chargement: {url} - {www.error}");
            }
        }
    }
    
    private void OnDestroy()
    {
        Debug.Log("[ScoresTab] 🧹 Nettoyage des ressources dynamiques");
        resourceTracker.Cleanup();
        Debug.Log($"[ScoresTab] ✅ Nettoyage terminé: {resourceTracker.Count} ressources étaient trackées");
    }
    
    protected override void OnDisable()
    {
        base.OnDisable();
        // Pas de cleanup ici, on le fait seulement dans OnDestroy
        // pour éviter de détruire les ressources quand on change juste d'onglet
    }
    
    private void TrackDynamic(Texture2D tex, Sprite sp)
    {
        resourceTracker.Track(tex, sp);
    }
    
    private void CreateInterface()
    {
        // Container principal avec layout horizontal (gauche + droite)
        HorizontalLayoutGroup mainLayout = gameObject.AddComponent<HorizontalLayoutGroup>();
        mainLayout.childAlignment = TextAnchor.UpperCenter;
        
        float spacing = config?.layout?.mainSpacing ?? 20;
        mainLayout.spacing = spacing;
        
        int padL = 40, padR = 40, padT = 40, padB = 40;
        if (config?.layout?.mainPadding != null)
        {
            padL = (int)config.layout.mainPadding.left;
            padR = (int)config.layout.mainPadding.right;
            padT = (int)config.layout.mainPadding.top;
            padB = (int)config.layout.mainPadding.bottom;
        }
        mainLayout.padding = new RectOffset(padL, padR, padT, padB);
        
        mainLayout.childControlWidth = true;
        mainLayout.childControlHeight = true;
        mainLayout.childForceExpandWidth = false;
        mainLayout.childForceExpandHeight = false;
        
        // Section GAUCHE (placeholder pour l'instant)
        leftSection = CreateLeftSection();
        
        // Section DROITE
        rightSection = CreateRightSection();
    }
    
    private GameObject CreateLeftSection()
    {
        GameObject section = new GameObject("LeftSection");
        section.transform.SetParent(transform, false);
        
        RectTransform rect = section.AddComponent<RectTransform>();
        
        // Récupérer les dimensions depuis la config
        float width = config?.leftSection?.width ?? 500;
        float height = config?.leftSection?.height ?? 600;
        float cornerRadius = config?.leftSection?.cornerRadius ?? 20;
        float spacing = config?.leftSection?.spacing ?? 30;
        
        // Récupérer le padding depuis la config
        int padLeft = 20, padRight = 20, padTop = 20, padBottom = 20;
        if (config?.leftSection?.padding != null)
        {
            padLeft = (int)config.leftSection.padding.left;
            padRight = (int)config.leftSection.padding.right;
            padTop = (int)config.leftSection.padding.top;
            padBottom = (int)config.leftSection.padding.bottom;
        }
        
        LayoutElement layout = section.AddComponent<LayoutElement>();
        layout.minWidth = width;
        layout.preferredWidth = width;
        layout.minHeight = height;
        layout.preferredHeight = height;
        layout.flexibleWidth = 0;
        layout.flexibleHeight = 0;
        
        // Layout vertical : Jauge Zénitude + DDA + Texte info
        VerticalLayoutGroup vLayout = section.AddComponent<VerticalLayoutGroup>();
        vLayout.childAlignment = TextAnchor.UpperCenter;
        vLayout.spacing = spacing;
        vLayout.padding = new RectOffset(padLeft, padRight, padTop, padBottom);
        vLayout.childControlWidth = false;
        vLayout.childControlHeight = false;
        vLayout.childForceExpandWidth = false;
        vLayout.childForceExpandHeight = false;
        
        // Fond avec coins arrondis et couleur depuis la config
        Color bgColor = new Color(0.9f, 0.87f, 0.84f, 0.5f);
        if (config?.leftSection != null && !string.IsNullOrEmpty(config.leftSection.backgroundColor))
        {
            bgColor = HexToColor(config.leftSection.backgroundColor);
        }
        
        Image bg = section.AddComponent<Image>();
        bg.sprite = CreateRoundedSprite((int)width, (int)height, cornerRadius, bgColor);
        bg.type = Image.Type.Sliced;
        bg.raycastTarget = false;
        
        // Bloc DDA
        CreateDDASection(section.transform);
        
        // Texte d'information en bas
        CreateInfoText(section.transform);
        
        return section;
    }
    
    
    private Sprite CreateRoundedRectSprite(int width, int height, int cornerRadius, Color fillColor, Color borderColor, int borderWidth)
    {
        Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
        Color[] pixels = new Color[width * height];
        
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                bool isInside = IsInsideRoundedRect(x, y, width, height, cornerRadius);
                bool isBorder = borderWidth > 0 && IsInRoundedRectBorder(x, y, width, height, cornerRadius, borderWidth);
                
                if (isBorder)
                {
                    pixels[y * width + x] = borderColor;
                }
                else if (isInside)
                {
                    pixels[y * width + x] = fillColor;
                }
                else
                {
                    pixels[y * width + x] = Color.clear;
                }
            }
        }
        
        texture.SetPixels(pixels);
        texture.Apply();
        
        return Sprite.Create(texture, new Rect(0, 0, width, height), new Vector2(0.5f, 0.5f), 100f);
    }
    
    private bool IsInsideRoundedRect(int x, int y, int width, int height, int cornerRadius)
    {
        // Coins
        if (x < cornerRadius && y < cornerRadius)
            return Vector2.Distance(new Vector2(x, y), new Vector2(cornerRadius, cornerRadius)) <= cornerRadius;
        if (x >= width - cornerRadius && y < cornerRadius)
            return Vector2.Distance(new Vector2(x, y), new Vector2(width - cornerRadius - 1, cornerRadius)) <= cornerRadius;
        if (x < cornerRadius && y >= height - cornerRadius)
            return Vector2.Distance(new Vector2(x, y), new Vector2(cornerRadius, height - cornerRadius - 1)) <= cornerRadius;
        if (x >= width - cornerRadius && y >= height - cornerRadius)
            return Vector2.Distance(new Vector2(x, y), new Vector2(width - cornerRadius - 1, height - cornerRadius - 1)) <= cornerRadius;
        
        return true;
    }
    
    private bool IsInRoundedRectBorder(int x, int y, int width, int height, int cornerRadius, int borderWidth)
    {
        bool outerInside = IsInsideRoundedRect(x, y, width, height, cornerRadius);
        bool innerInside = IsInsideRoundedRect(x, y, width - 2 * borderWidth, height - 2 * borderWidth, Mathf.Max(0, cornerRadius - borderWidth));
        
        // Ajuster la position pour le rectangle intérieur
        int innerX = x - borderWidth;
        int innerY = y - borderWidth;
        
        if (innerX >= 0 && innerX < width - 2 * borderWidth && innerY >= 0 && innerY < height - 2 * borderWidth)
        {
            innerInside = IsInsideRoundedRect(innerX, innerY, width - 2 * borderWidth, height - 2 * borderWidth, Mathf.Max(0, cornerRadius - borderWidth));
        }
        else
        {
            innerInside = false;
        }
        
        return outerInside && !innerInside;
    }
    
    
    private void CreateDDASection(Transform parent)
    {
        GameObject ddaSection = new GameObject("DDASection");
        ddaSection.transform.SetParent(parent, false);
        
        RectTransform ddaRect = ddaSection.AddComponent<RectTransform>();
        ddaRect.sizeDelta = new Vector2(500, 150);
        
        // Layout vertical : Titre + Contenu
        VerticalLayoutGroup vLayout = ddaSection.AddComponent<VerticalLayoutGroup>();
        vLayout.childAlignment = TextAnchor.UpperCenter;
        vLayout.spacing = 20;
        vLayout.childControlWidth = false;
        vLayout.childControlHeight = false;
        vLayout.childForceExpandWidth = false;
        vLayout.childForceExpandHeight = false;
        
        // Titre "DDA"
        GameObject titleObj = new GameObject("Title");
        titleObj.transform.SetParent(ddaSection.transform, false);
        
        RectTransform titleRect = titleObj.AddComponent<RectTransform>();
        titleRect.sizeDelta = new Vector2(400, 40);
        
        // Récupérer les paramètres depuis la config
        string ddaTitleText = config?.leftSection?.dda?.titleText ?? "DDA";
        float ddaTitleFontSize = config?.leftSection?.dda?.titleFontSize ?? 24;
        Color ddaTitleColor = new Color(0.35f, 0.31f, 0.45f, 1f);
        if (config?.leftSection?.dda != null && !string.IsNullOrEmpty(config.leftSection.dda.titleColor))
        {
            ddaTitleColor = HexToColor(config.leftSection.dda.titleColor);
        }
        
        TextMeshProUGUI titleText = titleObj.AddComponent<TextMeshProUGUI>();
        titleText.text = ddaTitleText;
        titleText.fontSize = ddaTitleFontSize;
        titleText.color = ddaTitleColor;
        titleText.alignment = TextAlignmentOptions.Center;
        titleText.font = GetAntonFont();
        titleText.raycastTarget = false;
        
        // Container vertical pour horloge+temps en overlay + bouton
        GameObject contentContainer = new GameObject("ContentContainer");
        contentContainer.transform.SetParent(ddaSection.transform, false);
        
        RectTransform contentRect = contentContainer.AddComponent<RectTransform>();
        contentRect.sizeDelta = new Vector2(500, 200);
        
        VerticalLayoutGroup vLayoutContent = contentContainer.AddComponent<VerticalLayoutGroup>();
        vLayoutContent.childAlignment = TextAnchor.UpperCenter;
        vLayoutContent.spacing = config?.leftSection?.dda?.buttonMarginTop ?? 20;
        vLayoutContent.childControlWidth = false;
        vLayoutContent.childControlHeight = false;
        vLayoutContent.childForceExpandWidth = false;
        vLayoutContent.childForceExpandHeight = false;
        
        // Container pour horloge + texte en overlay
        GameObject clockContainer = new GameObject("ClockContainer");
        clockContainer.transform.SetParent(contentContainer.transform, false);
        
        float clockWidth = config?.leftSection?.dda?.clockWidth ?? 80;
        float clockHeight = config?.leftSection?.dda?.clockHeight ?? 80;
        
        RectTransform clockContainerRect = clockContainer.AddComponent<RectTransform>();
        clockContainerRect.sizeDelta = new Vector2(clockWidth, clockHeight);
        
        // Image de l'horloge DDA
        ddaClockImage = new GameObject("ClockImage");
        ddaClockImage.transform.SetParent(clockContainer.transform, false);
        
        RectTransform clockRect = ddaClockImage.AddComponent<RectTransform>();
        clockRect.anchorMin = new Vector2(0.5f, 0.5f);
        clockRect.anchorMax = new Vector2(0.5f, 0.5f);
        clockRect.pivot = new Vector2(0.5f, 0.5f);
        clockRect.anchoredPosition = Vector2.zero;
        clockRect.sizeDelta = new Vector2(clockWidth, clockHeight);
        
        Image clockImage = ddaClockImage.AddComponent<Image>();
        clockImage.preserveAspect = true;
        clockImage.raycastTarget = false;
        
        // Rendre l'image transparente pendant le chargement
        Color transparentColor = Color.white;
        transparentColor.a = 0f;
        clockImage.color = transparentColor;
        
        // Ajouter à la liste d'attente pour chargement
        string uiPath = generalConfig?.assetsPaths?.uiPath ?? "https://d27dezxjuxsdf7.cloudfront.net/media/2024/11/";
        string clockImageName = config?.leftSection?.dda?.clockImageName ?? "horloge-dda.png";
        string clockUrl = uiPath + clockImageName;
        pendingImageLoads.Add(new PendingImageLoad 
        { 
            image = clockImage, 
            url = clockUrl, 
            needsCanvasGroupReveal = true 
        });
        
        // Texte du temps en overlay sur l'horloge
        GameObject timeTextObj = new GameObject("TimeText");
        timeTextObj.transform.SetParent(clockContainer.transform, false);
        
        float timeOffsetX = config?.leftSection?.dda?.timePosition?.offsetX ?? 0;
        float timeOffsetY = config?.leftSection?.dda?.timePosition?.offsetY ?? 0;
        
        RectTransform timeTextRect = timeTextObj.AddComponent<RectTransform>();
        timeTextRect.anchorMin = new Vector2(0.5f, 0.5f);
        timeTextRect.anchorMax = new Vector2(0.5f, 0.5f);
        timeTextRect.pivot = new Vector2(0.5f, 0.5f);
        timeTextRect.anchoredPosition = new Vector2(timeOffsetX, timeOffsetY);
        timeTextRect.sizeDelta = new Vector2(clockWidth, 40);
        
        string timeDefaultText = config?.leftSection?.dda?.timeDefaultText ?? "8 HEURES";
        float timeFontSize = config?.leftSection?.dda?.timeFontSize ?? 18;
        Color timeTextColor = new Color(0.35f, 0.31f, 0.29f, 1f);
        if (config?.leftSection?.dda != null && !string.IsNullOrEmpty(config.leftSection.dda.timeTextColor))
        {
            timeTextColor = HexToColor(config.leftSection.dda.timeTextColor);
        }
        
        TextMeshProUGUI timeText = timeTextObj.AddComponent<TextMeshProUGUI>();
        timeText.text = timeDefaultText;
        timeText.fontSize = timeFontSize;
        timeText.color = timeTextColor;
        timeText.alignment = TextAlignmentOptions.Center;
        timeText.raycastTarget = false;
        
        // Bouton "TÉLÉCHARGER L'ATTESTATION DDA" sous l'horloge
        CreateDDAButton(contentContainer.transform);
    }
    
    private void CreateDDAButton(Transform parent)
    {
        GameObject buttonObj = new GameObject("DDAButton");
        buttonObj.transform.SetParent(parent, false);
        
        float buttonWidth = config?.leftSection?.dda?.buttonWidth ?? 280;
        float buttonHeight = config?.leftSection?.dda?.buttonHeight ?? 60;
        
        RectTransform buttonRect = buttonObj.AddComponent<RectTransform>();
        buttonRect.sizeDelta = new Vector2(buttonWidth, buttonHeight);
        
        Button button = buttonObj.AddComponent<Button>();
        
        // Utiliser le style depuis la config ou validationDefault par défaut
        string buttonStyleName = config?.leftSection?.dda?.buttonStyle ?? "validationDefault";
        ButtonStyleConfig style = GeneralConfigManager.Instance?.GetConfig()?.buttonStyles?.GetStyle(buttonStyleName);
        
        if (style != null)
        {
            Image buttonImage = buttonObj.AddComponent<Image>();
            
            // Créer le sprite avec gradient
            Color startColor = HexToColor(style.gradient.startColor);
            Color endColor = HexToColor(style.gradient.endColor);
            Color borderColor = HexToColor(style.borderColor);
            
            Sprite buttonSprite = CreateGradientSpriteWithBorder(
                (int)buttonRect.sizeDelta.x,
                (int)buttonRect.sizeDelta.y,
                (int)style.borderRadius,
                startColor,
                endColor,
                borderColor,
                (int)style.borderWidth
            );
            
            buttonImage.sprite = buttonSprite;
            TrackDynamic(buttonSprite.texture, buttonSprite);
            button.targetGraphic = buttonImage;
            
            // Configurer les couleurs du bouton (effets hover/pressed)
            ColorBlock colors = button.colors;
            colors.normalColor = Color.white;
            colors.highlightedColor = new Color(1.1f, 1.1f, 1.1f, 1f);
            colors.pressedColor = new Color(0.9f, 0.9f, 0.9f, 1f);
            colors.disabledColor = new Color(0.8f, 0.8f, 0.8f, 0.5f);
            button.colors = colors;
            
            // Texte du bouton
            GameObject textObj = new GameObject("Text");
            textObj.transform.SetParent(buttonObj.transform, false);
            
            RectTransform textRect = textObj.AddComponent<RectTransform>();
            textRect.anchorMin = Vector2.zero;
            textRect.anchorMax = Vector2.one;
            textRect.offsetMin = Vector2.zero;
            textRect.offsetMax = Vector2.zero;
            
            string buttonTextContent = config?.leftSection?.dda?.buttonText ?? "TÉLÉCHARGER L'ATTESTATION DDA";
            float buttonFontSize = config?.leftSection?.dda?.buttonFontSize ?? 14;
            
            // Récupérer la couleur du texte depuis le style
            Color textColor = Color.white;
            if (style.text != null && !string.IsNullOrEmpty(style.text.color))
            {
                textColor = HexToColor(style.text.color);
            }
            
            TextMeshProUGUI buttonText = textObj.AddComponent<TextMeshProUGUI>();
            buttonText.text = buttonTextContent;
            buttonText.fontSize = buttonFontSize;
            buttonText.color = textColor;
            buttonText.fontStyle = FontStyles.Bold;
            buttonText.alignment = TextAlignmentOptions.Center;
            buttonText.verticalAlignment = VerticalAlignmentOptions.Middle;
            buttonText.raycastTarget = false;
            
            // Charger la police depuis le style
            if (style.text != null && !string.IsNullOrEmpty(style.text.fontFamily))
            {
                TMP_FontAsset customFont = Resources.Load<TMP_FontAsset>($"Fonts/{style.text.fontFamily}");
                if (customFont != null)
                {
                    buttonText.font = customFont;
                }
            }
            
            // Action du bouton (à implémenter)
            button.onClick.AddListener(() => OnDDAButtonClicked());
        }
    }
    
    private Sprite CreateGradientSpriteWithBorder(int width, int height, int cornerRadius, Color startColor, Color endColor, Color borderColor, int borderWidth)
    {
        Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
        Color[] pixels = new Color[width * height];
        
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                bool isInside = IsInsideRoundedRect(x, y, width, height, cornerRadius);
                bool isBorder = borderWidth > 0 && IsInRoundedRectBorder(x, y, width, height, cornerRadius, borderWidth);
                
                if (isBorder)
                {
                    pixels[y * width + x] = borderColor;
                }
                else if (isInside)
                {
                    // Gradient vertical
                    float t = (float)y / height;
                    pixels[y * width + x] = Color.Lerp(startColor, endColor, t);
                }
                else
                {
                    pixels[y * width + x] = Color.clear;
                }
            }
        }
        
        texture.SetPixels(pixels);
        texture.Apply();
        
        return Sprite.Create(texture, new Rect(0, 0, width, height), new Vector2(0.5f, 0.5f), 100f);
    }
    
    private void OnDDAButtonClicked()
    {
        Debug.Log("[ScoresTab] 📄 Téléchargement de l'attestation DDA demandé");
        // TODO: Implémenter le téléchargement de l'attestation DDA
    }
    
    private void CreateInfoText(Transform parent)
    {
        GameObject infoObj = new GameObject("InfoText");
        infoObj.transform.SetParent(parent, false);
        
        float textWidth = config?.leftSection?.infoText?.textWidth ?? 450;
        float marginTop = config?.leftSection?.infoText?.marginTop ?? 20;
        
        RectTransform infoRect = infoObj.AddComponent<RectTransform>();
        infoRect.sizeDelta = new Vector2(textWidth, 100);
        
        // Ajouter un LayoutElement pour gérer le marginTop
        LayoutElement layoutElem = infoObj.AddComponent<LayoutElement>();
        layoutElem.preferredWidth = textWidth;
        layoutElem.preferredHeight = 100;
        
        // Texte d'information (sans icône)
        GameObject textObj = new GameObject("Text");
        textObj.transform.SetParent(infoObj.transform, false);
        
        RectTransform textRect = textObj.AddComponent<RectTransform>();
        textRect.anchorMin = Vector2.zero;
        textRect.anchorMax = Vector2.one;
        textRect.offsetMin = Vector2.zero;
        textRect.offsetMax = Vector2.zero;
        
        string infoTextContent = config?.leftSection?.infoText?.text ?? "Un Jour Sans Assurance te permet de tester tes connaissances sur tout le secteur de l'assurance mais si tu souhaites exclure certaines thématiques, <color=#6A5ACD><u>c'est par ici</u></color>.";
        float textFontSize = config?.leftSection?.infoText?.textFontSize ?? 12;
        
        Color textColor = new Color(0.35f, 0.31f, 0.29f, 1f);
        if (config?.leftSection?.infoText != null && !string.IsNullOrEmpty(config.leftSection.infoText.textColor))
        {
            textColor = HexToColor(config.leftSection.infoText.textColor);
        }
        
        TextMeshProUGUI infoText = textObj.AddComponent<TextMeshProUGUI>();
        infoText.text = infoTextContent;
        infoText.fontSize = textFontSize;
        infoText.color = textColor;
        infoText.alignment = TextAlignmentOptions.TopLeft;
        infoText.textWrappingMode = TextWrappingModes.Normal;
        infoText.raycastTarget = false;
    }
    
    private GameObject CreateRightSection()
    {
        GameObject section = new GameObject("RightSection");
        section.transform.SetParent(transform, false);
        
        RectTransform rect = section.AddComponent<RectTransform>();
        
        // Récupérer les dimensions depuis la config
        float width = config?.rightSection?.width ?? 1000;
        float height = config?.rightSection?.height ?? 800;
        float spacing = config?.rightSection?.spacing ?? 30;
        
        // Récupérer le padding depuis la config
        int padLeft = 20, padRight = 20, padTop = 20, padBottom = 20;
        if (config?.rightSection?.padding != null)
        {
            padLeft = (int)config.rightSection.padding.left;
            padRight = (int)config.rightSection.padding.right;
            padTop = (int)config.rightSection.padding.top;
            padBottom = (int)config.rightSection.padding.bottom;
        }
        
        LayoutElement layout = section.AddComponent<LayoutElement>();
        layout.minWidth = width;
        layout.preferredWidth = width;
        layout.minHeight = height;
        layout.preferredHeight = height;
        layout.flexibleWidth = 0;
        layout.flexibleHeight = 0;
        
        // Layout vertical : Titre + Badges + Super-badge
        VerticalLayoutGroup vLayout = section.AddComponent<VerticalLayoutGroup>();
        vLayout.childAlignment = TextAnchor.UpperCenter;
        vLayout.spacing = spacing;
        vLayout.padding = new RectOffset(padLeft, padRight, padTop, padBottom);
        vLayout.childControlWidth = false;
        vLayout.childControlHeight = false;
        vLayout.childForceExpandWidth = false;
        vLayout.childForceExpandHeight = false;
        
        // Fond avec couleur depuis la config
        Color bgColor = new Color(0.95f, 0.93f, 0.90f, 1f);
        if (config?.rightSection != null && !string.IsNullOrEmpty(config.rightSection.backgroundColor))
        {
            bgColor = HexToColor(config.rightSection.backgroundColor);
        }
        
        Image bg = section.AddComponent<Image>();
        bg.color = bgColor;
        bg.raycastTarget = false;
        
        // Titre "TES BADGES"
        CreateSectionTitle(section.transform);
        
        // Zone des badges avec navigation
        CreateBadgesNavigationSection(section.transform);
        
        // Titre "SUPER-BADGE"
        CreateSuperBadgeTitle(section.transform);
        
        // Zone du super-badge
        CreateSuperBadgeSection(section.transform);
        
        return section;
    }
    
    private void CreateSectionTitle(Transform parent)
    {
        GameObject titleObj = new GameObject("BadgesTitle");
        titleObj.transform.SetParent(parent, false);
        
        RectTransform titleRect = titleObj.AddComponent<RectTransform>();
        titleRect.sizeDelta = new Vector2(600, 50);
        
        TextMeshProUGUI titleText = titleObj.AddComponent<TextMeshProUGUI>();
        titleText.text = "TES BADGES";
        titleText.fontSize = 32;
        titleText.color = new Color(0.35f, 0.31f, 0.45f, 1f); // Violet foncé
        titleText.alignment = TextAlignmentOptions.Center;
        titleText.font = GetAntonFont();
        titleText.raycastTarget = false;
    }
    
    private void CreateBadgesNavigationSection(Transform parent)
    {
        GameObject navSection = new GameObject("BadgesNavigationSection");
        navSection.transform.SetParent(parent, false);
        
        RectTransform navRect = navSection.AddComponent<RectTransform>();
        navRect.sizeDelta = new Vector2(800, 200);
        
        // Layout horizontal : Flèche gauche | Badges | Flèche droite
        HorizontalLayoutGroup hLayout = navSection.AddComponent<HorizontalLayoutGroup>();
        hLayout.childAlignment = TextAnchor.MiddleCenter;
        hLayout.spacing = 15;
        hLayout.childControlWidth = false;
        hLayout.childControlHeight = false;
        hLayout.childForceExpandWidth = false;
        hLayout.childForceExpandHeight = false;
        
        // Flèche gauche
        leftArrow = CreateNavigationArrow(navSection.transform, true);
        
        // Container pour les badges
        badgesContainer = new GameObject("BadgesContainer");
        badgesContainer.transform.SetParent(navSection.transform, false);
        
        RectTransform containerRect = badgesContainer.AddComponent<RectTransform>();
        containerRect.sizeDelta = new Vector2(600, 200);
        
        HorizontalLayoutGroup badgesLayout = badgesContainer.AddComponent<HorizontalLayoutGroup>();
        badgesLayout.childAlignment = TextAnchor.MiddleCenter;
        badgesLayout.spacing = 20;
        badgesLayout.childControlWidth = false;
        badgesLayout.childControlHeight = false;
        badgesLayout.childForceExpandWidth = false;
        badgesLayout.childForceExpandHeight = false;
        
        // Flèche droite
        rightArrow = CreateNavigationArrow(navSection.transform, false);
    }
    
    private GameObject CreateNavigationArrow(Transform parent, bool isLeft)
    {
        GameObject arrowObj = new GameObject(isLeft ? "LeftArrow" : "RightArrow");
        arrowObj.transform.SetParent(parent, false);
        
        RectTransform arrowRect = arrowObj.AddComponent<RectTransform>();
        arrowRect.sizeDelta = new Vector2(60, 60);
        
        Image arrowImage = arrowObj.AddComponent<Image>();
        arrowImage.raycastTarget = true;
        
        // Masquer pendant le chargement
        CanvasGroup cg = arrowObj.AddComponent<CanvasGroup>();
        cg.alpha = 0f;
        
        Button arrowButton = arrowObj.AddComponent<Button>();
        arrowButton.targetGraphic = arrowImage;
        arrowButton.onClick.AddListener(() => NavigateBadges(isLeft ? -1 : 1));
        
        // Ajouter à la liste d'attente
        string arrowName = isLeft ? "nav_gauche.png" : "nav_droite.png";
        string uiPath = generalConfig?.assetsPaths?.uiPath ?? "https://d27dezxjuxsdf7.cloudfront.net/media/2024/11/";
        string arrowUrl = uiPath + arrowName;
        
        pendingImageLoads.Add(new PendingImageLoad 
        { 
            image = arrowImage, 
            url = arrowUrl, 
            needsCanvasGroupReveal = true 
        });
        
        return arrowObj;
    }
    
    private IEnumerator LoadArrowSprite(string arrowName, Image targetImage)
    {
        string uiPath = generalConfig?.assetsPaths?.uiPath ?? "https://d27dezxjuxsdf7.cloudfront.net/media/2024/11/";
        string url = uiPath + arrowName;
        
        Debug.Log($"[ScoresTab] ➡️ Chargement de la flèche depuis: {url}");
        
        using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(url))
        {
            yield return www.SendWebRequest();
            
            if (www.result == UnityWebRequest.Result.Success)
            {
                Texture2D texture = DownloadHandlerTexture.GetContent(www);
                if (texture != null)
                {
                    Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100f);
                    TrackDynamic(texture, sprite);
                    
                    if (targetImage != null)
                    {
                        targetImage.sprite = sprite;
                        Debug.Log($"[ScoresTab] ✅ Flèche {arrowName} chargée avec succès");
                    }
                    else
                    {
                        Debug.LogWarning("[ScoresTab] ⚠️ targetImage est null pour la flèche");
                    }
                }
                else
                {
                    Debug.LogError($"[ScoresTab] ❌ texture est null pour {arrowName}");
                }
            }
            else
            {
                Debug.LogWarning($"[ScoresTab] ⚠️ Erreur de chargement de la flèche {arrowName}: {www.error}");
            }
        }
    }
    
    private void CreateSuperBadgeTitle(Transform parent)
    {
        GameObject titleObj = new GameObject("SuperBadgeTitle");
        titleObj.transform.SetParent(parent, false);
        
        RectTransform titleRect = titleObj.AddComponent<RectTransform>();
        titleRect.sizeDelta = new Vector2(600, 50);
        
        TextMeshProUGUI titleText = titleObj.AddComponent<TextMeshProUGUI>();
        titleText.text = "SUPER-BADGE \"LE 100% ASSURANCE\"";
        titleText.fontSize = 28;
        titleText.color = new Color(0.35f, 0.31f, 0.45f, 1f); // Violet foncé
        titleText.alignment = TextAlignmentOptions.Center;
        titleText.font = GetAntonFont();
        titleText.raycastTarget = false;
    }
    
    private void CreateSuperBadgeSection(Transform parent)
    {
        GameObject superBadgeObj = new GameObject("SuperBadgeSection");
        superBadgeObj.transform.SetParent(parent, false);
        
        // Récupérer les dimensions depuis la config
        float badgeWidth = config?.rightSection?.superBadge?.badgeWidth ?? 250;
        float badgeHeight = config?.rightSection?.superBadge?.badgeHeight ?? 250;
        float scoreFontSize = config?.rightSection?.superBadge?.scoreFontSize ?? 36;
        
        // Récupérer la position du score
        string scoreMode = config?.rightSection?.superBadge?.scorePosition?.mode ?? "below";
        float scoreOffsetX = config?.rightSection?.superBadge?.scorePosition?.offsetX ?? 0;
        float scoreOffsetY = config?.rightSection?.superBadge?.scorePosition?.offsetY ?? 0;
        
        Color scoreColor = new Color(0.66f, 0.36f, 0.98f, 1f);
        if (config?.rightSection?.superBadge != null && !string.IsNullOrEmpty(config.rightSection.superBadge.scoreColor))
        {
            scoreColor = HexToColor(config.rightSection.superBadge.scoreColor);
        }
        
        RectTransform superBadgeRect = superBadgeObj.AddComponent<RectTransform>();
        superBadgeRect.sizeDelta = new Vector2(300, 300);
        
        bool useOverlay = scoreMode == "overlay";
        
        if (!useOverlay)
        {
            // Mode "below" : Layout vertical classique (Badge + Score)
            VerticalLayoutGroup vLayout = superBadgeObj.AddComponent<VerticalLayoutGroup>();
            vLayout.childAlignment = TextAnchor.UpperCenter;
            vLayout.spacing = 10;
            vLayout.childControlWidth = false;
            vLayout.childControlHeight = false;
            vLayout.childForceExpandWidth = false;
            vLayout.childForceExpandHeight = false;
        }
        
        // Image du super-badge
        GameObject badgeImageObj = new GameObject("SuperBadgeImage");
        badgeImageObj.transform.SetParent(superBadgeObj.transform, false);
        
        RectTransform badgeImageRect = badgeImageObj.AddComponent<RectTransform>();
        
        if (useOverlay)
        {
            // Mode overlay : badge centré dans le conteneur
            badgeImageRect.anchorMin = new Vector2(0.5f, 0.5f);
            badgeImageRect.anchorMax = new Vector2(0.5f, 0.5f);
            badgeImageRect.pivot = new Vector2(0.5f, 0.5f);
            badgeImageRect.anchoredPosition = Vector2.zero;
        }
        
        badgeImageRect.sizeDelta = new Vector2(badgeWidth, badgeHeight);
        
        Image badgeImage = badgeImageObj.AddComponent<Image>();
        badgeImage.raycastTarget = false;
        badgeImage.preserveAspect = true;
        
        // Rendre l'image transparente pendant le chargement (comme pour les badges normaux)
        Color transparentColor = Color.white;
        transparentColor.a = 0f;
        badgeImage.color = transparentColor;
        
        // Score du super-badge
        GameObject scoreObj = new GameObject("SuperBadgeScore");
        scoreObj.transform.SetParent(superBadgeObj.transform, false);
        
        RectTransform scoreRect = scoreObj.AddComponent<RectTransform>();
        
        if (useOverlay)
        {
            // Mode overlay : score centré sur le badge avec offset
            scoreRect.anchorMin = new Vector2(0.5f, 0.5f);
            scoreRect.anchorMax = new Vector2(0.5f, 0.5f);
            scoreRect.pivot = new Vector2(0.5f, 0.5f);
            scoreRect.anchoredPosition = new Vector2(scoreOffsetX, scoreOffsetY);
            scoreRect.sizeDelta = new Vector2(badgeWidth, 60);
        }
        else
        {
            // Mode below : score positionné normalement sous le badge
            scoreRect.sizeDelta = new Vector2(200, 50);
        }
        
        TextMeshProUGUI scoreText = scoreObj.AddComponent<TextMeshProUGUI>();
        scoreText.text = "0%";
        scoreText.fontSize = scoreFontSize;
        scoreText.color = scoreColor;
        scoreText.alignment = TextAlignmentOptions.Center;
        scoreText.font = GetAntonFont();
        scoreText.raycastTarget = false;
    }
    
    private TMP_FontAsset GetAntonFont()
    {
        // Charger la police Anton depuis les ressources
        string fontName = "Anton-Regular SDF";
        TMP_FontAsset font = Resources.Load<TMP_FontAsset>("Fonts & Materials/" + fontName);
        if (font == null)
        {
            font = Resources.Load<TMP_FontAsset>(fontName);
        }
        return font;
    }
    
    private void LoadData()
    {
        if (isLoadingData) return;
        
        isLoadingData = true;
        Debug.Log("[ScoresTab] 🚀 Chargement des données");
        
        // Charger les quêtes pour obtenir les badges
        StartCoroutine(LoadQuestsData());
        
        // Charger le super-badge
        StartCoroutine(LoadUserData());
    }
    
    private IEnumerator LoadQuestsData()
    {
        // Utiliser la même méthode que QuetesTab pour obtenir l'URL
        string apiUrl = GeneralConfigManager.Instance?.GetMainSceneConfigApiUrl();
        
        if (string.IsNullOrEmpty(apiUrl))
        {
            Debug.LogWarning("[ScoresTab] ⚠️ Impossible d'obtenir l'URL de l'API");
            isLoadingData = false;
            yield break;
        }
        
        Debug.Log($"[ScoresTab] 📊 Chargement des quêtes depuis: {apiUrl}");
        
        using (UnityWebRequest www = UnityWebRequest.Get(apiUrl))
        {
            // Ajouter le token Bearer
            string token = UserDataManager.Instance != null ? UserDataManager.Instance.token : PlayerPrefs.GetString("userToken", "");
            if (!string.IsNullOrEmpty(token))
            {
                www.SetRequestHeader("Authorization", $"Bearer {token}");
                Debug.Log("[ScoresTab] 🔑 Token ajouté à la requête");
            }
            
            yield return www.SendWebRequest();
            
            if (www.result == UnityWebRequest.Result.Success)
            {
                string json = www.downloadHandler.text;
                Debug.Log($"[ScoresTab] ✅ Données reçues ({json.Length} caractères)");
                
                // Parser la réponse (structure MainSceneApiResponse)
                MainSceneApiResponse response = JsonUtility.FromJson<MainSceneApiResponse>(json);
                
                if (response != null && response.status == "success" && response.data != null && response.data.quests != null)
                {
                    Debug.Log($"[ScoresTab] 📋 {response.data.quests.Count} quêtes trouvées");
                    ProcessQuestsData(response.data.quests);
                }
                else
                {
                    Debug.LogWarning("[ScoresTab] ⚠️ Réponse invalide de l'API quêtes");
                }
            }
            else
            {
                Debug.LogError($"[ScoresTab] ❌ Erreur de chargement des quêtes: {www.error}");
            }
        }
        
        isLoadingData = false;
    }
    
    private void ProcessQuestsData(List<Quest> quests)
    {
        unlockedBadges.Clear();
        currentInProgressQuest = null;
        
        foreach (Quest quest in quests)
        {
            if (quest.user != null && quest.user.Count > 0)
            {
                foreach (QuestUserProgress progress in quest.user)
                {
                    // Chercher la quête en cours (0 < completion < 100)
                    if (currentInProgressQuest == null && progress.completion > 0 && progress.completion < 100)
                    {
                        currentInProgressQuest = progress;
                        Debug.Log($"[ScoresTab] 🌸 Quête en cours trouvée: {quest.title} ({progress.difficulty}) - {progress.completion}%");
                    }
                    
                    // Ne garder que les badges avec completion = 100
                    if (progress.completion == 100)
                    {
                        BadgeData badgeData = new BadgeData
                        {
                            questId = quest.id,
                            questTitle = quest.title,
                            difficulty = progress.difficulty,
                            score = progress.score,
                            completion = progress.completion,
                            badgeUrl = progress.badge
                        };
                        
                        unlockedBadges.Add(badgeData);
                    }
                }
            }
        }
        
        Debug.Log($"[ScoresTab] 🏆 {unlockedBadges.Count} badges débloqués trouvés");
        
        // Afficher les badges
        PopulateBadges();
        
        // Marquer les données comme chargées pour éviter de recharger à chaque changement d'onglet
        hasLoadedData = true;
    }
    
    private void PopulateBadges()
    {
        // Nettoyer le container
        foreach (Transform child in badgesContainer.transform)
        {
            Destroy(child.gameObject);
        }
        
        int maxVisibleBadges = config?.rightSection?.badges?.maxVisibleBadges ?? 3;
        
        // Calculer les badges visibles
        int startIndex = currentBadgeIndex;
        int endIndex = Mathf.Min(startIndex + maxVisibleBadges, unlockedBadges.Count);
        
        Debug.Log($"[ScoresTab] 📊 Affichage des badges {startIndex} à {endIndex-1} sur {unlockedBadges.Count}");
        
        // Créer les cartes de badges
        for (int i = startIndex; i < endIndex; i++)
        {
            CreateBadgeCard(unlockedBadges[i]);
        }
        
        // Charger les images en attente si on vient de créer des badges
        if (pendingImageLoads.Count > 0)
        {
            Debug.Log($"[ScoresTab] 🖼️ Déclenchement du chargement de {pendingImageLoads.Count} images après création des badges");
            StartCoroutine(LoadAllPendingImages());
        }
        
        // Mise à jour de l'état des flèches
        UpdateNavigationArrows();
    }
    
    private void CreateBadgeCard(BadgeData badgeData)
    {
        GameObject cardObj = new GameObject($"BadgeCard_{badgeData.questId}_{badgeData.difficulty}");
        cardObj.transform.SetParent(badgesContainer.transform, false);
        
        // Récupérer les dimensions depuis la config
        float badgeWidth = config?.rightSection?.badges?.badgeWidth ?? 150;
        float badgeHeight = config?.rightSection?.badges?.badgeHeight ?? 182;
        
        RectTransform cardRect = cardObj.AddComponent<RectTransform>();
        cardRect.sizeDelta = new Vector2(180, 200);
        
        // Layout vertical : Badge + Titre
        VerticalLayoutGroup vLayout = cardObj.AddComponent<VerticalLayoutGroup>();
        vLayout.childAlignment = TextAnchor.UpperCenter;
        vLayout.spacing = 10;
        vLayout.childControlWidth = false;
        vLayout.childControlHeight = false;
        vLayout.childForceExpandWidth = false;
        vLayout.childForceExpandHeight = false;
        
        // Container pour le badge avec le badge de score
        GameObject badgeContainer = new GameObject("BadgeContainer");
        badgeContainer.transform.SetParent(cardObj.transform, false);
        
        RectTransform badgeContainerRect = badgeContainer.AddComponent<RectTransform>();
        badgeContainerRect.sizeDelta = new Vector2(badgeWidth, badgeHeight);
        
        // Image du badge
        GameObject badgeImageObj = new GameObject("BadgeImage");
        badgeImageObj.transform.SetParent(badgeContainer.transform, false);
        
        RectTransform badgeImageRect = badgeImageObj.AddComponent<RectTransform>();
        badgeImageRect.anchorMin = new Vector2(0.5f, 0.5f);
        badgeImageRect.anchorMax = new Vector2(0.5f, 0.5f);
        badgeImageRect.pivot = new Vector2(0.5f, 0.5f);
        badgeImageRect.sizeDelta = new Vector2(badgeWidth, badgeHeight);
        
        Image badgeImage = badgeImageObj.AddComponent<Image>();
        badgeImage.raycastTarget = false;
        badgeImage.preserveAspect = true;
        
        // Rendre l'image transparente pendant le chargement
        Color transparentColor = Color.white;
        transparentColor.a = 0f;
        badgeImage.color = transparentColor;
        
        // Ajouter à la liste d'attente
        if (!string.IsNullOrEmpty(badgeData.badgeUrl))
        {
            pendingImageLoads.Add(new PendingImageLoad 
            { 
                image = badgeImage, 
                url = badgeData.badgeUrl, 
                needsCanvasGroupReveal = true 
            });
        }
        
        // Badge de pourcentage (bulle avec le score)
        CreateScoreBadge(badgeContainer.transform, badgeData.score);
        
        // Titre sous le badge
        GameObject titleObj = new GameObject("BadgeTitle");
        titleObj.transform.SetParent(cardObj.transform, false);
        
        RectTransform titleRect = titleObj.AddComponent<RectTransform>();
        titleRect.sizeDelta = new Vector2(180, 40);
        
        TextMeshProUGUI titleText = titleObj.AddComponent<TextMeshProUGUI>();
        titleText.text = $"{badgeData.questTitle}\n<size=12>{badgeData.difficulty}</size>";
        titleText.fontSize = 14;
        titleText.color = new Color(0.47f, 0.4f, 0.44f, 1f);
        titleText.alignment = TextAlignmentOptions.Center;
        titleText.textWrappingMode = TextWrappingModes.Normal;
        titleText.raycastTarget = false;
    }
    
    private void CreateScoreBadge(Transform parent, int score)
    {
        GameObject scoreBadgeObj = new GameObject("ScoreBadge");
        scoreBadgeObj.transform.SetParent(parent, false);
        
        RectTransform scoreBadgeRect = scoreBadgeObj.AddComponent<RectTransform>();
        scoreBadgeRect.anchorMin = new Vector2(1f, 1f);
        scoreBadgeRect.anchorMax = new Vector2(1f, 1f);
        scoreBadgeRect.pivot = new Vector2(1f, 1f);
        scoreBadgeRect.anchoredPosition = new Vector2(-5, -5);
        scoreBadgeRect.sizeDelta = new Vector2(50, 50);
        
        // Fond circulaire violet
        Image bg = scoreBadgeObj.AddComponent<Image>();
        bg.sprite = CreateCircleSprite(50);
        bg.color = new Color(0.66f, 0.36f, 0.98f, 1f); // Violet
        TrackDynamic(bg.sprite.texture, bg.sprite);
        
        // Texte du score
        GameObject scoreTextObj = new GameObject("ScoreText");
        scoreTextObj.transform.SetParent(scoreBadgeObj.transform, false);
        
        RectTransform scoreTextRect = scoreTextObj.AddComponent<RectTransform>();
        scoreTextRect.anchorMin = Vector2.zero;
        scoreTextRect.anchorMax = Vector2.one;
        scoreTextRect.offsetMin = Vector2.zero;
        scoreTextRect.offsetMax = Vector2.zero;
        
        TextMeshProUGUI scoreText = scoreTextObj.AddComponent<TextMeshProUGUI>();
        scoreText.text = $"{score}%";
        scoreText.fontSize = 14;
        scoreText.color = Color.white;
        scoreText.alignment = TextAlignmentOptions.Center;
        scoreText.font = GetAntonFont();
        scoreText.raycastTarget = false;
    }
    
    private Sprite CreateCircleSprite(int size)
    {
        Texture2D texture = new Texture2D(size, size, TextureFormat.RGBA32, false);
        Color[] pixels = new Color[size * size];
        
        float radius = size / 2f;
        Vector2 center = new Vector2(radius, radius);
        
        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                float distance = Vector2.Distance(new Vector2(x, y), center);
                pixels[y * size + x] = distance <= radius ? Color.white : Color.clear;
            }
        }
        
        texture.SetPixels(pixels);
        texture.Apply();
        
        return Sprite.Create(texture, new Rect(0, 0, size, size), new Vector2(0.5f, 0.5f), 100f);
    }
    
    private IEnumerator LoadImageSprite(string url, Image targetImage)
    {
        Debug.Log($"[ScoresTab] 🖼️ Chargement d'image depuis: {url}");
        
        using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(url))
        {
            yield return request.SendWebRequest();
            
            if (request.result == UnityWebRequest.Result.Success)
            {
                Texture2D texture = DownloadHandlerTexture.GetContent(request);
                if (texture != null)
                {
                    Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100f);
                    TrackDynamic(texture, sprite);
                    
                    if (targetImage != null)
                    {
                        targetImage.sprite = sprite;
                        Debug.Log($"[ScoresTab] ✅ Image chargée avec succès ({texture.width}x{texture.height})");
                    }
                    else
                    {
                        Debug.LogWarning("[ScoresTab] ⚠️ targetImage est null");
                    }
                }
                else
                {
                    Debug.LogError("[ScoresTab] ❌ texture est null après GetContent");
                }
            }
            else
            {
                Debug.LogWarning($"[ScoresTab] ⚠️ Erreur de chargement de l'image: {url} - {request.error}");
            }
        }
    }
    
    private IEnumerator LoadUserData()
    {
        string baseUrl = generalConfig?.apiUrls?.baseUrl ?? "https://www.newsassurancespro.com";
        string url = $"{baseUrl}/api/ujsa/user";
        
        Debug.Log($"[ScoresTab] 👤 Chargement des données utilisateur depuis: {url}");
        
        using (UnityWebRequest www = UnityWebRequest.Get(url))
        {
            // Ajouter le token Bearer
            string token = UserDataManager.Instance != null ? UserDataManager.Instance.token : PlayerPrefs.GetString("userToken", "");
            if (!string.IsNullOrEmpty(token))
            {
                www.SetRequestHeader("Authorization", $"Bearer {token}");
            }
            
            yield return www.SendWebRequest();
            
            if (www.result == UnityWebRequest.Result.Success)
            {
                string json = www.downloadHandler.text;
                UserApiResponse response = JsonUtility.FromJson<UserApiResponse>(json);
                
                if (response != null && response.status == "success" && response.data != null)
                {
                    ProcessUserData(response.data);
                }
            }
            else
            {
                Debug.LogWarning($"[ScoresTab] ⚠️ Erreur de chargement des données utilisateur: {www.error}");
            }
        }
    }
    
    private void ProcessUserData(UserData userData)
    {
        if (userData.super_badges != null && userData.super_badges.Count > 0)
        {
            // Récupérer le super-badge du projet actuel
            string projectSlug = generalConfig?.slug ?? "ujsa-default";
            currentSuperBadge = userData.super_badges.Find(sb => sb.project_slug == projectSlug);
            
            if (currentSuperBadge != null)
            {
                Debug.Log($"[ScoresTab] 🏆 Super-badge trouvé: {currentSuperBadge.score}%");
                UpdateSuperBadgeDisplay();
            }
        }
    }
    
    private void UpdateSuperBadgeDisplay()
    {
        if (currentSuperBadge == null || rightSection == null) return;
        
        // Trouver la section du super-badge
        Transform superBadgeSection = rightSection.transform.Find("SuperBadgeSection");
        if (superBadgeSection == null) return;
        
        // Mettre à jour l'image
        Transform badgeImageObj = superBadgeSection.Find("SuperBadgeImage");
        if (badgeImageObj != null)
        {
            Image badgeImage = badgeImageObj.GetComponent<Image>();
            if (badgeImage != null && !string.IsNullOrEmpty(currentSuperBadge.badge_url))
            {
                // Ajouter à la liste d'attente ou charger directement
                if (gameObject.activeInHierarchy)
                {
                    StartCoroutine(LoadImageFromUrl(currentSuperBadge.badge_url, badgeImage, true));
                }
                else
                {
                    pendingImageLoads.Add(new PendingImageLoad 
                    { 
                        image = badgeImage, 
                        url = currentSuperBadge.badge_url, 
                        needsCanvasGroupReveal = true 
                    });
                }
            }
        }
        
        // Mettre à jour le score
        Transform scoreObj = superBadgeSection.Find("SuperBadgeScore");
        if (scoreObj != null)
        {
            TextMeshProUGUI scoreText = scoreObj.GetComponent<TextMeshProUGUI>();
            if (scoreText != null)
            {
                scoreText.text = $"{currentSuperBadge.score}%";
            }
        }
    }
    
    private void NavigateBadges(int direction)
    {
        int maxVisibleBadges = config?.rightSection?.badges?.maxVisibleBadges ?? 3;
        
        currentBadgeIndex += direction * maxVisibleBadges;
        currentBadgeIndex = Mathf.Clamp(currentBadgeIndex, 0, Mathf.Max(0, unlockedBadges.Count - maxVisibleBadges));
        
        Debug.Log($"[ScoresTab] 🔄 Navigation badges: index = {currentBadgeIndex}");
        
        PopulateBadges();
    }
    
    private void UpdateNavigationArrows()
    {
        int maxVisibleBadges = config?.rightSection?.badges?.maxVisibleBadges ?? 3;
        
        // Désactiver la flèche gauche si on est au début
        if (leftArrow != null)
        {
            leftArrow.SetActive(currentBadgeIndex > 0);
        }
        
        // Désactiver la flèche droite si on est à la fin
        if (rightArrow != null)
        {
            rightArrow.SetActive(currentBadgeIndex + maxVisibleBadges < unlockedBadges.Count);
        }
    }
    
    
    private Color HexToColor(string hex)
    {
        if (string.IsNullOrEmpty(hex)) return Color.white;
        
        hex = hex.Replace("#", "");
        
        if (hex.Length == 6)
        {
            hex += "FF";
        }
        
        if (hex.Length == 8)
        {
            byte r = System.Convert.ToByte(hex.Substring(0, 2), 16);
            byte g = System.Convert.ToByte(hex.Substring(2, 2), 16);
            byte b = System.Convert.ToByte(hex.Substring(4, 2), 16);
            byte a = System.Convert.ToByte(hex.Substring(6, 2), 16);
            
            return new Color32(r, g, b, a);
        }
        
        return Color.white;
    }
    
    private Sprite CreateRoundedSprite(int width, int height, float radius, Color fillColor)
    {
        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;
                
                // Coins arrondis
                if (x < radius && y > height - radius)
                {
                    float dx = radius - x;
                    float dy = (height - radius) - y;
                    float distance = Mathf.Sqrt(dx * dx + dy * dy);
                    if (distance > radius) alpha = 0f;
                }
                else if (x > width - radius && y > height - radius)
                {
                    float dx = x - (width - radius);
                    float dy = (height - radius) - y;
                    float distance = Mathf.Sqrt(dx * dx + dy * dy);
                    if (distance > radius) alpha = 0f;
                }
                else if (x < radius && y < radius)
                {
                    float dx = radius - x;
                    float dy = radius - y;
                    float distance = Mathf.Sqrt(dx * dx + dy * dy);
                    if (distance > radius) alpha = 0f;
                }
                else if (x > width - radius && y < radius)
                {
                    float dx = x - (width - radius);
                    float dy = radius - y;
                    float distance = Mathf.Sqrt(dx * dx + dy * dy);
                    if (distance > radius) alpha = 0f;
                }
                
                pixels[y * width + x] = new Color(fillColor.r, fillColor.g, fillColor.b, fillColor.a * alpha);
            }
        }
        
        texture.SetPixels(pixels);
        texture.Apply();
        
        Sprite sprite = Sprite.Create(texture, new Rect(0, 0, width, height), new Vector2(0.5f, 0.5f), 100f);
        TrackDynamic(texture, sprite);
        
        return sprite;
    }
}

// ========== Classes de données ==========

[System.Serializable]
public class BadgeData
{
    public int questId;
    public string questTitle;
    public string difficulty;
    public int score;
    public int completion;
    public string badgeUrl;
}

[System.Serializable]
public class MainSceneApiResponse
{
    public string status;
    public string message;
    public MainSceneData data;
}

[System.Serializable]
public class MainSceneData
{
    public List<Quest> quests;
}
