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

public class UIManager : MonoBehaviour
{
    [Header("UI Prefabs")]
    public GameObject messageWindowPrefab;

    [Header("Message Window Settings")]
    public float slideDuration = 0.3f;
    public AnimationCurve slideCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
    public float cursorAnimationSpeed = 1f;
    public float cursorAnimationHeight = 10f;

    private RectTransform messageWindow;
    public TMP_Text messageText;
    public TMP_Text shadowText;
    private RectTransform cursor;
    private RectTransform cursor2;
    private Vector2 cursorOriginalPosition;

    private bool isMessageWindowVisible = false;
    private bool isWaitingForInput = false;
    private Coroutine cursorAnimationCoroutine;
    private Coroutine slideCoroutine;

    public int userSelectionVariant;

    private ExecutionContext currentContext;

    private bool isInitialized = false;

    public void Initialize()
    {
        if (isInitialized) return;

        CreateMessageWindow();
        isInitialized = true;
    }

    private void CreateMessageWindow()
    {
        if (messageWindowPrefab == null)
        {
            Debug.LogError("MessageWindow prefab is not assigned!");
            return;
        }

        GameObject messageWindowGO = Instantiate(messageWindowPrefab, transform);
        messageWindow = messageWindowGO.GetComponent<RectTransform>();

        // Находим текстовые компоненты
        messageText = messageWindowGO.transform.Find("TextContainer/MessageText")?.GetComponent<TMP_Text>();
        shadowText = messageWindowGO.transform.Find("TextContainer/ShadowText")?.GetComponent<TMP_Text>();

        // Находим курсор
        Transform cursorTransform = messageWindowGO.transform.Find("Cursor");
        Transform cursor2Transform = messageWindowGO.transform.Find("Cursor2");
        if (cursorTransform != null)
        {
            cursor = cursorTransform.GetComponent<RectTransform>();
            cursorOriginalPosition = cursor.anchoredPosition;
            cursor.gameObject.SetActive(false);            
            cursor2 = cursor2Transform.GetComponent<RectTransform>();
            cursor2.gameObject.SetActive(false);
        }

        // Сразу скрываем окно
        HideMessageWindowImmediate();
    }

    // Методы для управления MessageWindow
    public void ShowMessageWindow()
    {
        if (messageWindow != null && !isMessageWindowVisible)
        {
            // Активируем окно перед анимацией
            messageWindow.gameObject.SetActive(true);

            if (slideCoroutine != null)
                StopCoroutine(slideCoroutine);

            slideCoroutine = StartCoroutine(SlideWindow(true));
        }
    }

    public void HideMessageWindow(ExecutionContext ctx)
    {
        if (messageWindow != null && isMessageWindowVisible)
        {
            currentContext = ctx;
            ctx.IsPaused = true;

            if (slideCoroutine != null)
                StopCoroutine(slideCoroutine);

            slideCoroutine = StartCoroutine(SlideWindow(false));
        } else
        {
            ctx.IsPaused = false;
        }
    }

    private IEnumerator SlideWindow(bool show)
    {
        float elapsed = 0f;
        float startOffset = show ? -messageWindow.rect.height : 0f;
        float targetOffset = show ? 0f : -messageWindow.rect.height;

        while (elapsed < slideDuration)
        {
            elapsed += Time.deltaTime;
            float t = slideCurve.Evaluate(elapsed / slideDuration);

            // Анимируем через offsetMin/offsetMax
            float currentOffset = Mathf.Lerp(startOffset, targetOffset, t);
            messageWindow.offsetMin = new Vector2(0f, currentOffset);
            messageWindow.offsetMax = new Vector2(0f, currentOffset);

            yield return null;
        }

        // Финализируем позицию
        float finalOffset = show ? 0f : -messageWindow.rect.height;
        messageWindow.offsetMin = new Vector2(0f, finalOffset);
        messageWindow.offsetMax = new Vector2(0f, finalOffset);

        isMessageWindowVisible = show;

        // Если скрываем окно - деактивируем
        if (!show)
        {
            messageWindow.gameObject.SetActive(false);

            if (currentContext != null)
            {
                currentContext.IsPaused = false;
                currentContext = null;
            }

        }
    }

    public void HideMessageWindowImmediate()
    {
        if (messageWindow != null)
        {
            // Устанавливаем позицию ниже экрана
            messageWindow.offsetMin = new Vector2(0f, messageWindow.rect.height);
            messageWindow.offsetMax = new Vector2(0f, messageWindow.rect.height);

            isMessageWindowVisible = false;
            messageWindow.gameObject.SetActive(false);

            if (currentContext != null)
            {
                currentContext.IsPaused = false;
                currentContext = null;
            }
        }
    }

    // Методы для работы с текстом
    public void SetText(string text)
    {
        if (messageText != null) messageText.text = text;
        if (shadowText != null) shadowText.text = text;
    }

    public void AppendText(string text)
    {
        if (messageText != null) messageText.text += text;
        if (shadowText != null) shadowText.text += text;
    }

    public void ClearText()
    {
        if (messageText != null) messageText.text = "";
        if (shadowText != null) shadowText.text = "";
    }

    // Методы для курсора
    public void ShowCursor(bool show)
    {
        if (cursor != null)
        {
            cursor.gameObject.SetActive(show);
            cursor2.gameObject.SetActive(show);
            
            isWaitingForInput = show;

            if (show && cursorAnimationCoroutine == null)
            {
                cursorAnimationCoroutine = StartCoroutine(AnimateCursor());
            }
            else if (!show && cursorAnimationCoroutine != null)
            {
                StopCoroutine(cursorAnimationCoroutine);
                cursorAnimationCoroutine = null;
                cursor.anchoredPosition = cursorOriginalPosition;
                cursor2.anchoredPosition = cursorOriginalPosition;
            }
        }
    }

    private IEnumerator AnimateCursor()
    {
        while (isWaitingForInput)
        {
            float yOffset = Mathf.Sin(Time.time * cursorAnimationSpeed) * cursorAnimationHeight;
            float yOffset2 = Mathf.Sin((Time.time - 0.1f) * cursorAnimationSpeed) * cursorAnimationHeight;
            cursor.anchoredPosition = cursorOriginalPosition + new Vector2(0, yOffset);
            cursor2.anchoredPosition = cursorOriginalPosition + new Vector2(0, yOffset2);
            yield return null;
        }
    }

    // user dialog selection
    public void ShowSelection(List<string> variants)
    {
        switch (variants.Count)
        {
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
                break;
        }
    }

    public void WipeSelection()
    {
       
    }


    public bool IsMessageWindowVisible => isMessageWindowVisible;
    public bool IsWaitingForInput => isWaitingForInput;
}