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

/// <summary>
/// Gestionnaire commun pour créer et gérer le header dans toutes les scènes
/// </summary>
public class HeaderManager : MonoBehaviour
{
    private static HeaderManager _instance;
    public static HeaderManager Instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject obj = new GameObject("HeaderManager");
                _instance = obj.AddComponent<HeaderManager>();
                DontDestroyOnLoad(obj);
            }
            return _instance;
        }
    }

    private GameObject headerPanel;
    private System.Action<string> onHeaderElementClick;

    // Permet de masquer/afficher le bouton Options (RightElement) même si le header est recréé
    private bool optionsButtonVisible = true;

    /// <summary>
    /// Masque/Affiche le bouton Options (roue dentée) dans le header.
    /// Implémenté via le GameObject "RightElement".
    /// </summary>
    public void SetOptionsButtonVisible(bool visible)
    {
        optionsButtonVisible = visible;
        ApplyOptionsButtonVisibility();
    }

    private void ApplyOptionsButtonVisibility()
    {
        if (headerPanel == null) return;
        Transform right = headerPanel.transform.Find("RightElement");
        if (right != null)
        {
            right.gameObject.SetActive(optionsButtonVisible);
        }
    }

    // Empêche les animations d'apparition de la fleur (Map/LeftElement) de se chevaucher,
    // ce qui peut "capturer" une scale déjà gonflée et laisser la fleur trop grande au step suivant.
    private Coroutine mapFlowerAppearanceCoroutine;

    // Cache simple des sprites du header (évite re-téléchargements + fuites en WebGL)
    private readonly Dictionary<string, Sprite> spriteCache = new Dictionary<string, Sprite>();
    private readonly Dictionary<string, Texture2D> textureCache = new Dictionary<string, Texture2D>();
    
    // Logs verbeux désactivés en production
    // (static readonly pour éviter CS0162 "unreachable code detected" quand le compilateur voit une constante)
    private static readonly bool VERBOSE_DEBUG = false;
    [System.Diagnostics.Conditional("UNITY_EDITOR")]
    private void LogVerbose(string message) { if (VERBOSE_DEBUG) Debug.Log(message); }
    
    /// <summary>
    /// Configure le callback pour les clics sur les éléments du header (utilisé pour les headers personnalisés)
    /// </summary>
    public void SetHeaderElementClickCallback(System.Action<string> callback)
    {
        onHeaderElementClick = callback;
    }
    
    /// <summary>
    /// Masque le header (utilisé pendant les vidéos plein écran)
    /// </summary>
    public void HideHeader()
    {
        if (headerPanel != null)
        {
            headerPanel.SetActive(false);
            LogVerbose("[HeaderManager] Header masqué");
        }
    }
    
    /// <summary>
    /// Affiche le header (après une vidéo plein écran)
    /// </summary>
    public void ShowHeader()
    {
        // Ne pas réafficher le header si une vidéo plein écran est en cours
        MapManager mapManager = FindFirstObjectByType<MapManager>();
        if (mapManager != null && mapManager.IsFullscreenVideoPlaying())
        {
            LogVerbose("[HeaderManager] Tentative d'affichage du header bloquée - vidéo plein écran en cours");
            return;
        }
        
        if (headerPanel != null)
        {
            headerPanel.SetActive(true);
            LogVerbose("[HeaderManager] Header affiché");
        }
    }

    void Awake()
    {
        if (_instance == null)
        {
            _instance = this;
            DontDestroyOnLoad(gameObject);

            // ✅ Point de nettoyage global: sur changement de scène, on peut purger une partie du cache
            // pour éviter l'accumulation en WebGL (on garde un cache simple, sans LRU).
            CleanupPoints.Instance?.RegisterOnSceneChange("HeaderManager", () =>
            {
                // Le header peut changer d'icônes selon les scènes/steps.
                // Purge conservatrice: si le cache grossit trop, on libère.
                if (spriteCache.Count > 32)
                {
                    foreach (var sp in spriteCache.Values)
                        if (sp != null) Destroy(sp);
                    foreach (var tex in textureCache.Values)
                        if (tex != null) Destroy(tex);
                    spriteCache.Clear();
                    textureCache.Clear();
                }
            });
        }
        else if (_instance != this)
        {
            Destroy(gameObject);
        }
    }

    private void OnDestroy()
    {
        if (_instance == this)
        {
            try { CleanupPoints.GetExisting()?.UnregisterOnSceneChange("HeaderManager"); } catch { }
        }
    }

    /// <summary>
    /// Crée le header dans la scène actuelle en utilisant la configuration depuis general-config.json
    /// </summary>
    public IEnumerator CreateHeader(Canvas canvas, System.Action<string> onClickCallback = null)
    {
        if (canvas == null)
        {
            Debug.LogError("[HeaderManager] Canvas introuvable pour créer le header");
            yield break;
        }

        onHeaderElementClick = onClickCallback;

        // S'assurer qu'un EventSystem existe pour les interactions du header
        EnsureEventSystem();

        // Obtenir la configuration depuis general-config.json
        DefaultHeaderConfig headerConfig = GeneralConfigManager.Instance.GetDefaultHeaderConfig();
        
        if (headerConfig == null || !headerConfig.show)
        {
            LogVerbose("[HeaderManager] Header désactivé dans la configuration");
            yield break;
        }

        // Détecter la scène actuelle
        string currentSceneName = SceneManager.GetActiveScene().name;
        LogVerbose($"[HeaderManager] Scène actuelle: {currentSceneName}");

        LogVerbose($"[HeaderManager] Création du header - Canvas: {canvas.name}");

        // Détruire l'ancien header s'il existe
        if (headerPanel != null)
        {
            Destroy(headerPanel);
        }

        headerPanel = new GameObject("HeaderPanel");
        headerPanel.transform.SetParent(canvas.transform, false);
        // S'assurer que le header est au-dessus du reste (raycasts inclus), surtout sur Map où des UI full-screen
        // peuvent intercepter les clics (ScrollRect/background).
        headerPanel.transform.SetAsLastSibling();

        // RectTransform (UI) : Unity peut déjà l'ajouter automatiquement dès qu'on ajoute un Canvas.
        // => ne jamais AddComponent sans vérifier, sinon exception et header invisible.
        RectTransform headerRect = headerPanel.GetComponent<RectTransform>();
        if (headerRect == null) headerRect = headerPanel.AddComponent<RectTransform>();

        // Canvas dédié au header pour prioriser le tri / raycasts
        Canvas headerCanvas = headerPanel.GetComponent<Canvas>();
        if (headerCanvas == null) headerCanvas = headerPanel.AddComponent<Canvas>();
        headerCanvas.overrideSorting = true;
        headerCanvas.sortingOrder = 5000;
        if (headerPanel.GetComponent<GraphicRaycaster>() == null)
        {
            headerPanel.AddComponent<GraphicRaycaster>();
        }
        headerRect.anchorMin = new Vector2(0f, 1f);
        headerRect.anchorMax = new Vector2(1f, 1f);
        headerRect.pivot = new Vector2(0.5f, 1f);
        headerRect.sizeDelta = new Vector2(0f, headerConfig.height);
        headerRect.anchoredPosition = Vector2.zero;

        Image headerBg = headerPanel.AddComponent<Image>();
        if (ColorUtility.TryParseHtmlString(headerConfig.backgroundColor, out Color bgColor))
        {
            headerBg.color = bgColor;
        }
        // IMPORTANT : Ne pas bloquer les raycasts sur le header background pour permettre les clics sur les éléments
        headerBg.raycastTarget = false;

        // Adapter le header selon la scène
        if (currentSceneName == "main")
        {
            // Scène main : seulement rightElement (settings)
            LogVerbose("[HeaderManager] Scène 'main' détectée - Affichage uniquement du rightElement");
            if (headerConfig.rightElement != null)
            {
                yield return StartCoroutine(CreateHeaderElement(headerConfig.rightElement, "RightElement", false));
            }
        }
        else if (currentSceneName == "Map")
        {
            // Scène Map : rightElement + leftElement avec fleur dynamique basée sur le step
            LogVerbose("[HeaderManager] Scène 'Map' détectée - Affichage du rightElement et leftElement avec fleur dynamique");
            
            // Créer l'élément de droite (settings)
            if (headerConfig.rightElement != null)
            {
                yield return StartCoroutine(CreateHeaderElement(headerConfig.rightElement, "RightElement", false));
            }

            // 🔧 NOUVEAU : Créer l'élément de gauche avec la fleur appropriée (fleur_XX.png selon le step)
            if (headerConfig.leftElement != null)
            {
                // Obtenir le numéro de step depuis MapManager
                MapManager mapManager = FindFirstObjectByType<MapManager>();
                int stepNumber = 1; // Par défaut step 1
                
                if (mapManager != null)
                {
                    // Obtenir le numéro du step actuel (sans compter l'intro)
                    stepNumber = mapManager.GetCurrentStepNumber();
                    LogVerbose($"[HeaderManager] Numéro de step calculé: {stepNumber}");
                }
                else
                {
                    Debug.LogWarning("[HeaderManager] MapManager introuvable, utilisation du step 1 par défaut");
                }

                // Construire l'URL de la fleur selon le step (fleur_01.png, fleur_02.png, etc.)
                string fleurImageUrl = $"fleur_{stepNumber:D2}.png";

                // Créer une copie de leftElement avec l'URL de fleur appropriée
                DefaultHeaderElement leftElementWithFleur = new DefaultHeaderElement
                {
                    imageUrl = fleurImageUrl,
                    position = headerConfig.leftElement.position,
                    size = headerConfig.leftElement.size,
                    clickable = headerConfig.leftElement.clickable,
                    targetAction = headerConfig.leftElement.targetAction
                };

                yield return StartCoroutine(CreateHeaderElement(leftElementWithFleur, "LeftElement", true));
            }
        }
        else
        {
            // Autres scènes : comportement par défaut (leftElement + rightElement)
            LogVerbose($"[HeaderManager] Scène '{currentSceneName}' - Comportement par défaut");

        // Créer l'élément de gauche
        if (headerConfig.leftElement != null)
        {
            yield return StartCoroutine(CreateHeaderElement(headerConfig.leftElement, "LeftElement", true));
        }

        // Créer l'élément de droite
        if (headerConfig.rightElement != null)
        {
            yield return StartCoroutine(CreateHeaderElement(headerConfig.rightElement, "RightElement", false));
            }
        }

        LogVerbose("[HeaderManager] Header créé avec succès");

        // Appliquer l'état courant (utile si on a masqué le bouton Options pendant une modale/panel)
        ApplyOptionsButtonVisibility();
        
        // Si une vidéo plein écran est en cours, masquer le header immédiatement
        MapManager videoCheckManager = FindFirstObjectByType<MapManager>();
        if (videoCheckManager != null && videoCheckManager.IsFullscreenVideoPlaying())
        {
            LogVerbose("[HeaderManager] Vidéo plein écran détectée - Masquage du header après création");
            HideHeader();
        }
    }

    IEnumerator CreateHeaderElement(DefaultHeaderElement elementData, string name, bool isLeft)
    {
        GameObject elementObj = new GameObject(name);
        elementObj.transform.SetParent(headerPanel.transform, false);

        RectTransform rt = elementObj.AddComponent<RectTransform>();

        if (isLeft)
        {
            rt.anchorMin = new Vector2(0f, 1f);
            rt.anchorMax = new Vector2(0f, 1f);
            rt.pivot = new Vector2(0f, 1f);
        }
        else
        {
            rt.anchorMin = new Vector2(1f, 1f);
            rt.anchorMax = new Vector2(1f, 1f);
            rt.pivot = new Vector2(1f, 1f);
        }

        rt.anchoredPosition = elementData.position;
        rt.sizeDelta = elementData.size;

        // Map: taille de la fleur (LeftElement, fleur_XX.png)
        bool isMapFleurElement =
            SceneManager.GetActiveScene().name == "Map" &&
            name == "LeftElement" &&
            !string.IsNullOrEmpty(elementData.imageUrl) &&
            elementData.imageUrl.StartsWith("fleur_");
        if (isMapFleurElement)
        {
            // Ne plus forcer ÷2 : l'utilisateur veut revenir à la taille normale (config).
            rt.sizeDelta = elementData.size;
            // S'assurer que la scale de base est saine dès la création (sinon l'anim peut partir d'une scale incorrecte).
            rt.localScale = Vector3.one;
        }

        Image img = elementObj.AddComponent<Image>();
        img.raycastTarget = elementData.clickable;

        // Évite le "flash" blanc : tant que le sprite distant n'est pas chargé,
        // Unity rend l'Image en blanc par défaut (sprite null).
        // On masque donc l'élément via CanvasGroup jusqu'à assignation du sprite.
        CanvasGroup cg = elementObj.GetComponent<CanvasGroup>();
        if (cg == null) cg = elementObj.AddComponent<CanvasGroup>();
        bool hasRemoteImage = !string.IsNullOrEmpty(elementData.imageUrl);
        if (hasRemoteImage)
        {
            cg.alpha = 0f;
            cg.blocksRaycasts = false;
            cg.interactable = false;
        }
        else
        {
            cg.alpha = 1f;
            cg.blocksRaycasts = elementData.clickable;
            cg.interactable = elementData.clickable;
        }

        // S'assurer que le Canvas parent a un GraphicRaycaster
        Canvas parentCanvas = headerPanel.GetComponentInParent<Canvas>();
        if (parentCanvas != null && parentCanvas.GetComponent<GraphicRaycaster>() == null)
        {
            parentCanvas.gameObject.AddComponent<GraphicRaycaster>();
            LogVerbose("[HeaderManager] GraphicRaycaster ajouté au Canvas");
        }

        HeaderElementUI headerElement = elementObj.AddComponent<HeaderElementUI>();
        headerElement.Initialize(elementData, this);

        if (!string.IsNullOrEmpty(elementData.imageUrl))
        {
            // Sur la scène Map, la fleur (LeftElement) doit aussi avoir l'effet à la 1ère apparition (chargement de la scène).
            bool shouldAnimateOnLoad =
                SceneManager.GetActiveScene().name == "Map" &&
                name == "LeftElement" &&
                elementData.imageUrl.StartsWith("fleur_");

            yield return StartCoroutine(LoadOrGetHeaderSprite(elementData.imageUrl, (sprite) =>
            {
                if (sprite != null)
                {
                    headerElement.SetSprite(sprite);
                    // Rendre visible uniquement quand le sprite est prêt (supprime le carré blanc)
                    cg.alpha = 1f;
                    cg.blocksRaycasts = elementData.clickable;
                    cg.interactable = elementData.clickable;
                    LogVerbose($"[HeaderManager] ✅ Image header assignée: {elementData.imageUrl}");

                    if (shouldAnimateOnLoad)
                    {
                        RestartMapFlowerAppearanceAnimation(elementObj);
                    }
                }
                else
                {
                    // En cas d'échec de chargement, rester masqué plutôt que d'afficher un placeholder blanc.
                    cg.alpha = 0f;
                    cg.blocksRaycasts = false;
                    cg.interactable = false;
                }
            }));
        }
    }

    /// <summary>
    /// Met à jour la fleur (LeftElement) dans la scène Map selon l'avancement courant.
    /// Appelée par MapManager lors des changements de step.
    /// 🔧 NOUVEAU : Applique un effet d'apparition (fade in + scale 2x → 1x)
    /// </summary>
    public void RefreshMapJauge()
    {
        if (headerPanel == null) return;
        if (SceneManager.GetActiveScene().name != "Map") return;

        DefaultHeaderConfig headerConfig = GeneralConfigManager.Instance.GetDefaultHeaderConfig();
        if (headerConfig?.leftElement == null) return;

        MapManager mapManager = FindFirstObjectByType<MapManager>();
        int stepNumber = 1;
        if (mapManager != null)
        {
            stepNumber = mapManager.GetCurrentStepNumber();
        }

        // Construire l'URL de la fleur selon le step (fleur_01.png, fleur_02.png, etc.)
        string imageUrl = $"fleur_{stepNumber:D2}.png";

        Transform left = headerPanel.transform.Find("LeftElement");
        if (left == null) return;

        HeaderElementUI ui = left.GetComponent<HeaderElementUI>();
        if (ui == null) return;

        // Assurer la même taille (config) même lors des refresh de step.
        RectTransform leftRt = left.GetComponent<RectTransform>();
        if (leftRt != null)
        {
            leftRt.sizeDelta = headerConfig.leftElement.size;
        }

        // Si aucune fleur n'est actuellement affichée, masquer l'élément pendant le téléchargement
        // pour éviter le rectangle blanc (sprite null).
        CanvasGroup cg = left.GetComponent<CanvasGroup>();
        if (cg == null) cg = left.gameObject.AddComponent<CanvasGroup>();
        Image currentImg = left.GetComponent<Image>();
        if (currentImg != null && currentImg.sprite == null)
        {
            cg.alpha = 0f;
            cg.blocksRaycasts = false;
            cg.interactable = false;
        }

        StartCoroutine(LoadOrGetHeaderSprite(imageUrl, (sprite) =>
        {
            if (sprite != null)
            {
                ui.SetSprite(sprite);
                // Rendre visible maintenant que le sprite est prêt, puis animer l'apparition.
                cg.alpha = 1f;
                cg.blocksRaycasts = headerConfig.leftElement.clickable;
                cg.interactable = headerConfig.leftElement.clickable;
                // 🔧 Appliquer l'effet d'apparition
                RestartMapFlowerAppearanceAnimation(left.gameObject);
            }
        }));
    }

    /// <summary>
    /// Redémarre l'animation d'apparition de la fleur en garantissant une scale de base stable.
    /// (Sinon, si une animation démarre pendant une autre, la fleur peut rester à une scale > 1.)
    /// </summary>
    private void RestartMapFlowerAppearanceAnimation(GameObject flowerObj)
    {
        if (flowerObj == null) return;

        // Stopper l'anim précédente si elle tourne encore (cas step change rapide)
        if (mapFlowerAppearanceCoroutine != null)
        {
            StopCoroutine(mapFlowerAppearanceCoroutine);
            mapFlowerAppearanceCoroutine = null;
        }

        // Revenir à une base stable avant de relancer (respecte la taille "normale" du 1er step)
        RectTransform rt = flowerObj.GetComponent<RectTransform>();
        if (rt != null)
        {
            rt.localScale = Vector3.one;
        }

        mapFlowerAppearanceCoroutine = StartCoroutine(AnimateFlowerAppearance(flowerObj));
    }

    /// <summary>
    /// Coroutine pour animer l'apparition de la fleur :
    /// - Fade in (alpha 0 → 1)
    /// - Scale (2x → 1x)
    /// </summary>
    private IEnumerator AnimateFlowerAppearance(GameObject flowerObj)
    {
        if (flowerObj == null) yield break;

        Image img = flowerObj.GetComponent<Image>();
        RectTransform rt = flowerObj.GetComponent<RectTransform>();
        if (img == null || rt == null) yield break;

        // Démarrer avec alpha 0 et scale 2x
        Color startColor = img.color;
        startColor.a = 0f;
        img.color = startColor;
        
        Vector3 originalScale = rt.localScale;
        rt.localScale = originalScale * 2f;

        // Animation sur 0.5 secondes
        float duration = 0.5f;
        float elapsed = 0f;

        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            float t = elapsed / duration;

            // Fade in
            Color newColor = img.color;
            newColor.a = Mathf.Lerp(0f, 1f, t);
            img.color = newColor;

            // Scale down
            rt.localScale = Vector3.Lerp(originalScale * 2f, originalScale, t);

            yield return null;
        }

        // S'assurer que les valeurs finales sont exactes
        Color finalColor = img.color;
        finalColor.a = 1f;
        img.color = finalColor;
        rt.localScale = originalScale;
    }

    private IEnumerator LoadOrGetHeaderSprite(string imageUrl, System.Action<Sprite> onLoaded)
    {
        if (string.IsNullOrEmpty(imageUrl))
        {
            onLoaded?.Invoke(null);
            yield break;
        }

        if (spriteCache.TryGetValue(imageUrl, out Sprite cached) && cached != null)
        {
            onLoaded?.Invoke(cached);
            yield break;
        }

        string fullImageUrl = GeneralConfigManager.Instance.GetUIUrl(imageUrl);
        LogVerbose($"[HeaderManager] Chargement image header (cache miss): {fullImageUrl}");

        using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(fullImageUrl))
        {
            yield return www.SendWebRequest();

            if (www.result == UnityWebRequest.Result.Success)
            {
                Texture2D texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
                Sprite sprite = Sprite.Create(texture,
                    new Rect(0, 0, texture.width, texture.height),
                    new Vector2(0.5f, 0.5f));

                textureCache[imageUrl] = texture;
                spriteCache[imageUrl] = sprite;
                onLoaded?.Invoke(sprite);
            }
            else
            {
                Debug.LogError($"[HeaderManager] ❌ Erreur chargement image header: {www.error} (URL: {fullImageUrl})");
                onLoaded?.Invoke(null);
            }
        }
    }

    /// <summary>
    /// Appelé quand un élément du header est cliqué
    /// </summary>
    public void OnHeaderElementClick(string action)
    {
        LogVerbose($"[HeaderManager] OnHeaderElementClick appelé avec action: {action}");
        LogVerbose($"[HeaderManager] Callback disponible: {onHeaderElementClick != null}");
        
        if (onHeaderElementClick != null)
        {
            onHeaderElementClick.Invoke(action);
        }
        else
        {
            Debug.LogError("[HeaderManager] Aucun callback défini pour OnHeaderElementClick !");
        }
    }

    /// <summary>
    /// S'assure qu'un EventSystem existe pour les interactions UI
    /// </summary>
    private void EnsureEventSystem()
    {
        // Vérifier si un EventSystem existe et est actif
        UnityEngine.EventSystems.EventSystem eventSystem = UnityEngine.EventSystems.EventSystem.current;
        
        if (eventSystem == null || !eventSystem.enabled)
        {
            // Chercher un EventSystem existant mais désactivé
            eventSystem = FindFirstObjectByType<UnityEngine.EventSystems.EventSystem>();
            
            if (eventSystem != null && !eventSystem.enabled)
            {
                // Réactiver l'EventSystem existant
                eventSystem.enabled = true;
                LogVerbose("[HeaderManager] ✅ EventSystem existant réactivé");
            }
            else if (eventSystem == null)
            {
                // Créer un nouvel EventSystem
                GameObject eventSystemObj = new GameObject("EventSystem");
                eventSystem = eventSystemObj.AddComponent<UnityEngine.EventSystems.EventSystem>();
                LogVerbose("[HeaderManager] ✅ Nouvel EventSystem créé");
            }
        }
        else
        {
            LogVerbose("[HeaderManager] ✅ EventSystem actif trouvé");
        }
        
        // S'assurer qu'il y a un InputSystemUIInputModule (compatible avec le nouveau Input System)
        if (eventSystem != null)
        {
            var inputModule = eventSystem.GetComponent<UnityEngine.InputSystem.UI.InputSystemUIInputModule>();
            if (inputModule == null)
            {
                // Vérifier s'il y a un StandaloneInputModule (à supprimer)
                var standaloneModule = eventSystem.GetComponent<UnityEngine.EventSystems.StandaloneInputModule>();
                if (standaloneModule != null)
                {
                    standaloneModule.enabled = false;
                    Destroy(standaloneModule);
                    LogVerbose("[HeaderManager] ⚠️ StandaloneInputModule supprimé");
                }
                
                // Ajouter InputSystemUIInputModule
                eventSystem.gameObject.AddComponent<UnityEngine.InputSystem.UI.InputSystemUIInputModule>();
                LogVerbose("[HeaderManager] ✅ InputSystemUIInputModule ajouté");
            }
            else
            {
                LogVerbose("[HeaderManager] ✅ InputSystemUIInputModule déjà présent");
            }
            
            // Vérifier que l'EventSystem est bien actif
            LogVerbose($"[HeaderManager] EventSystem status - enabled: {eventSystem.enabled}, gameObject.activeInHierarchy: {eventSystem.gameObject.activeInHierarchy}");
        }
        else
        {
            Debug.LogError("[HeaderManager] ❌ EventSystem est null après création !");
        }
    }

    /// <summary>
    /// Détruit le header actuel
    /// </summary>
    public void DestroyHeader()
    {
        if (headerPanel != null)
        {
            Destroy(headerPanel);
            headerPanel = null;
        }
    }
}

/// <summary>
/// Composant UI pour un élément du header
/// </summary>
public class HeaderElementUI : MonoBehaviour
{
    private DefaultHeaderElement elementData;
    private HeaderManager headerManager;
    private RectTransform rectTransform;
    private Image image;
    private Button button;
    private int _lastClickFrame = -1;

    public void Initialize(DefaultHeaderElement data, HeaderManager manager)
    {
        elementData = data;
        headerManager = manager;
        rectTransform = GetComponent<RectTransform>();
        image = GetComponent<Image>();

        if (data.clickable)
        {
            // S'assurer que l'image peut recevoir les raycasts
            if (image != null)
            {
                image.raycastTarget = true;
            }

            // Ajouter un Button
            button = gameObject.AddComponent<Button>();
            button.transition = Selectable.Transition.ColorTint;
            button.targetGraphic = image;
            button.interactable = true;

            ColorBlock colors = button.colors;
            colors.normalColor = Color.white;
            colors.highlightedColor = new Color(0.9f, 0.9f, 0.9f, 1f);
            colors.pressedColor = new Color(0.7f, 0.7f, 0.7f, 1f);
            button.colors = colors;

            button.onClick.AddListener(OnClick);
            // Debug verbeux désactivé: $"[HeaderElementUI] Button créé pour action: {data.targetAction}");

            // Ajouter aussi un EventTrigger comme fallback
            UnityEngine.EventSystems.EventTrigger eventTrigger = gameObject.GetComponent<UnityEngine.EventSystems.EventTrigger>();
            if (eventTrigger == null)
            {
                eventTrigger = gameObject.AddComponent<UnityEngine.EventSystems.EventTrigger>();
            }

            // Ajouter un listener pour PointerClick
            UnityEngine.EventSystems.EventTrigger.Entry clickEntry = new UnityEngine.EventSystems.EventTrigger.Entry();
            clickEntry.eventID = UnityEngine.EventSystems.EventTriggerType.PointerClick;
            clickEntry.callback.AddListener((eventData) => {
                // Debug verbeux désactivé: $"[HeaderElementUI] EventTrigger PointerClick détecté pour action: {data.targetAction}");
                OnClick();
            });
            eventTrigger.triggers.Add(clickEntry);

            // Debug verbeux désactivé: $"[HeaderElementUI] EventTrigger ajouté comme fallback pour action: {data.targetAction}");
        }
    }

    void OnClick()
    {
        // Évite les doubles déclenchements : on a un Button ET un EventTrigger PointerClick (fallback),
        // qui peuvent appeler OnClick deux fois sur le même clic (même frame) => effets "toggle" involontaires.
        if (_lastClickFrame == Time.frameCount) return;
        _lastClickFrame = Time.frameCount;

        // Debug verbeux désactivé: $"[HeaderElementUI] OnClick appelé - action: {elementData?.targetAction}");
        if (headerManager != null && elementData != null)
        {
            headerManager.OnHeaderElementClick(elementData.targetAction);
        }
        else
        {
            Debug.LogError($"[HeaderElementUI] headerManager ou elementData est null - headerManager: {headerManager != null}, elementData: {elementData != null}");
        }
    }

    public void SetSprite(Sprite sprite)
    {
        if (image != null)
        {
            image.sprite = sprite;
        }
    }
}

