using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.InputSystem;

/// <summary>
/// Gère l'affichage du viseur personnalisé avec deux états visuels :
/// - Pleine taille et opaque sur les zones cibles
/// - Taille réduite et semi-transparent ailleurs
/// Compatible avec le nouveau Input System de Unity
/// </summary>
public class CrosshairManager : MonoBehaviour
{
    [Header("Configuration du Viseur")]
    public float crosshairSize = 50f; // Taille du viseur en pixels
    public float minSize = 0.5f;
    public float maxSize = 3f;
    
    [Header("Configuration États Visuels")]
    [Tooltip("Taille du viseur quand on survole une zone cible (multiplier de crosshairSize)")]
    public float onTargetSizeMultiplier = 1f; // Taille normale sur zone
    [Tooltip("Taille du viseur quand on ne survole pas de zone (multiplier de crosshairSize)")]
    public float offTargetSizeMultiplier = 0.5f; // Moitié de la taille ailleurs
    [Tooltip("Opacité du viseur sur une zone cible")]
    public float onTargetAlpha = 1f; // Complètement opaque sur zone
    [Tooltip("Opacité du viseur hors zone cible")]
    public float offTargetAlpha = 0.5f; // Semi-transparent ailleurs
    
    [Header("Nouveau comportement")]
    [Tooltip("Si true, le viseur est toujours visible (deux états). Si false, ancien comportement (visible/invisible)")]
    public bool alwaysShowCrosshair = true;
    
    [Header("References")]
    public GameManager gameManagerReference; // Assignez manuellement si FindObjectOfType échoue
    
    [Header("Transition")]
    public float transitionSpeed = 10f; // Vitesse d'apparition/disparition du viseur
    public float sizeTransitionSpeed = 15f; // Vitesse de changement de taille
    public bool smoothTransition = true; // Transition smooth ou instantanée
    
    [Header("Curseur Système")]
    public bool hideSystemCursorDuringGame = true; // Masquer le curseur système pendant le jeu
    public bool showSystemCursorDuringFeedback = true; // Montrer le curseur système pendant feedback
    
    [Header("Debug")]
    public bool showDebugInfo = false;

    // Références privées
    private GameObject crosshairInstance;
    private Image crosshairImage;
    private RectTransform crosshairRect;
    private Canvas parentCanvas;
    private Camera mainCamera;
    private CanvasGroup crosshairCanvasGroup;
    private Vector2 originalSize;
    
    // État du viseur
    private bool isOverTargetZone = false;
    private bool crosshairShouldBeVisible = false;
    private float targetAlpha = 0f;
    private float targetSizeMultiplier = 1f; // NOUVEAU : multiplier de taille cible
    private float currentSizeMultiplier = 1f; // NOUVEAU : multiplier de taille actuel
    private bool feedbackPanelActive = false;
    
    // Références Input System
    private Mouse mouse;
    private Touchscreen touchscreen;
    
    // Référence au GameManager pour accéder aux zones
    private GameManager gameManager;
    
    void Start()
    {
        // Récupérer les références
        mainCamera = Camera.main;
        
        // Priorité à la référence manuelle, sinon essayer FindObjectOfType
        if (gameManagerReference != null)
        {
            gameManager = gameManagerReference;
        }
        else
        {
            gameManager = FindFirstObjectByType<GameManager>();
        }
        
        if (mainCamera == null)
        {
            Debug.LogError("CrosshairManager: Aucune caméra principale trouvée !");
            return;
        }
        
        if (gameManager == null)
        {
            // Vérifier si on est dans un jeu de calculatrice (qui n'a pas besoin de CrosshairManager)
            var calculatorManager = FindFirstObjectByType<CalculatorGameManager>();
            if (calculatorManager != null)
            {
                Debug.Log("CrosshairManager: Scène de calculatrice détectée, désactivation du crosshair et restauration du curseur système");
                Cursor.visible = true;
                Cursor.lockState = CursorLockMode.None;
                gameObject.SetActive(false); // Désactiver complètement ce script
                return;
            }
            
            Debug.LogError("CrosshairManager: GameManager introuvable ! Assignez 'gameManagerReference' manuellement dans l'Inspector.");
            return;
        }
        else
        {
            Debug.Log("CrosshairManager: GameManager trouvé avec succès");
        }
        
        // Initialiser les références Input System
        InitializeInputReferences();
        
        // Créer le viseur (masqué par défaut si mode ancien, visible si nouveau mode)
        CreateCrosshair();
        
        // Configuration initiale selon le mode
        if (alwaysShowCrosshair)
        {
            // Nouveau mode : commencer avec l'état "hors zone"
            targetAlpha = offTargetAlpha;
            targetSizeMultiplier = offTargetSizeMultiplier;
            currentSizeMultiplier = offTargetSizeMultiplier;
            crosshairShouldBeVisible = true;
            
            // Log supprimé
        }
        else
        {
            // Ancien mode : masqué par défaut
            targetAlpha = 0f;
            targetSizeMultiplier = onTargetSizeMultiplier;
            currentSizeMultiplier = onTargetSizeMultiplier;
            crosshairShouldBeVisible = false;
            
            // Log supprimé
        }
        
        // Cacher le curseur système - le crosshair le remplace
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Confined; // Garder dans la fenêtre
        Debug.Log("[CrosshairManager] Curseur système masqué - crosshair actif");
    }
    
    /// <summary>
    /// Initialise les références pour le nouveau Input System
    /// </summary>
    void InitializeInputReferences()
    {
        mouse = Mouse.current;
        touchscreen = Touchscreen.current;
        
        // Logs d'initialisation supprimés pour réduire le bruit en WebGL
    }
    
    void Update()
    {
        if (crosshairInstance == null) 
        {
            // Log une seule fois si le crosshair est null
            if (Time.frameCount % 300 == 0)
            {
                Debug.LogWarning("[CrosshairManager] crosshairInstance est NULL !");
            }
            return;
        }
        
        if (crosshairRect == null)
        {
            if (Time.frameCount % 300 == 0)
            {
                Debug.LogWarning("[CrosshairManager] crosshairRect est NULL !");
            }
            return;
        }
        
        // Vérifier l'état du feedback panel
        UpdateFeedbackPanelState();
        
        // Mettre à jour la position du viseur
        UpdateCrosshairPosition();
        
        // Détecter si on survole une zone cible
        DetectTargetZoneHover();
        
        // Gérer l'affichage du viseur selon l'état
        UpdateCrosshairVisibility();
        
        // NOUVEAU : Gérer les transitions de taille
        UpdateCrosshairSize();
    }
    
    /// <summary>
    /// Récupère la position actuelle de l'input (souris ou tactile)
    /// </summary>
    Vector2 GetCurrentInputPosition()
    {
        // Priorité à la souris si disponible
        if (mouse != null)
        {
            return mouse.position.ReadValue();
        }
        
        // Sinon utiliser le tactile si disponible et pressé
        if (touchscreen != null && touchscreen.primaryTouch.press.isPressed)
        {
            return touchscreen.primaryTouch.position.ReadValue();
        }
        
        // Fallback : position du milieu de l'écran
        return new Vector2(Screen.width / 2f, Screen.height / 2f);
    }
    
    /// <summary>
    /// Crée le GameObject du viseur avec un Canvas dédié
    /// </summary>
    private void CreateCrosshair()
    {
        // Créer un Canvas dédié au crosshair
        GameObject crosshairCanvasObj = new GameObject("CrosshairCanvas");
        parentCanvas = crosshairCanvasObj.AddComponent<Canvas>();
        parentCanvas.renderMode = RenderMode.ScreenSpaceOverlay;
        parentCanvas.sortingOrder = 1000;
        
        // CanvasScaler avec résolution de référence 1920x1080
        CanvasScaler scaler = crosshairCanvasObj.AddComponent<CanvasScaler>();
        scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
        scaler.referenceResolution = new Vector2(1920, 1080);
        scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
        scaler.matchWidthOrHeight = 0.5f;
        
        crosshairCanvasObj.AddComponent<GraphicRaycaster>();
        
        // Créer le GameObject du viseur
        crosshairInstance = new GameObject("Crosshair");
        crosshairInstance.transform.SetParent(crosshairCanvasObj.transform, false);
        
        // Ajouter CanvasGroup pour les transitions smooth
        crosshairCanvasGroup = crosshairInstance.AddComponent<CanvasGroup>();
        crosshairCanvasGroup.alpha = alwaysShowCrosshair ? offTargetAlpha : 0f;
        crosshairCanvasGroup.blocksRaycasts = false;
        
        // Ajouter le composant Image
        crosshairImage = crosshairInstance.AddComponent<Image>();
        crosshairImage.raycastTarget = false;
        crosshairImage.preserveAspect = true;
        
        // Créer un crosshair de fallback
        CreateFallbackCrosshair();
        crosshairImage.color = Color.white;
        
        // Configuration du RectTransform
        crosshairRect = crosshairInstance.GetComponent<RectTransform>();
        crosshairRect.sizeDelta = new Vector2(crosshairSize, crosshairSize);
        crosshairRect.anchorMin = new Vector2(0.5f, 0.5f);
        crosshairRect.anchorMax = new Vector2(0.5f, 0.5f);
        crosshairRect.pivot = new Vector2(0.5f, 0.5f); // Centre sur le curseur
        
        originalSize = crosshairRect.sizeDelta;
        
        Debug.Log("[CrosshairManager] Crosshair créé avec Canvas dédié");
    }
    
    /// <summary>
    /// Gestion de l'état du feedback panel
    /// </summary>
    void UpdateFeedbackPanelState()
    {
        if (gameManager == null) return;
        
        bool currentFeedbackState = gameManager.IsFeedbackPanelActive();
        
        // Si l'état du feedback a changé
        if (currentFeedbackState != feedbackPanelActive)
        {
            feedbackPanelActive = currentFeedbackState;
            
            if (feedbackPanelActive)
            {
                // Feedback affiché : montrer le curseur système
                OnFeedbackPanelShown();
            }
            else
            {
                // Feedback masqué : retour au mode jeu
                OnFeedbackPanelHidden();
            }
        }
        
        // IMPORTANT: Forcer le curseur visible à chaque frame si le feedback est actif
        // pour éviter qu'il disparaisse quand on bouge la souris
        if (feedbackPanelActive && showSystemCursorDuringFeedback)
        {
            Cursor.visible = true;
            Cursor.lockState = CursorLockMode.None;
        }
    }
    
    /// <summary>
    /// Quand le feedback s'affiche
    /// </summary>
    void OnFeedbackPanelShown()
    {
        if (showSystemCursorDuringFeedback)
        {
            Cursor.visible = true;
            Cursor.lockState = CursorLockMode.None; // Libérer le curseur pour cliquer sur les boutons
            Debug.Log("CrosshairManager: Curseur système activé (feedback)");
        }
        
        // Masquer le viseur pendant le feedback
        if (crosshairInstance != null)
        {
            crosshairInstance.SetActive(false);
        }
    }
    
    /// <summary>
    /// Quand le feedback se cache
    /// </summary>
    void OnFeedbackPanelHidden()
    {
        // Cacher le curseur système - le crosshair reprend le contrôle
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Confined; // Confiner dans la fenêtre
        
        // Réactiver le crosshair
        if (crosshairInstance != null)
        {
            crosshairInstance.SetActive(true);
        }
    }
    
    /// <summary>
    /// Détecte si la position actuelle survole une zone cible
    /// </summary>
    void DetectTargetZoneHover()
    {
        Vector2 inputPosition = GetCurrentInputPosition();
        bool wasOverTargetZone = isOverTargetZone;
        isOverTargetZone = false;
        
        // Utiliser la méthode du GameManager pour détecter les zones
        if (gameManager != null)
        {
            isOverTargetZone = gameManager.IsPointOverTargetZone(inputPosition);
        }
        else
        {
            if (showDebugInfo)
            {
                Debug.LogError("CrosshairManager: GameManager reference manquante !");
            }
        }
        
        // Si l'état a changé
        if (isOverTargetZone != wasOverTargetZone)
        {
            OnTargetZoneHoverChanged(isOverTargetZone);
        }
        
        if (showDebugInfo)
        {
            // Log supprimé (trop verbeux)
        }
    }
    
    /// <summary>
    /// Appelé quand l'état de survol des zones cibles change
    /// </summary>
    void OnTargetZoneHoverChanged(bool overTargetZone)
    {
        if (alwaysShowCrosshair)
        {
            // NOUVEAU MODE : Toujours visible, mais changer d'état visuel
            crosshairShouldBeVisible = true; // Toujours visible
            
            if (overTargetZone)
            {
                // Sur zone : pleine taille et opaque
                targetAlpha = onTargetAlpha;
                targetSizeMultiplier = onTargetSizeMultiplier;
            }
            else
            {
                // Hors zone : taille réduite et semi-transparent
                targetAlpha = offTargetAlpha;
                targetSizeMultiplier = offTargetSizeMultiplier;
            }
        }
        else
        {
            // ANCIEN MODE : Visible/invisible selon la zone
            crosshairShouldBeVisible = overTargetZone;
            targetAlpha = crosshairShouldBeVisible ? onTargetAlpha : 0f;
            targetSizeMultiplier = onTargetSizeMultiplier; // Toujours pleine taille quand visible
        }
        
        // Cacher le curseur système - le crosshair est visible
        Cursor.visible = false;
        
        if (showDebugInfo)
        {
            // Log supprimé (trop verbeux)
        }
    }
    
    /// <summary>
    /// Met à jour la visibilité du viseur avec transition smooth
    /// </summary>
    void UpdateCrosshairVisibility()
    {
        if (crosshairCanvasGroup == null || gameManager == null) return;
        
        // Ne pas afficher le viseur pendant le feedback
        if (feedbackPanelActive)
        {
            crosshairCanvasGroup.alpha = 0f;
            return;
        }
        
        if (smoothTransition)
        {
            // Transition smooth
            float currentAlpha = crosshairCanvasGroup.alpha;
            float newAlpha = Mathf.MoveTowards(currentAlpha, targetAlpha, transitionSpeed * Time.deltaTime);
            crosshairCanvasGroup.alpha = newAlpha;
        }
        else
        {
            // Transition instantanée
            crosshairCanvasGroup.alpha = targetAlpha;
        }
    }
    
    /// <summary>
    /// NOUVEAU : Met à jour la taille du viseur avec transition smooth
    /// </summary>
    void UpdateCrosshairSize()
    {
        if (crosshairRect == null || originalSize == Vector2.zero) return;
        
        // Ne pas changer la taille pendant le feedback
        if (feedbackPanelActive) return;
        
        if (smoothTransition)
        {
            // Transition smooth de la taille
            currentSizeMultiplier = Mathf.MoveTowards(currentSizeMultiplier, targetSizeMultiplier, sizeTransitionSpeed * Time.deltaTime);
        }
        else
        {
            // Transition instantanée
            currentSizeMultiplier = targetSizeMultiplier;
        }
        
        // Appliquer la nouvelle taille
        Vector2 newSize = originalSize * currentSizeMultiplier;
        crosshairRect.sizeDelta = newSize;
        
        if (showDebugInfo && Mathf.Abs(currentSizeMultiplier - targetSizeMultiplier) > 0.01f)
        {
            // Log supprimé (trop verbeux)
        }
    }
    
    /// <summary>
    /// Met à jour la position du viseur selon la position de l'input
    /// </summary>
    private void UpdateCrosshairPosition()
    {
        // Récupérer la position de l'input en coordonnées écran
        Vector2 screenPosition = GetCurrentInputPosition();
        
        // Utiliser la résolution de référence du CanvasScaler (1920x1080)
        CanvasScaler scaler = parentCanvas.GetComponent<CanvasScaler>();
        Vector2 referenceResolution;
        
        if (scaler != null && scaler.uiScaleMode == CanvasScaler.ScaleMode.ScaleWithScreenSize)
        {
            referenceResolution = scaler.referenceResolution;
        }
        else
        {
            // Fallback : utiliser la taille de l'écran
            referenceResolution = new Vector2(Screen.width, Screen.height);
        }
        
        // Convertir la position écran (0 à Screen.width/height) vers l'espace Canvas de référence
        // Le crosshair a des ancres au centre (0.5, 0.5), donc (0,0) = centre du Canvas
        float canvasX = (screenPosition.x / Screen.width - 0.5f) * referenceResolution.x;
        float canvasY = (screenPosition.y / Screen.height - 0.5f) * referenceResolution.y;
        
        crosshairRect.anchoredPosition = new Vector2(canvasX, canvasY);
    }
    
    /// <summary>
    /// Charge le sprite du viseur depuis une URL
    /// </summary>
    /// <param name="url">URL du sprite du viseur</param>
    public void LoadCrosshairFromURL(string url)
    {
        if (crosshairImage == null)
        {
            Debug.LogError("CrosshairManager: Image du viseur non initialisée !");
            return;
        }
        
        // Vérifier que l'URL n'est pas vide
        if (string.IsNullOrEmpty(url))
        {
            Debug.LogError($"[CrosshairManager] ❌ URL vide passée à LoadCrosshairFromURL() ! Création d'un fallback.");
            CreateFallbackCrosshair();
            return;
        }
        
        Debug.Log($"[CrosshairManager] ✅ Chargement crosshair depuis URL: '{url}'");
        StartCoroutine(DownloadCrosshairSprite(url));
    }
    
    /// <summary>
    /// Coroutine pour télécharger le sprite du viseur
    /// </summary>
    private IEnumerator DownloadCrosshairSprite(string url)
    {
        Debug.Log($"[CrosshairManager] 📥 Téléchargement du viseur depuis {url}");
        Debug.Log($"[CrosshairManager] Platform: {Application.platform}");
        
        // CORRECTION MAC : Utiliser MacImageLoader au lieu de UnityWebRequest direct
        bool success = false;
        Texture2D texture = null;
        string error = null;
        
        yield return MacImageLoader.LoadTexture(url,
            (loadedTexture) => {
                success = true;
                texture = loadedTexture;
            },
            (errorMsg) => {
                success = false;
                error = errorMsg;
            }
        );
        
        if (success && texture != null)
        {
            Debug.Log($"[CrosshairManager] ✅ Texture reçue: {texture.width}x{texture.height}");
            
            try
            {
                Sprite crosshairSprite = Sprite.Create(
                    texture,
                    new Rect(0, 0, texture.width, texture.height),
                    new Vector2(0.5f, 0.5f),
                    100f
                );
                
                // Appliquer le sprite ET rendre visible
                crosshairImage.sprite = crosshairSprite;
                crosshairImage.color = Color.white;
                
                // Stocker les proportions originales
                float aspectRatio = (float)texture.width / texture.height;
                originalSize = new Vector2(crosshairSize * aspectRatio, crosshairSize);
                
                UpdateCrosshairSizeWithAspect();
                
                Debug.Log($"[CrosshairManager] ✅ Sprite appliqué et rendu visible");
            }
            catch (System.Exception e)
            {
                Debug.LogError($"[CrosshairManager] ❌ Erreur création sprite: {e.Message}");
                CreateFallbackCrosshair();
            }
        }
        else
        {
            Debug.LogError($"[CrosshairManager] ❌ Échec téléchargement: {error}");
            Debug.LogError($"[CrosshairManager] URL: {url}");
            
            #if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
            Debug.LogError("[CrosshairManager] 🍎 PROBLÈME MAC - Création du fallback...");
            #endif
            
            CreateFallbackCrosshair();
        }
    }

    /// <summary>
    /// Met à jour la taille du crosshair en respectant les proportions
    /// </summary>
    private void UpdateCrosshairSizeWithAspect()
    {
        if (crosshairRect != null && originalSize != Vector2.zero)
        {
            float scale = crosshairSize / 50f; // 50f est la taille de référence
            Vector2 newSize = originalSize * scale * currentSizeMultiplier; // MODIFIÉ : inclure le multiplier actuel
            crosshairRect.sizeDelta = newSize;
            
            Debug.Log($"Crosshair redimensionné: {newSize} (échelle: {scale:F2}, multiplier: {currentSizeMultiplier:F2})");
        }
    }
    
    /// <summary>
    /// Crée un viseur de fallback simple - VISIBLE avec contour noir
    /// </summary>
    private void CreateFallbackCrosshair()
    {
        // Créer une texture simple pour le viseur
        Texture2D fallbackTexture = new Texture2D(64, 64);
        Color[] pixels = new Color[64 * 64];
        
        // Remplir avec transparence
        for (int i = 0; i < pixels.Length; i++)
        {
            pixels[i] = Color.clear;
        }
        
        // Dessiner une croix avec contour noir pour meilleure visibilité
        for (int x = 0; x < 64; x++)
        {
            for (int y = 0; y < 64; y++)
            {
                // Contour noir horizontal
                if (y >= 28 && y <= 36 && (x < 26 || x > 38))
                {
                    pixels[y * 64 + x] = new Color(0f, 0f, 0f, 1f); // Noir opaque
                }
                // Contour noir vertical
                if (x >= 28 && x <= 36 && (y < 26 || y > 38))
                {
                    pixels[y * 64 + x] = new Color(0f, 0f, 0f, 1f); // Noir opaque
                }
                
                // Ligne blanche horizontale (intérieur)
                if (y >= 30 && y <= 34 && (x < 28 || x > 36))
                {
                    pixels[y * 64 + x] = new Color(1f, 1f, 1f, 1f); // Blanc opaque
                }
                // Ligne blanche verticale (intérieur)
                if (x >= 30 && x <= 34 && (y < 28 || y > 36))
                {
                    pixels[y * 64 + x] = new Color(1f, 1f, 1f, 1f); // Blanc opaque
                }
                
                // Centre rouge vif
                if ((x >= 28 && x <= 36) && (y >= 28 && y <= 36))
                {
                    pixels[y * 64 + x] = new Color(1f, 0f, 0f, 1f); // Rouge opaque
                }
            }
        }
        
        fallbackTexture.SetPixels(pixels);
        fallbackTexture.Apply();
        
        Sprite fallbackSprite = Sprite.Create(
            fallbackTexture,
            new Rect(0, 0, 64, 64),
            new Vector2(0.5f, 0.5f),
            100f
        );
        
        crosshairImage.sprite = fallbackSprite;
        crosshairImage.color = Color.white; // Rendre visible maintenant
        
        Debug.Log("CrosshairManager: Viseur de fallback créé");
    }
    
    // ========================================
    // MÉTHODES PUBLIQUES
    // ========================================
    
    /// <summary>
    /// Change la taille du viseur
    /// </summary>
    public void SetCrosshairSize(float newSize)
    {
        crosshairSize = Mathf.Clamp(newSize, minSize, maxSize);
        
        // Mettre à jour la taille en respectant les proportions
        UpdateCrosshairSizeWithAspect();
    }
    
    /// <summary>
    /// Change la couleur du viseur
    /// </summary>
    public void SetCrosshairColor(Color color)
    {
        if (crosshairImage != null)
        {
            crosshairImage.color = color;
        }
    }
    
    /// <summary>
    /// Active/désactive les transitions smooth
    /// </summary>
    public void SetSmoothTransition(bool smooth)
    {
        smoothTransition = smooth;
    }
    
    /// <summary>
    /// Change la vitesse de transition d'alpha
    /// </summary>
    public void SetTransitionSpeed(float speed)
    {
        transitionSpeed = speed;
    }
    
    /// <summary>
    /// NOUVEAU : Change la vitesse de transition de taille
    /// </summary>
    public void SetSizeTransitionSpeed(float speed)
    {
        sizeTransitionSpeed = speed;
    }
    
    /// <summary>
    /// NOUVEAU : Configure les multiplieurs de taille
    /// </summary>
    public void SetSizeMultipliers(float onTarget, float offTarget)
    {
        onTargetSizeMultiplier = onTarget;
        offTargetSizeMultiplier = offTarget;
        
        // Mettre à jour l'état actuel si nécessaire
        if (isOverTargetZone)
        {
            targetSizeMultiplier = onTargetSizeMultiplier;
        }
        else
        {
            targetSizeMultiplier = offTargetSizeMultiplier;
        }
        
        Debug.Log($"Multiplieurs de taille mis à jour: Sur zone={onTarget}, Hors zone={offTarget}");
    }
    
    /// <summary>
    /// NOUVEAU : Configure les valeurs d'alpha
    /// </summary>
    public void SetAlphaValues(float onTarget, float offTarget)
    {
        onTargetAlpha = onTarget;
        offTargetAlpha = offTarget;
        
        // Mettre à jour l'état actuel si nécessaire
        if (alwaysShowCrosshair)
        {
            if (isOverTargetZone)
            {
                targetAlpha = onTargetAlpha;
            }
            else
            {
                targetAlpha = offTargetAlpha;
            }
        }
        
        Debug.Log($"Valeurs alpha mises à jour: Sur zone={onTarget}, Hors zone={offTarget}");
    }
    
    /// <summary>
    /// NOUVEAU : Active/désactive le mode double état
    /// </summary>
    public void SetAlwaysShowCrosshair(bool alwaysShow)
    {
        bool wasAlwaysShow = alwaysShowCrosshair;
        alwaysShowCrosshair = alwaysShow;
        
        if (wasAlwaysShow != alwaysShow)
        {
            // Réappliquer l'état selon le nouveau mode
            OnTargetZoneHoverChanged(isOverTargetZone);
            
            Debug.Log($"Mode viseur changé: {(alwaysShow ? "Double état (toujours visible)" : "Conditionnel (visible/invisible)")}");
        }
    }
    
    /// <summary>
    /// Force l'affichage ou le masquage du viseur (pour debug)
    /// </summary>
    public void ForceVisibility(bool visible)
    {
        crosshairShouldBeVisible = visible;
        targetAlpha = visible ? onTargetAlpha : 0f;
        
        if (showDebugInfo)
        {
            Debug.Log($"Viseur forcé: {(visible ? "VISIBLE" : "MASQUÉ")}");
        }
    }
    
    /// <summary>
    /// Vérifie si le viseur est actuellement visible
    /// </summary>
    public bool IsVisible()
    {
        return crosshairCanvasGroup != null && crosshairCanvasGroup.alpha > 0f;
    }
    
    /// <summary>
    /// Vérifie si on survole actuellement une zone cible
    /// </summary>
    public bool IsOverTargetZone()
    {
        return isOverTargetZone;
    }
    
    /// <summary>
    /// Force l'état du curseur système
    /// </summary>
    public void SetSystemCursorVisible(bool visible)
    {
        Cursor.visible = visible;
        Debug.Log($"CrosshairManager: Curseur système forcé à {(visible ? "visible" : "masqué")}");
    }
    
    /// <summary>
    /// Debug complet de l'état du curseur
    /// </summary>
    public void DebugCursorState()
    {
        Debug.Log("=== DEBUG CURSEUR ===");
        Debug.Log($"Mode: {(alwaysShowCrosshair ? "Double état" : "Conditionnel")}");
        Debug.Log($"Curseur système visible: {Cursor.visible}");
        Debug.Log($"Feedback panel actif: {feedbackPanelActive}");
        Debug.Log($"Viseur actif: {(crosshairImage != null ? crosshairImage.gameObject.activeInHierarchy : false)}");
        Debug.Log($"Viseur alpha: {(crosshairCanvasGroup != null ? crosshairCanvasGroup.alpha : -1f)} (cible: {targetAlpha})");
        Debug.Log($"Viseur taille multiplier: {currentSizeMultiplier:F2} (cible: {targetSizeMultiplier:F2})");
        Debug.Log($"Sur zone cible: {isOverTargetZone}");
        Debug.Log($"Multipliers: Sur zone={onTargetSizeMultiplier}, Hors zone={offTargetSizeMultiplier}");
        Debug.Log($"Alpha: Sur zone={onTargetAlpha}, Hors zone={offTargetAlpha}");
        Debug.Log("====================");
    }
    
    void OnDestroy()
    {
        // Restaurer le curseur système
        Cursor.visible = true;
    }
    
    void OnApplicationFocus(bool hasFocus)
    {
        // Restaurer le curseur système si on perd le focus
        if (!hasFocus)
        {
            Cursor.visible = true;
        }
    }

    /// <summary>
    /// Configure le viseur selon les paramètres JSON (compatible avec CrosshairConfig existant)
    /// </summary>
    public void ApplyCrosshairConfig(CrosshairConfig config)
    {
        if (config == null) 
        {
            Debug.LogWarning("Configuration crosshair nulle, utilisation des valeurs par défaut");
            return;
        }
        
        Debug.Log($"=== APPLICATION CONFIG CROSSHAIR ===");
        
        // 1. APPLIQUER LES PROPRIÉTÉS DE BASE (toujours présentes)
        minSize = config.minSize;
        maxSize = config.maxSize;
        SetCrosshairSize(config.defaultSize);
        
        // 2. UTILISER LA RÉFLEXION POUR LES NOUVELLES PROPRIÉTÉS
        System.Type configType = config.GetType();
        
        // Mode d'affichage
        bool useAlwaysShow = GetFieldValue<bool>(config, configType, "alwaysShowCrosshair", true);
        SetAlwaysShowCrosshair(useAlwaysShow);
        
        // Multipliers de taille
        float onTargetSize = GetFieldValue<float>(config, configType, "onTargetSizeMultiplier", 1.0f);
        float offTargetSize = GetFieldValue<float>(config, configType, "offTargetSizeMultiplier", 0.5f);
        SetSizeMultipliers(onTargetSize, offTargetSize);
        
        // Valeurs d'alpha
        float onTargetAlphaValue = GetFieldValue<float>(config, configType, "onTargetAlpha", 1.0f);
        float offTargetAlphaValue = GetFieldValue<float>(config, configType, "offTargetAlpha", 0.6f);
        SetAlphaValues(onTargetAlphaValue, offTargetAlphaValue);
        
        // Vitesses de transition
        float alphaSpeed = GetFieldValue<float>(config, configType, "alphaTransitionSpeed", 10f);
        float sizeSpeed = GetFieldValue<float>(config, configType, "sizeTransitionSpeed", 15f);
        SetTransitionSpeed(alphaSpeed);
        SetSizeTransitionSpeed(sizeSpeed);
        
        // Transitions smooth
        bool smoothTrans = GetFieldValue<bool>(config, configType, "smoothTransitions", true);
        SetSmoothTransition(smoothTrans);
        
        Debug.Log($"Configuration appliquée avec succès :");
        Debug.Log($"  Mode: {(alwaysShowCrosshair ? "Double état" : "Classique")}");
        Debug.Log($"  Taille: {crosshairSize}px (min: {minSize}, max: {maxSize})");
        Debug.Log($"  Multipliers: Sur zone x{onTargetSizeMultiplier:F1}, Hors zone x{offTargetSizeMultiplier:F1}");
        Debug.Log($"  Alpha: Sur zone {onTargetAlpha:F1}, Hors zone {offTargetAlpha:F1}");
        Debug.Log($"  Vitesses: Taille {sizeTransitionSpeed}, Alpha {transitionSpeed}");
        Debug.Log($"=== FIN APPLICATION CONFIG ===");
    }

    /// <summary>
    /// Récupère la valeur d'un champ avec fallback si il n'existe pas
    /// </summary>
    private T GetFieldValue<T>(object obj, System.Type objType, string fieldName, T defaultValue)
    {
        try
        {
            var field = objType.GetField(fieldName);
            if (field != null && field.FieldType == typeof(T))
            {
                T value = (T)field.GetValue(obj);
                Debug.Log($"Propriété {fieldName} trouvée: {value}");
                return value;
            }
            else
            {
                Debug.Log($"Propriété {fieldName} non trouvée, utilisation valeur par défaut: {defaultValue}");
                return defaultValue;
            }
        }
        catch (System.Exception e)
        {
            Debug.LogWarning($"Erreur lecture propriété {fieldName}: {e.Message}. Utilisation valeur par défaut: {defaultValue}");
            return defaultValue;
        }
    }
}