using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using TMPro;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem.UI;
#endif

public class RetroMainMenuUI : MonoBehaviour
{
    private Canvas m_MenuCanvas;
    private bool m_MenuActive;

    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    private static void Bootstrap()
    {
        if (Object.FindFirstObjectByType<RetroMainMenuUI>() != null)
        {
            return;
        }

        GameObject root = new("RetroMainMenuUI");
        root.AddComponent<RetroMainMenuUI>();
    }

    private void Awake()
    {
        m_MenuActive = true;
        Time.timeScale = 0f;
        ApplyMenuCursorState();

        BuildMenu();
        EnsureEventSystem();

        UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded;
    }

    private void OnDestroy()
    {
        UnityEngine.SceneManagement.SceneManager.sceneLoaded -= OnSceneLoaded;
    }

    private void OnSceneLoaded(UnityEngine.SceneManagement.Scene scene, UnityEngine.SceneManagement.LoadSceneMode mode)
    {
        // Check again when the scene finishes loading to remove any baked-in duplicate EventSystems
        EnsureEventSystem();
    }

    private void LateUpdate()
    {
        if (!m_MenuActive)
        {
            return;
        }

        // Some gameplay scripts lock the cursor during Start/Update.
        // Force menu cursor state while the menu is active.
        ApplyMenuCursorState();
    }

    private void BuildMenu()
    {
        Color bgColor = HexToColor("001e26");
        Color panelColor = HexToColor("517567");
        Color titleColor = HexToColor("f3d58d");
        Color TextNormalColor = HexToColor("eb9843");
        Color textWarningColor = HexToColor("c12204");
        Color shadowColor = HexToColor("520805");

        GameObject canvasObject = new("MainMenuCanvas");
        Canvas canvas = canvasObject.AddComponent<Canvas>();
        canvas.renderMode = RenderMode.ScreenSpaceOverlay;
        canvas.sortingOrder = 10000;
        m_MenuCanvas = canvas;

        CanvasScaler scaler = canvasObject.AddComponent<CanvasScaler>();
        scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
        scaler.referenceResolution = new Vector2(1920f, 1080f);
        scaler.matchWidthOrHeight = 0.5f;

        canvasObject.AddComponent<GraphicRaycaster>();

        // Background
        GameObject background = CreateImage("Background", canvasObject.transform, bgColor);
        StretchToFull(background.GetComponent<RectTransform>());

        // Decorative horizontal lines (scanline aesthetic)
        CreateLine("TopLine", background.transform, new Rect(0, -60, 0, 4), panelColor, AnchorPreset.TopStretch);
        CreateLine("BotLine", background.transform, new Rect(0, 60, 0, 4), panelColor, AnchorPreset.BottomStretch);

        // --- LEFT PANEL ---
        GameObject leftPanel = new GameObject("LeftPanel", typeof(RectTransform));
        leftPanel.transform.SetParent(canvasObject.transform, false);
        RectTransform leftRect = leftPanel.GetComponent<RectTransform>();
        leftRect.anchorMin = new Vector2(0.08f, 0.1f);
        leftRect.anchorMax = new Vector2(0.45f, 0.9f);
        leftRect.offsetMin = Vector2.zero;
        leftRect.offsetMax = Vector2.zero;

        // Title
        TextMeshProUGUI titleText = CreateTMP("Title", leftPanel.transform, "HEADLESS HAZARD", titleColor, 72, TextAlignmentOptions.BottomLeft);
        RectTransform titleRect = titleText.GetComponent<RectTransform>();
        titleRect.anchorMin = new Vector2(0f, 0.85f);
        titleRect.anchorMax = new Vector2(1f, 1f);
        titleRect.offsetMin = Vector2.zero;
        titleRect.offsetMax = Vector2.zero;
        titleText.fontStyle = FontStyles.Bold;

        // Title Shadow
        TextMeshProUGUI titleShadow = CreateTMP("TitleShadow", leftPanel.transform, "HEADLESS HAZARD", shadowColor, 72, TextAlignmentOptions.BottomLeft);
        RectTransform shadowRect = titleShadow.GetComponent<RectTransform>();
        shadowRect.anchorMin = new Vector2(0f, 0.85f);
        shadowRect.anchorMax = new Vector2(1f, 1f);
        shadowRect.offsetMin = new Vector2(4f, -4f); // apply drop shadow offset
        shadowRect.offsetMax = new Vector2(4f, -4f);
        titleShadow.fontStyle = FontStyles.Bold;
        titleShadow.transform.SetSiblingIndex(0); // push behind title

        // Subtitle / Decorative Status
        TextMeshProUGUI subText = CreateTMP("Subtitle", leftPanel.transform, "SYSTEM_BOOT // OS.ACTIVE_ ", panelColor, 20, TextAlignmentOptions.TopLeft);
        RectTransform subRect = subText.GetComponent<RectTransform>();
        subRect.anchorMin = new Vector2(0f, 0.80f);
        subRect.anchorMax = new Vector2(1f, 0.85f);
        subRect.offsetMin = Vector2.zero;
        subRect.offsetMax = Vector2.zero;

        // Button Group
        GameObject buttonGroup = new("ButtonGroup", typeof(RectTransform), typeof(VerticalLayoutGroup));
        buttonGroup.transform.SetParent(leftPanel.transform, false);
        RectTransform groupRect = buttonGroup.GetComponent<RectTransform>();
        groupRect.anchorMin = new Vector2(0f, 0f);
        groupRect.anchorMax = new Vector2(1f, 0.65f);
        groupRect.offsetMin = Vector2.zero;
        groupRect.offsetMax = Vector2.zero;

        VerticalLayoutGroup layout = buttonGroup.GetComponent<VerticalLayoutGroup>();
        layout.childAlignment = TextAnchor.UpperLeft;
        layout.spacing = 16f;
        layout.childControlWidth = true;
        layout.childControlHeight = false;

        CreateTextButton(buttonGroup.transform, "> INITIALIZE_PLAY", TextNormalColor, titleColor, () =>
        {
            Debug.Log("Play clicked.");
            OnPlayClicked();
        });

        CreateTextButton(buttonGroup.transform, "> CONFIGURE_PARAMS", TextNormalColor, titleColor, () =>
        {
            Debug.Log("Options clicked.");
        });

        CreateTextButton(buttonGroup.transform, "> TERMINATE_PROCESS", TextNormalColor, textWarningColor, () =>
        {
            Debug.Log("Quit clicked.");
#if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;
#else
            Application.Quit();
#endif
        });


        // --- RIGHT PANEL (Level Info) ---
        GameObject rightPanel = new GameObject("RightPanel", typeof(RectTransform));
        rightPanel.transform.SetParent(canvasObject.transform, false);
        RectTransform rightRect = rightPanel.GetComponent<RectTransform>();
        rightRect.anchorMin = new Vector2(0.55f, 0.4f);
        rightRect.anchorMax = new Vector2(0.92f, 0.82f);
        rightRect.offsetMin = Vector2.zero;
        rightRect.offsetMax = Vector2.zero;

        // Right side Border lines
        CreateLine("R_Top", rightPanel.transform, new Rect(0, 0, 0, 2), panelColor, AnchorPreset.TopStretch);
        CreateLine("R_Bot", rightPanel.transform, new Rect(0, 0, 0, 2), panelColor, AnchorPreset.BottomStretch);
        CreateLine("R_Left", rightPanel.transform, new Rect(0, 0, 2, 0), panelColor, AnchorPreset.LeftStretch);
        CreateLine("R_Right", rightPanel.transform, new Rect(0, 0, 2, 0), panelColor, AnchorPreset.RightStretch);

        // Right Panel Headers
        TextMeshProUGUI headerText = CreateTMP("LevelHeader", rightPanel.transform, "CURRENT_SECTOR", panelColor, 24, TextAlignmentOptions.TopLeft);
        headerText.GetComponent<RectTransform>().anchorMin = new Vector2(0f, 1f);
        headerText.GetComponent<RectTransform>().anchorMax = new Vector2(1f, 1f);
        headerText.GetComponent<RectTransform>().anchoredPosition = new Vector2(20f, -20f);

        // Big Level Text
        TextMeshProUGUI levelText = CreateTMP("LevelNumber", rightPanel.transform, "LEVEL 01", textWarningColor, 140, TextAlignmentOptions.Center);
        StretchToFull(levelText.GetComponent<RectTransform>());
        levelText.fontStyle = FontStyles.Bold;

        // Decorative status
        TextMeshProUGUI statusText = CreateTMP("LevelStatus", rightPanel.transform, "[ STATUS: OPTIMAL ]", panelColor, 24, TextAlignmentOptions.BottomRight);
        statusText.GetComponent<RectTransform>().anchorMin = new Vector2(0f, 0f);
        statusText.GetComponent<RectTransform>().anchorMax = new Vector2(1f, 0f);
        statusText.GetComponent<RectTransform>().anchoredPosition = new Vector2(-20f, 20f);
    }

    private void OnPlayClicked()
    {
        m_MenuActive = false;
        Time.timeScale = 1f;
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;

        if (m_MenuCanvas != null)
        {
            Destroy(m_MenuCanvas.gameObject);
        }

        Destroy(gameObject);
    }

    private static GameObject CreateTextButton(
        Transform parent,
        string label,
        Color normalColor,
        Color highlightColor,
        UnityEngine.Events.UnityAction clickAction)
    {
        GameObject buttonObject = new(label, typeof(RectTransform), typeof(TextMeshProUGUI), typeof(Button));
        buttonObject.transform.SetParent(parent, false);

        RectTransform rect = buttonObject.GetComponent<RectTransform>();
        rect.sizeDelta = new Vector2(0f, 60f); // Height 60, width auto-controlled by LayoutGroup

        TextMeshProUGUI text = buttonObject.GetComponent<TextMeshProUGUI>();
        text.text = label;
        text.fontSize = 38;
        text.alignment = TextAlignmentOptions.Left;
        text.color = Color.white; // Button tint applies on top of white
        text.textWrappingMode = TextWrappingModes.NoWrap;

        Button button = buttonObject.GetComponent<Button>();
        button.targetGraphic = text;
        button.transition = Selectable.Transition.ColorTint;

        ColorBlock colors = button.colors;
        colors.normalColor = normalColor;
        colors.highlightedColor = highlightColor;
        colors.pressedColor = highlightColor;
        colors.selectedColor = highlightColor;
        colors.disabledColor = Color.gray;
        colors.colorMultiplier = 1f;
        colors.fadeDuration = 0.1f;
        button.colors = colors;

        button.onClick.AddListener(clickAction);

        return buttonObject;
    }

    private static TextMeshProUGUI CreateTMP(string name, Transform parent, string textStr, Color color, float size, TextAlignmentOptions align)
    {
        GameObject go = new GameObject(name, typeof(RectTransform), typeof(TextMeshProUGUI));
        go.transform.SetParent(parent, false);
        TextMeshProUGUI tmp = go.GetComponent<TextMeshProUGUI>();
        tmp.text = textStr;
        tmp.color = color;
        tmp.fontSize = size;
        tmp.alignment = align;
        tmp.textWrappingMode = TextWrappingModes.NoWrap;
        return tmp;
    }

    enum AnchorPreset { TopStretch, BottomStretch, LeftStretch, RightStretch }
    private static GameObject CreateLine(string name, Transform parent, Rect details, Color color, AnchorPreset preset)
    {
        GameObject line = CreateImage(name, parent, color);
        RectTransform rect = line.GetComponent<RectTransform>();

        switch (preset)
        {
            case AnchorPreset.TopStretch:
                rect.anchorMin = new Vector2(0, 1);
                rect.anchorMax = new Vector2(1, 1);
                rect.sizeDelta = new Vector2(details.width, details.height);
                rect.anchoredPosition = new Vector2(details.x, details.y);
                break;
            case AnchorPreset.BottomStretch:
                rect.anchorMin = new Vector2(0, 0);
                rect.anchorMax = new Vector2(1, 0);
                rect.sizeDelta = new Vector2(details.width, details.height);
                rect.anchoredPosition = new Vector2(details.x, details.y);
                break;
            case AnchorPreset.LeftStretch:
                rect.anchorMin = new Vector2(0, 0);
                rect.anchorMax = new Vector2(0, 1);
                rect.sizeDelta = new Vector2(details.width, details.height);
                rect.anchoredPosition = new Vector2(details.x, details.y);
                break;
            case AnchorPreset.RightStretch:
                rect.anchorMin = new Vector2(1, 0);
                rect.anchorMax = new Vector2(1, 1);
                rect.sizeDelta = new Vector2(details.width, details.height);
                rect.anchoredPosition = new Vector2(details.x, details.y);
                break;
        }

        return line;
    }

    private static GameObject CreateImage(string name, Transform parent, Color color)
    {
        GameObject imageObject = new(name, typeof(RectTransform), typeof(Image));
        imageObject.transform.SetParent(parent, false);
        Image image = imageObject.GetComponent<Image>();
        image.color = color;
        return imageObject;
    }

    private static void StretchToFull(RectTransform rect)
    {
        rect.anchorMin = Vector2.zero;
        rect.anchorMax = Vector2.one;
        rect.offsetMin = Vector2.zero;
        rect.offsetMax = Vector2.zero;
    }

    private static Color HexToColor(string hex)
    {
        if (ColorUtility.TryParseHtmlString("#" + hex, out Color color))
        {
            return color;
        }

        return Color.magenta;
    }

    private static void ApplyMenuCursorState()
    {
        Cursor.lockState = CursorLockMode.None;
        Cursor.visible = true;
    }

    private static void EnsureEventSystem()
    {
        EventSystem[] allEventSystems = Object.FindObjectsByType<EventSystem>(FindObjectsInactive.Include, FindObjectsSortMode.None);
        EventSystem eventSystem;
        if (allEventSystems.Length == 0)
        {
            GameObject eventSystemObject = new("EventSystem", typeof(EventSystem));
            eventSystem = eventSystemObject.GetComponent<EventSystem>();
        }
        else
        {
            eventSystem = allEventSystems[0];

            for (int i = 1; i < allEventSystems.Length; i++)
            {
                if (allEventSystems[i] != null)
                {
                    Destroy(allEventSystems[i].gameObject);
                }
            }
        }

        EnsureCompatibleInputModule(eventSystem.gameObject);
    }

    private static void EnsureCompatibleInputModule(GameObject eventSystemObject)
    {
#if ENABLE_INPUT_SYSTEM
        StandaloneInputModule standaloneModule = eventSystemObject.GetComponent<StandaloneInputModule>();
        if (standaloneModule != null)
        {
            Destroy(standaloneModule);
        }

        if (eventSystemObject.GetComponent<InputSystemUIInputModule>() == null)
        {
            eventSystemObject.AddComponent<InputSystemUIInputModule>();
        }
#else
        if (eventSystemObject.GetComponent<StandaloneInputModule>() == null)
        {
            eventSystemObject.AddComponent<StandaloneInputModule>();
        }
#endif
    }
}