using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;

namespace UI
{
    /// <summary>
    /// A draggable window component with title bar dragging and close button functionality.
    /// Automatically creates UI structure on Awake.
    /// </summary>
    public class Window : MonoBehaviour
    {
        [Header("Window Settings")]
        [SerializeField] private Vector2 windowSize = new Vector2(600, 400);
        [SerializeField] private string windowTitle = "Window";
        [SerializeField] private Color backgroundColor = new Color(0.2f, 0.2f, 0.2f, 1f);
        [SerializeField] private Color titleBarColor = new Color(0.3f, 0.3f, 0.3f, 1f);
        [SerializeField] private float titleBarHeight = 30f;

        private RectTransform rectTransform;
        private RectTransform titleBarRect;
        private Image titleBarImage;
        private bool isDragging = false;
        private Vector2 dragOffset;
        private bool wasMouseDownLastFrame = false;

        private void Awake()
        {
            rectTransform = GetComponent<RectTransform>();
            if (rectTransform == null)
            {
                rectTransform = gameObject.AddComponent<RectTransform>();
            }

            CreateUIStructure();
        }

        private void Update()
        {
            // Fallback: Check for mouse down on title bar if interface didn't fire
            bool isMouseDown = Mouse.current.leftButton.isPressed;
            if (isMouseDown && !wasMouseDownLastFrame && !isDragging)
            {
                CheckTitleBarClick();
            }
            wasMouseDownLastFrame = isMouseDown;

            HandleDragging();
        }

        /// <summary>
        /// Fallback method to check if mouse clicked on title bar using raycasting
        /// </summary>
        private void CheckTitleBarClick()
        {
            Debug.Log("CheckTitleBarClick");
            if (EventSystem.current == null) return;

            Vector2 mousePosition = Mouse.current.position.ReadValue();
            
            // Use EventSystem to raycast
            PointerEventData pointerData = new PointerEventData(EventSystem.current);
            pointerData.position = mousePosition;

            var results = new System.Collections.Generic.List<RaycastResult>();
            EventSystem.current.RaycastAll(pointerData, results);

            foreach (var result in results)
            {
                // Check if we hit the title bar (but not the close button or its children)
                Transform hitTransform = result.gameObject.transform;
                if (hitTransform.name == "TitleBar" && hitTransform.IsChildOf(transform))
                {
                    OnTitleBarPointerDown(mousePosition);
                    break;
                }
                // If we hit a child of TitleBar, check if it's not the close button
                else if (hitTransform.IsChildOf(transform.Find("TitleBar")))
                {
                    // Skip if it's the close button or its children
                    if (!hitTransform.name.Contains("CloseButton") && hitTransform.parent != null && hitTransform.parent.name != "CloseButton")
                    {
                        OnTitleBarPointerDown(mousePosition);
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// Creates the UI structure: background, title bar, close button, and content area
        /// </summary>
        private void CreateUIStructure()
        {
            // Set up root RectTransform
            rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
            rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
            rectTransform.pivot = new Vector2(0.5f, 0.5f);
            rectTransform.sizeDelta = windowSize;
            rectTransform.anchoredPosition = Vector2.zero;

            // Create Background
            GameObject backgroundObj = new GameObject("Background");
            backgroundObj.transform.SetParent(transform, false);
            Image backgroundImage = backgroundObj.AddComponent<Image>();
            backgroundImage.color = backgroundColor;

            RectTransform backgroundRect = backgroundObj.GetComponent<RectTransform>();
            backgroundRect.anchorMin = Vector2.zero;
            backgroundRect.anchorMax = Vector2.one;
            backgroundRect.sizeDelta = Vector2.zero;
            backgroundRect.anchoredPosition = Vector2.zero;

            // Create Title Bar
            GameObject titleBarObj = new GameObject("TitleBar");
            titleBarObj.transform.SetParent(transform, false);
            Image titleBarImage = titleBarObj.AddComponent<Image>();
            titleBarImage.color = titleBarColor;

            titleBarRect = titleBarObj.GetComponent<RectTransform>();
            titleBarRect.anchorMin = new Vector2(0, 1);
            titleBarRect.anchorMax = new Vector2(1, 1);
            titleBarRect.pivot = new Vector2(0.5f, 1);
            titleBarRect.sizeDelta = new Vector2(0, titleBarHeight);
            titleBarRect.anchoredPosition = new Vector2(0, 0);
            this.titleBarImage = titleBarImage;

            // Add TitleBarDragHandler component for dragging
            TitleBarDragHandler dragHandler = titleBarObj.AddComponent<TitleBarDragHandler>();
            dragHandler.Initialize(this);

            // Create Title Text
            GameObject titleTextObj = new GameObject("TitleText");
            titleTextObj.transform.SetParent(titleBarObj.transform, false);
            Text titleText = titleTextObj.AddComponent<Text>();
            titleText.text = windowTitle;
            titleText.color = Color.white;
            titleText.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
            titleText.fontSize = 14;
            titleText.alignment = TextAnchor.MiddleLeft;

            RectTransform titleTextRect = titleTextObj.GetComponent<RectTransform>();
            titleTextRect.anchorMin = new Vector2(0, 0);
            titleTextRect.anchorMax = new Vector2(1, 1);
            titleTextRect.sizeDelta = new Vector2(-60, 0); // Leave space for close button
            titleTextRect.anchoredPosition = new Vector2(10, 0);

            // Create Close Button
            GameObject closeButtonObj = new GameObject("CloseButton");
            closeButtonObj.transform.SetParent(titleBarObj.transform, false);
            Image closeButtonImage = closeButtonObj.AddComponent<Image>();
            closeButtonImage.color = new Color(0.5f, 0.5f, 0.5f, 1f);

            Button closeButton = closeButtonObj.AddComponent<Button>();
            ColorBlock colors = closeButton.colors;
            colors.normalColor = new Color(0.5f, 0.5f, 0.5f, 1f);
            colors.highlightedColor = new Color(0.8f, 0.2f, 0.2f, 1f);
            colors.pressedColor = new Color(0.6f, 0.1f, 0.1f, 1f);
            closeButton.colors = colors;
            closeButton.onClick.AddListener(OnCloseButtonClicked);

            RectTransform closeButtonRect = closeButtonObj.GetComponent<RectTransform>();
            closeButtonRect.anchorMin = new Vector2(1, 0);
            closeButtonRect.anchorMax = new Vector2(1, 1);
            closeButtonRect.pivot = new Vector2(1, 0.5f);
            closeButtonRect.sizeDelta = new Vector2(30, 0);
            closeButtonRect.anchoredPosition = new Vector2(0, 0);

            // Create Close Button Text (X)
            GameObject closeButtonTextObj = new GameObject("Text");
            closeButtonTextObj.transform.SetParent(closeButtonObj.transform, false);
            Text closeButtonText = closeButtonTextObj.AddComponent<Text>();
            closeButtonText.text = "X";
            closeButtonText.color = Color.white;
            closeButtonText.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
            closeButtonText.fontSize = 16;
            closeButtonText.alignment = TextAnchor.MiddleCenter;
            closeButtonText.fontStyle = FontStyle.Bold;

            RectTransform closeButtonTextRect = closeButtonTextObj.GetComponent<RectTransform>();
            closeButtonTextRect.anchorMin = Vector2.zero;
            closeButtonTextRect.anchorMax = Vector2.one;
            closeButtonTextRect.sizeDelta = Vector2.zero;
            closeButtonTextRect.anchoredPosition = Vector2.zero;

            // Create Content Area
            GameObject contentAreaObj = new GameObject("ContentArea");
            contentAreaObj.transform.SetParent(transform, false);
            RectTransform contentAreaRect = contentAreaObj.AddComponent<RectTransform>();
            contentAreaRect.anchorMin = new Vector2(0, 0);
            contentAreaRect.anchorMax = new Vector2(1, 1);
            contentAreaRect.sizeDelta = new Vector2(0, -titleBarHeight);
            contentAreaRect.anchoredPosition = new Vector2(0, 0);

            // Create Placeholder Text
            GameObject placeholderTextObj = new GameObject("PlaceholderText");
            placeholderTextObj.transform.SetParent(contentAreaObj.transform, false);
            Text placeholderText = placeholderTextObj.AddComponent<Text>();
            placeholderText.text = "Content Area";
            placeholderText.color = new Color(0.8f, 0.8f, 0.8f, 1f);
            placeholderText.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
            placeholderText.fontSize = 12;
            placeholderText.alignment = TextAnchor.MiddleCenter;

            RectTransform placeholderTextRect = placeholderTextObj.GetComponent<RectTransform>();
            placeholderTextRect.anchorMin = Vector2.zero;
            placeholderTextRect.anchorMax = Vector2.one;
            placeholderTextRect.sizeDelta = Vector2.zero;
            placeholderTextRect.anchoredPosition = Vector2.zero;
        }

        /// <summary>
        /// Called when pointer is pressed down on the title bar
        /// </summary>
        public void OnTitleBarPointerDown(Vector2 screenPosition)
        {
            isDragging = true;
            RectTransform parentRect = rectTransform.parent as RectTransform;
            if (parentRect != null)
            {
                RectTransformUtility.ScreenPointToLocalPointInRectangle(
                    parentRect,
                    screenPosition,
                    null,
                    out Vector2 localPoint
                );
                // Calculate offset from mouse position to window's current position
                dragOffset = localPoint - rectTransform.anchoredPosition;
            }
        }

        /// <summary>
        /// Handles window dragging in Update loop
        /// </summary>
        private void HandleDragging()
        {
            if (isDragging)
            {
                if (Mouse.current.leftButton.isPressed)
                {
                    Vector2 mousePosition = Mouse.current.position.ReadValue();
                    RectTransform parentRect = rectTransform.parent as RectTransform;
                    if (parentRect != null)
                    {
                        RectTransformUtility.ScreenPointToLocalPointInRectangle(
                            parentRect,
                            mousePosition,
                            null,
                            out Vector2 localPoint
                        );
                        rectTransform.anchoredPosition = localPoint - dragOffset;
                    }
                }
                else
                {
                    isDragging = false;
                }
            }
        }

        /// <summary>
        /// Called when close button is clicked
        /// </summary>
        private void OnCloseButtonClicked()
        {
            Destroy(gameObject);
        }

        /// <summary>
        /// Sets the window title
        /// </summary>
        public void SetTitle(string title)
        {
            windowTitle = title;
            Transform titleTextTransform = transform.Find("TitleBar/TitleText");
            if (titleTextTransform != null)
            {
                Text titleText = titleTextTransform.GetComponent<Text>();
                if (titleText != null)
                {
                    titleText.text = title;
                }
            }
        }
    }

    /// <summary>
    /// Helper component for handling title bar drag events
    /// </summary>
    public class TitleBarDragHandler : MonoBehaviour, IPointerDownHandler
    {
        private Window window;

        public void Initialize(Window windowComponent)
        {
            window = windowComponent;
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            if (window != null)
            {
                window.OnTitleBarPointerDown(eventData.position);
            }
        }
    }
}
