using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using TMPro;
using UnityEngine.EventSystems;

/// <summary>
/// Carte de niveau
/// - Ne consomme plus 'description' ni 'difficultyLevel'
/// - Charge la vignette via l'URL calculée par LevelManager
/// </summary>
public class LevelCard : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
    [Header("UI Components")]
    public Image thumbnailImage;
    public TextMeshProUGUI titleText;
    public TextMeshProUGUI descriptionText; // conservé dans l'Inspector mais non utilisé
    public TextMeshProUGUI typeText;
    public TextMeshProUGUI questText;
    public TextMeshProUGUI difficultyText;  // conservé dans l'Inspector mais non utilisé
    public GameObject lockedOverlay;
    public Image typeIcon;
    public Button cardButton;

    [Header("Visual Effects")]
    public float hoverScale = 1.05f;
    public float animationDuration = 0.2f;
    public Color enabledColor = Color.white;
    public Color disabledColor = Color.gray;

    [Header("Icons")]
    public Sprite shootingIcon;
    public Sprite calculatorIcon;
    public Sprite lockedIcon;

    // Données et références
    private LevelData levelData;
    private Vector3 originalScale;
    private CanvasGroup canvasGroup;
    private bool isInteractable = true;

    void Awake()
    {
        originalScale = transform.localScale;

        // Ajouter CanvasGroup si pas présent
        canvasGroup = GetComponent<CanvasGroup>();
        if (canvasGroup == null)
            canvasGroup = gameObject.AddComponent<CanvasGroup>();

        // Configurer le bouton
        if (cardButton == null)
        {
            cardButton = GetComponent<Button>();
            if (cardButton == null)
                cardButton = gameObject.AddComponent<Button>();
        }
    }

    /// <summary>
    /// Initialise la carte avec les données du niveau
    /// </summary>
    public void Initialize(LevelData level)
    {
        levelData = level;

        if (levelData == null)
        {
            Debug.LogError("LevelCard: Données de niveau nulles !");
            return;
        }

        SetupCardVisuals();
        SetupCardInteraction();

        // Charger l'image thumbnail via l'URL calculée
        string thumbUrl = LevelManager.Instance != null ? LevelManager.Instance.GetLevelThumbnailUrl(levelData) : null;
        if (!string.IsNullOrEmpty(thumbUrl))
            StartCoroutine(LoadThumbnail(thumbUrl));

        if (descriptionText) descriptionText.gameObject.SetActive(false); // plus utilisé
        if (difficultyText)  difficultyText.gameObject.SetActive(false);  // plus utilisé

        Debug.Log($"LevelCard initialisée : {levelData.title}");
    }

    /// <summary>
    /// Configure l'apparence visuelle de la carte
    /// </summary>
    void SetupCardVisuals()
    {
        if (titleText != null)
            titleText.text = levelData.title;

        if (typeText != null)
            typeText.text = GetDisplayType(levelData.type);

        if (questText != null)
            questText.text = levelData.questId?.ToUpper() ?? "";

        if (typeIcon != null)
            typeIcon.sprite = GetTypeIcon(levelData.type);

        SetCardEnabledState(levelData.isEnabled);
    }

    /// <summary>
    /// Configure l'interaction de la carte
    /// </summary>
    void SetupCardInteraction()
    {
        isInteractable = levelData.isEnabled;

        if (cardButton != null)
        {
            cardButton.interactable = isInteractable;
            cardButton.onClick.RemoveAllListeners();
            cardButton.onClick.AddListener(OnCardClicked);
        }

        if (lockedOverlay != null)
            lockedOverlay.SetActive(!levelData.isEnabled);
    }

    /// <summary>
    /// Charge l'image thumbnail depuis une URL
    /// </summary>
    IEnumerator LoadThumbnail(string url)
    {
        if (thumbnailImage == null)
        {
            Debug.LogWarning($"[LevelCard] ThumbnailImage non assigné pour {levelData.title} !");
            yield break;
        }

        Debug.Log($"[LevelCard] Chargement thumbnail pour {levelData.title}: {url}");

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

#if UNITY_2020_2_OR_NEWER
            bool ok = www.result == UnityWebRequest.Result.Success;
#else
            bool ok = !(www.isNetworkError || www.isHttpError);
#endif
            if (ok)
            {
                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)
                );

                thumbnailImage.sprite = sprite;
                Debug.Log($"[LevelCard] ✅ Thumbnail chargé avec succès pour {levelData.title}");
            }
            else
            {
                Debug.LogWarning($"[LevelCard] ❌ Erreur chargement thumbnail pour {levelData.title}:");
                Debug.LogWarning($"[LevelCard]    URL: {url}");
                Debug.LogWarning($"[LevelCard]    Erreur: {www.error}");
                Debug.LogWarning($"[LevelCard]    Code HTTP: {www.responseCode}");
                LoadFallbackThumbnail();
            }
        }
    }

    /// <summary>
    /// Crée une image de fallback simple
    /// </summary>
    void LoadFallbackThumbnail()
    {
        if (thumbnailImage == null) return;

        Texture2D fallbackTexture = new Texture2D(300, 200);
        Color baseColor = GetTypeColor(levelData.type);

        Color[] pixels = new Color[300 * 200];
        for (int i = 0; i < pixels.Length; i++)
            pixels[i] = baseColor;

        fallbackTexture.SetPixels(pixels);
        fallbackTexture.Apply();

        Sprite fallbackSprite = Sprite.Create(
            fallbackTexture,
            new Rect(0, 0, 300, 200),
            new Vector2(0.5f, 0.5f)
        );

        thumbnailImage.sprite = fallbackSprite;
    }

    void SetCardEnabledState(bool enabled)
    {
        if (canvasGroup != null)
            canvasGroup.alpha = enabled ? 1f : 0.7f;

        Color targetColor = enabled ? enabledColor : disabledColor;

        if (thumbnailImage != null)
            thumbnailImage.color = targetColor;

        isInteractable = enabled;
    }

    string GetDisplayType(string type)
    {
        switch (type.ToLower())
        {
            case "shooting":   return "TIR";
            case "calculator": return "CALCUL";
            default:           return type.ToUpper();
        }
    }

    Sprite GetTypeIcon(string type)
    {
        switch (type.ToLower())
        {
            case "shooting":   return shootingIcon;
            case "calculator": return calculatorIcon;
            default:           return null;
        }
    }

    Color GetTypeColor(string type)
    {
        switch (type.ToLower())
        {
            case "shooting":   return new Color(0.8f, 0.2f, 0.2f, 1f); // Rouge
            case "calculator": return new Color(0.2f, 0.6f, 0.8f, 1f); // Bleu
            default:           return new Color(0.5f, 0.5f, 0.5f, 1f); // Gris
        }
    }

    // ========================================
    // GESTION DES ÉVÉNEMENTS
    // ========================================

    void OnCardClicked()
    {
        if (!isInteractable || levelData == null)
        {
            Debug.LogWarning("Carte non cliquable ou données manquantes");
            return;
        }

        StartCoroutine(ClickAnimation());
        LaunchLevel(levelData);
    }
    
    /// <summary>
    /// Lance le niveau directement via LevelManager
    /// </summary>
    void LaunchLevel(LevelData levelData)
    {
        DebugLogger.LogInfo($"Lancement du niveau: {levelData.title}", "LevelCard");
        
        // Vérifications de sécurité
        if (LevelManager.Instance == null)
        {
            DebugLogger.LogError("LevelManager introuvable !", "LevelCard");
            return;
        }
        
        if (!LevelManager.Instance.IsConfigurationLoaded())
        {
            DebugLogger.LogError("LevelManager pas encore chargé ! Attente...", "LevelCard");
            StartCoroutine(WaitForLevelManagerThenLaunch(levelData));
            return;
        }
        
        if (GeneralConfigManager.Instance == null)
        {
            DebugLogger.LogError("GeneralConfigManager introuvable !", "LevelCard");
            return;
        }
        
        if (!GeneralConfigManager.Instance.IsConfigLoaded())
        {
            DebugLogger.LogError("GeneralConfigManager pas encore chargé ! Attente...", "LevelCard");
            StartCoroutine(WaitForGeneralConfigThenLaunch(levelData));
            return;
        }
        
        // Tout est prêt, on peut lancer
        DebugLogger.LogInfo("Tous les managers sont prêts, lancement...", "LevelCard");
        LevelManager.Instance.LoadLevel(levelData.id);
    }
    
    /// <summary>
    /// Attend que LevelManager soit prêt avant de lancer
    /// </summary>
    IEnumerator WaitForLevelManagerThenLaunch(LevelData levelData)
    {
        DebugLogger.LogWarning("Attente de LevelManager...", "LevelCard");
        
        float timeout = 5f;
        float elapsed = 0f;
        
        while (!LevelManager.Instance.IsConfigurationLoaded() && elapsed < timeout)
        {
            yield return new WaitForSeconds(0.1f);
            elapsed += 0.1f;
        }
        
        if (LevelManager.Instance.IsConfigurationLoaded())
        {
            DebugLogger.LogInfo("LevelManager prêt, relance...", "LevelCard");
            LaunchLevel(levelData); // Réessayer
        }
        else
        {
            DebugLogger.LogError($"Timeout : LevelManager toujours pas prêt après {timeout}s", "LevelCard");
        }
    }
    
    /// <summary>
    /// Attend que GeneralConfigManager soit prêt avant de lancer
    /// </summary>
    IEnumerator WaitForGeneralConfigThenLaunch(LevelData levelData)
    {
        DebugLogger.LogWarning("Attente de GeneralConfigManager...", "LevelCard");
        
        float timeout = 5f;
        float elapsed = 0f;
        
        while (!GeneralConfigManager.Instance.IsConfigLoaded() && elapsed < timeout)
        {
            yield return new WaitForSeconds(0.1f);
            elapsed += 0.1f;
        }
        
        if (GeneralConfigManager.Instance.IsConfigLoaded())
        {
            DebugLogger.LogInfo("GeneralConfigManager prêt, relance...", "LevelCard");
            LaunchLevel(levelData); // Réessayer
        }
        else
        {
            DebugLogger.LogError($"Timeout : GeneralConfigManager toujours pas prêt après {timeout}s", "LevelCard");
        }
    }

    IEnumerator ClickAnimation()
    {
        Vector3 smallScale = originalScale * 0.95f;

        yield return StartCoroutine(AnimateScale(smallScale, animationDuration * 0.5f));
        yield return StartCoroutine(AnimateScale(originalScale, animationDuration * 0.5f));
    }

    IEnumerator AnimateScale(Vector3 targetScale, float duration)
    {
        Vector3 startScale = transform.localScale;
        float elapsed = 0f;

        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            float t = Mathf.SmoothStep(0f, 1f, elapsed / duration);
            transform.localScale = Vector3.Lerp(startScale, targetScale, t);
            yield return null;
        }

        transform.localScale = targetScale;
    }

    // ========================================
    // INTERFACE POINTER EVENTS
    // ========================================

    public void OnPointerEnter(PointerEventData eventData)
    {
        if (!isInteractable) return;
        Vector3 hoverScaleVector = originalScale * hoverScale;
        StartCoroutine(AnimateScale(hoverScaleVector, animationDuration));
        if (canvasGroup != null) canvasGroup.alpha = 1f;
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        if (!isInteractable) return;
        StartCoroutine(AnimateScale(originalScale, animationDuration));
        if (canvasGroup != null) canvasGroup.alpha = levelData.isEnabled ? 1f : 0.7f;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        // Géré par OnCardClicked via le Button component
    }

    // ========================================
    // MÉTHODES PUBLIQUES
    // ========================================

    public LevelData GetLevelData() => levelData;

    public void UpdateLockState(bool isUnlocked)
    {
        if (levelData != null)
        {
            levelData.isEnabled = isUnlocked;
            SetupCardInteraction();
            SetCardEnabledState(isUnlocked);
        }
    }

    public void RefreshCard()
    {
        if (levelData != null)
        {
            SetupCardVisuals();
            SetupCardInteraction();
        }
    }

    public void ShowLevelPreview()
    {
        Debug.Log($"Preview du niveau : {levelData?.title}");
    }

    void OnDestroy()
    {
        StopAllCoroutines();
    }
}
