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

/// <summary>
/// Menu principal avec scroll vertical corrigé
/// </summary>
public class MainMenuManager : MonoBehaviour
{
    [Header("UI References")]
    public TextMeshProUGUI titleText;

    [Tooltip("Viewport du ScrollRect (enfant direct de l'objet Scroll View)")]
    public RectTransform viewport;

    [Tooltip("Transform/RectTransform qui contient les cartes (Content du ScrollRect)")]
    public RectTransform levelsContainer;

    [Tooltip("Prefab d'une carte de niveau")]
    public GameObject levelCardPrefab;

    [Tooltip("Scroll View (ScrollRect)")]
    public ScrollRect scrollRect;

    [Tooltip("Scrollbar verticale (optionnelle)")]
    public Scrollbar verticalScrollbar;

    [Header("Loading")]
    public GameObject loadingPanel;
    public TextMeshProUGUI loadingText;

    [Header("Filtres")]
    public TMP_Dropdown questFilter;
    public TMP_Dropdown typeFilter;
    public Toggle showOnlyUnlockedToggle;

    [Header("Layout (Grid)")]
    [SerializeField] private int columns = 3;
    [SerializeField] private Vector2 cellSize = new Vector2(300, 170);
    [SerializeField] private Vector2 spacing = new Vector2(30, 30);
    [SerializeField] private RectOffset padding;
    [SerializeField] private TextAnchor childAlignment = TextAnchor.UpperLeft;

    [Header("Debug")]
    public bool debugMode = false;

    // internes
    private readonly List<LevelCard> levelCards = new List<LevelCard>();
    private string currentQuestFilter = "";
    private string currentTypeFilter = "";
    private bool showOnlyUnlocked = false;

    private GridLayoutGroup grid;

    void Awake()
    {
        if (padding == null) padding = new RectOffset(40, 40, 40, 40);

        if (levelsContainer == null)
        {
            DebugLogger.LogError("'levelsContainer' n'est pas assigné.", "MainMenu");
            return;
        }

        // Assure le GridLayoutGroup sur le Content
        grid = levelsContainer.GetComponent<GridLayoutGroup>();
        if (grid == null) grid = levelsContainer.gameObject.AddComponent<GridLayoutGroup>();

        // Configure le Grid
        grid.cellSize = cellSize;
        grid.spacing = spacing;
        grid.padding = padding;
        grid.startCorner = GridLayoutGroup.Corner.UpperLeft;
        grid.startAxis = GridLayoutGroup.Axis.Horizontal;
        grid.childAlignment = childAlignment;
        grid.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
        grid.constraintCount = Mathf.Max(1, columns);

        // CORRECTION : Ancrage du Content pour le scroll vertical
        levelsContainer.anchorMin = new Vector2(0f, 1f);  // Ancré en haut à gauche
        levelsContainer.anchorMax = new Vector2(1f, 1f);  // Étiré horizontalement, ancré en haut
        levelsContainer.pivot = new Vector2(0.5f, 1f);    // Pivot en haut au centre
        
        // Position initiale du Content
        levelsContainer.anchoredPosition = new Vector2(0f, 0f);
    }

    void Start()
    {
        if (loadingPanel != null)
        {
            loadingPanel.SetActive(true);
            if (loadingText != null) loadingText.text = "Chargement des niveaux...";
        }

        SetupScrollRect();
        StartCoroutine(WaitForLevelManagerAndInitialize());
    }

    void SetupScrollRect()
    {
        if (scrollRect == null)
        {
            DebugLogger.LogError("ScrollRect non assigné.", "MainMenu");
            return;
        }

        // Assigne content/viewport
        scrollRect.content = levelsContainer;
        if (viewport != null) scrollRect.viewport = viewport;

        // Ajoute RectMask2D pour le clipping si absent
        if (viewport != null && viewport.GetComponent<RectMask2D>() == null)
            viewport.gameObject.AddComponent<RectMask2D>();

        // Configuration ScrollRect CORRIGÉE
        scrollRect.horizontal = false;
        scrollRect.vertical = true;
        scrollRect.movementType = ScrollRect.MovementType.Clamped;
        scrollRect.inertia = true;
        scrollRect.scrollSensitivity = 25f;
        scrollRect.decelerationRate = 0.135f;

        // Scrollbar optionnelle
        if (verticalScrollbar != null)
        {
            scrollRect.verticalScrollbar = verticalScrollbar;
#if UNITY_2021_1_OR_NEWER
            scrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
#endif
        }

        DebugLogger.Log($"ScrollRect configuré - Viewport: {viewport?.name}", "MainMenu");
    }

    IEnumerator WaitForLevelManagerAndInitialize()
    {
        while (LevelManager.Instance == null || !LevelManager.Instance.IsConfigurationLoaded())
            yield return new WaitForSeconds(0.1f);

        yield return new WaitForSeconds(0.2f); // Attente supplémentaire pour stabilité
        InitializeMenu();
    }

    void InitializeMenu()
    {
        if (titleText != null) titleText.text = LevelManager.Instance.GetGameTitle();

        SetupFilters();
        GenerateLevelCards();
        
        // CORRECTION : Forcer le recalcul avec délai
        StartCoroutine(UpdateLayoutWithDelay());

        if (loadingPanel != null) loadingPanel.SetActive(false);

        if (debugMode) DebugLogger.LogInfo("Initialisé.", "MainMenu");
    }

    // NOUVELLE MÉTHODE : Mise à jour du layout avec délai
    IEnumerator UpdateLayoutWithDelay()
    {
        yield return new WaitForEndOfFrame(); // Attendre la fin du frame
        yield return new WaitForEndOfFrame(); // Attendre encore un frame
        
        UpdateContentHeight();
        ScrollToTop();
        
        // Force rebuild du layout
        LayoutRebuilder.ForceRebuildLayoutImmediate(levelsContainer);
        Canvas.ForceUpdateCanvases();
    }

    // ---------- Filtres (inchangé) ----------
    void SetupFilters()
    {
        if (questFilter != null)
        {
            questFilter.options.Clear();
            questFilter.options.Add(new TMP_Dropdown.OptionData("Toutes les quêtes"));

            HashSet<string> quests = new HashSet<string>();
            foreach (var level in LevelManager.Instance.GetAllLevels())
                if (!string.IsNullOrEmpty(level.questId)) quests.Add(level.questId);

            foreach (var q in quests)
                questFilter.options.Add(new TMP_Dropdown.OptionData(q.ToUpper()));

            questFilter.onValueChanged.AddListener(OnQuestFilterChanged);
        }

        if (typeFilter != null)
        {
            typeFilter.options.Clear();
            typeFilter.options.Add(new TMP_Dropdown.OptionData("Tous les types"));
            typeFilter.options.Add(new TMP_Dropdown.OptionData("Shooting"));
            typeFilter.options.Add(new TMP_Dropdown.OptionData("Calculator"));
            typeFilter.onValueChanged.AddListener(OnTypeFilterChanged);
        }

        if (showOnlyUnlockedToggle != null)
            showOnlyUnlockedToggle.onValueChanged.AddListener(OnUnlockedToggleChanged);
    }

    void OnQuestFilterChanged(int index)
    {
        currentQuestFilter = (index == 0) ? "" : questFilter.options[index].text.ToLower();
        Regenerate();
    }

    void OnTypeFilterChanged(int index)
    {
        switch (index)
        {
            case 0: currentTypeFilter = ""; break;
            case 1: currentTypeFilter = "shooting"; break;
            case 2: currentTypeFilter = "calculator"; break;
        }
        Regenerate();
    }

    void OnUnlockedToggleChanged(bool value)
    {
        showOnlyUnlocked = value;
        Regenerate();
    }

    // ---------- Génération cartes ----------
    void Regenerate()
    {
        GenerateLevelCards();
        StartCoroutine(UpdateLayoutWithDelay()); // Utiliser la nouvelle méthode
    }

    void GenerateLevelCards()
    {
        ClearLevelCards();

        if (levelsContainer == null || levelCardPrefab == null)
        {
            DebugLogger.LogError("Références manquantes (levelsContainer / levelCardPrefab).", "MainMenu");
            return;
        }

        List<LevelData> levels = GetFilteredLevels();

        foreach (var level in levels)
        {
            var cardObj = Instantiate(levelCardPrefab, levelsContainer);

            // Assure la taille de la carte
            var rt = cardObj.GetComponent<RectTransform>();
            if (rt != null) rt.sizeDelta = cellSize;

            var levelCard = cardObj.GetComponent<LevelCard>() ?? cardObj.AddComponent<LevelCard>();
            levelCard.Initialize(level);
            levelCards.Add(levelCard);
        }

        DebugLogger.LogInfo($"{levelCards.Count} cartes générées", "MainMenu");
    }

    List<LevelData> GetFilteredLevels()
    {
        var all = LevelManager.Instance.GetAllLevels();
        var list = new List<LevelData>(all.Count);

        foreach (var level in all)
        {
            if (!string.IsNullOrEmpty(currentQuestFilter) && level.questId.ToLower() != currentQuestFilter)
                continue;

            if (!string.IsNullOrEmpty(currentTypeFilter) && level.type.ToLower() != currentTypeFilter)
                continue;

            if (showOnlyUnlocked && !level.isEnabled)
                continue;

            list.Add(level);
        }

        return list;
    }

    void ClearLevelCards()
    {
        foreach (var c in levelCards)
            if (c != null && c.gameObject != null) Destroy(c.gameObject);
        levelCards.Clear();
    }

    // ---------- CORRECTION SCROLL & HAUTEUR ----------
    void UpdateContentHeight()
    {
        if (grid == null || levelsContainer == null) 
        {
            DebugLogger.LogWarning("Grid ou levelsContainer manquant pour UpdateContentHeight", "MainMenu");
            return;
        }

        int items = levelCards.Count;
        if (items == 0)
        {
            // Pas d'items, hauteur minimale
            levelsContainer.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 100f);
            return;
        }

        int cols = Mathf.Max(1, columns);
        int rows = Mathf.CeilToInt(items / (float)cols);

        float totalHeight = padding.top
                          + rows * cellSize.y
                          + Mathf.Max(0, rows - 1) * spacing.y
                          + padding.bottom;

        // CORRECTION : S'assurer que la hauteur est suffisante pour le scroll
        float viewportHeight = viewport ? viewport.rect.height : 600f;
        float minHeight = Mathf.Max(totalHeight, viewportHeight + 50f); // +50 pour forcer le scroll

        // Ajuster la hauteur du Content
        levelsContainer.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, minHeight);

        if (debugMode)
        {
            DebugLogger.Log($"Items: {items}, Rows: {rows}, ContentH: {minHeight:F0}, ViewportH: {viewportHeight:F0}", "MainMenu");
        }

        // Force le rebuild du layout système
        LayoutRebuilder.ForceRebuildLayoutImmediate(levelsContainer);
        
        // NOUVEAU : Notifier le ScrollRect que le contenu a changé
        if (scrollRect != null)
        {
            scrollRect.Rebuild(CanvasUpdate.PostLayout);
        }
    }

    void ScrollToTop()
    {
        if (scrollRect != null)
        {
            // Force la position en haut
            scrollRect.verticalNormalizedPosition = 1f;
            
            // NOUVEAU : Force la mise à jour du ScrollRect
            scrollRect.velocity = Vector2.zero;
        }
    }

    // ---------- Public methods (inchangé) ----------
    public void OnLevelCardClicked(LevelData level)
    {
        if (level == null) { DebugLogger.LogError("Niveau null !", "MainMenu"); return; }

        if (loadingPanel != null)
        {
            loadingPanel.SetActive(true);
            if (loadingText != null) loadingText.text = $"Chargement de {level.title}...";
        }

        if (LevelManager.Instance != null) LevelManager.Instance.LoadLevel(level.id);
        else DebugLogger.LogError("LevelManager introuvable !", "MainMenu");
    }

    public void RefreshMenu()
    {
        if (LevelManager.Instance != null) LevelManager.Instance.ReloadConfiguration();
        StartCoroutine(WaitForLevelManagerAndInitialize());
    }

    public void SetColumns(int col)
    {
        columns = Mathf.Max(1, col);
        if (grid != null) grid.constraintCount = columns;
        Regenerate();
    }

    public void SetCellSize(float w, float h)
    {
        cellSize = new Vector2(w, h);
        if (grid != null) grid.cellSize = cellSize;
        Regenerate();
    }

    public void SetSpacing(float x, float y)
    {
        spacing = new Vector2(x, y);
        if (grid != null) grid.spacing = spacing;
        Regenerate();
    }

    // Debug hotkeys
    void Update()
    {
        var k = UnityEngine.InputSystem.Keyboard.current;
        if (k == null) return;

        // Touche ESC fonctionne TOUJOURS pour quitter le jeu depuis le menu
        if (k.escapeKey.wasPressedThisFrame)
        {
            Debug.Log("[MainMenuManager] 🚪 Touche ESC détectée - Quitter le jeu");
            QuitApplication();
            return;
        }
        
        // Les autres touches de debug ne fonctionnent qu'en mode debug
        if (!debugMode) return;
        
        if (k.rKey.wasPressedThisFrame) RefreshMenu();
        if (k.digit1Key.wasPressedThisFrame) SetColumns(1);
        if (k.digit2Key.wasPressedThisFrame) SetColumns(2);
        if (k.digit3Key.wasPressedThisFrame) SetColumns(3);
        if (k.digit4Key.wasPressedThisFrame) SetColumns(4);
        if (k.digit5Key.wasPressedThisFrame) SetColumns(5);
        if (k.digit6Key.wasPressedThisFrame) SetColumns(6);
        
        // NOUVEAU : Debug scroll
        if (k.spaceKey.wasPressedThisFrame) 
        {
            DebugLogger.Log($"ScrollRect - ContentH: {levelsContainer.rect.height}, ViewportH: {viewport.rect.height}", "MainMenu");
            DebugLogger.Log($"ScrollRect - Vertical: {scrollRect.vertical}, Position: {scrollRect.verticalNormalizedPosition}", "MainMenu");
        }
    }

    void QuitApplication()
    {
        DebugLogger.LogInfo("Demande de fermeture de l'application depuis le menu principal", "MainMenu");
        
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
        DebugLogger.LogInfo("Application fermée (mode éditeur)", "MainMenu");
#else
        Application.Quit();
        DebugLogger.LogInfo("Application fermée", "MainMenu");
#endif
    }
}