using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems; // IPointerEnterHandler, IPointerExitHandler 인터페이스 사용
using UnityEngine.UI;          // Selectable 컴포넌트 사용 (버튼 등의 상호작용 가능 여부 확인)

namespace UVC.UI.Tooltip
{
    /// <summary>
    /// UI 요소에 부착하여 마우스 오버 시 툴팁을 표시하고 마우스 아웃 시 툴팁을 숨기는 기능을 제공합니다.
    /// TooltipManager와 함께 작동하며, 마우스 이벤트 감지 후 TooltipManager에 툴팁 관리를 위임합니다.
    /// 
    /// 사용 방법:
    /// 1. 툴팁을 표시하고자 하는 UI 요소(예: Button, Image 등)에 이 컴포넌트를 추가합니다.
    /// 2. Inspector 창이나 코드를 통해 'Tooltip' 프로퍼티에 표시할 텍스트 또는 다국어 키를 설정합니다.
    /// 3. TooltipManager가 초기화되어 있어야 하며, 이 핸들러의 액션들을 TooltipManager의 메서드에 연결해야 합니다.
    ///    (일반적으로 다른 관리 클래스(예: ToolbarView)에서 이 연결을 수행합니다.)
    /// 
    /// 예시 (ToolbarView.cs에서의 설정 부분):
    /// <code>
    /// // ... ToolbarView.cs 내에서 버튼 생성 시 ...
    /// GameObject buttonGameObject = Instantiate(buttonPrefab);
    /// TooltipHandler tooltipHandler = buttonGameObject.AddComponent<TooltipHandler>();
    /// tooltipHandler.Tooltip = "my_tooltip_key"; // 표시할 툴팁 내용 또는 다국어 키
    /// 
    /// // TooltipManager의 메서드와 연결
    /// if (TooltipManager.Instance != null && TooltipManager.Instance.IsInitialized)
    /// {
    ///     tooltipHandler.OnPointerEnterAction = TooltipManager.Instance.HandlePointerEnter;
    ///     tooltipHandler.OnPointerExitAction = TooltipManager.Instance.HandlePointerExit;
    /// }
    /// </code>
    /// </summary>
    public class TooltipHandler : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
    {
        /// <summary>
        /// 마우스 포인터가 UI 요소에 진입했을 때 호출될 액션입니다.
        /// TooltipManager.Instance.HandlePointerEnter 메서드에 연결됩니다.
        /// 첫 번째 string 매개변수는 툴팁 내용(또는 키), 두 번째 Vector3는 마우스 위치입니다.
        /// </summary>
        public System.Action<string, Vector3> OnPointerEnterAction;

        /// <summary>
        /// 마우스 포인터가 UI 요소에서 벗어났을 때 호출될 액션입니다.
        /// TooltipManager.Instance.HandlePointerExit 메서드에 연결됩니다.
        /// </summary>
        public System.Action OnPointerExitAction;

        /// <summary>
        /// 이 UI 요소에 표시될 툴팁의 내용 또는 다국어 키입니다.
        /// Inspector에서 직접 설정하거나 코드로 할당할 수 있습니다.
        /// </summary>
        /// <example>
        /// <code>
        /// TooltipHandler handler = myButton.GetComponent<TooltipHandler>();
        /// if (handler != null)
        /// {
        ///     handler.Tooltip = "버튼_설명_키"; // 다국어 키 사용
        ///     // 또는 handler.Tooltip = "이 버튼은 저장 기능을 수행합니다."; // 직접 텍스트 사용
        /// }
        /// </code>
        /// </example>
        public string Tooltip { get; set; }

        private Coroutine _showTooltipCoroutine; // 툴팁 표시 지연을 위한 코루틴 참조
        private const float TooltipDelay = 0.5f; // 툴팁 표시까지의 지연 시간 (초 단위)

        /// <summary>
        /// 마우스 포인터가 이 UI 요소의 영역 안으로 들어왔을 때 호출됩니다. (IPointerEnterHandler 인터페이스 구현)
        /// 설정된 Tooltip 내용이 있고, 연결된 Selectable 컴포넌트가 상호작용 가능 상태일 때만 작동합니다.
        /// 지정된 지연 시간(TooltipDelay) 후에 OnPointerEnterAction을 호출하여 툴팁 표시를 요청합니다.
        /// </summary>
        /// <param name="eventData">포인터 이벤트 데이터입니다.</param>
        public void OnPointerEnter(PointerEventData eventData)
        {
            // 툴팁 내용이 있고, 이 게임오브젝트에 Selectable 컴포넌트가 있거나 없거나, 있다면 interactable 상태일 때만
            Selectable selectable = gameObject.GetComponent<Selectable>();
            if (!string.IsNullOrEmpty(Tooltip) && (selectable == null || selectable.interactable))
            {
                // 이전에 실행 중이던 코루틴이 있다면 중지 (빠르게 들어왔다 나갔다 반복하는 경우 대비)
                if (_showTooltipCoroutine != null)
                {
                    StopCoroutine(_showTooltipCoroutine);
                }
                // 새 코루틴 시작하여 지연 후 툴팁 표시
                _showTooltipCoroutine = StartCoroutine(ShowTooltipAfterDelayCoroutine(Tooltip, Input.mousePosition));
            }
        }

        /// <summary>
        /// 지정된 시간(TooltipDelay)만큼 대기한 후, OnPointerEnterAction을 호출하여 툴팁 표시를 요청하는 코루틴입니다.
        /// </summary>
        /// <param name="tooltip">표시할 툴팁 내용 또는 다국어 키입니다.</param>
        /// <param name="mousePosition">현재 마우스 포인터의 화면 좌표입니다.</param>
        private IEnumerator ShowTooltipAfterDelayCoroutine(string tooltip, Vector3 mousePosition)
        {
            yield return new WaitForSeconds(TooltipDelay); // 지정된 시간만큼 대기
            _showTooltipCoroutine = null; // 코루틴 완료 후 참조 null 처리
            OnPointerEnterAction?.Invoke(tooltip, mousePosition); // 연결된 액션 호출 (TooltipManager.HandlePointerEnter)
        }

        /// <summary>
        /// 마우스 포인터가 이 UI 요소의 영역 밖으로 나갔을 때 호출됩니다. (IPointerExitHandler 인터페이스 구현)
        /// 실행 중인 툴팁 표시 코루틴이 있다면 중지하고, OnPointerExitAction을 호출하여 툴팁 숨김을 요청합니다.
        /// </summary>
        /// <param name="eventData">포인터 이벤트 데이터입니다.</param>
        public void OnPointerExit(PointerEventData eventData)
        {
            // 실행 중인 툴팁 표시 코루틴이 있다면 중지 (마우스가 나가면 지연 중이던 툴팁 표시 취소)
            if (_showTooltipCoroutine != null)
            {
                StopCoroutine(_showTooltipCoroutine);
                _showTooltipCoroutine = null;
            }
            OnPointerExitAction?.Invoke(); // 연결된 액션 호출 (TooltipManager.HandlePointerExit)
        }

        /// <summary>
        /// 이 MonoBehaviour가 비활성화될 때 호출됩니다.
        /// 실행 중인 코루틴이 있다면 정리합니다.
        /// </summary>
        private void OnDisable()
        {
            if (_showTooltipCoroutine != null)
            {
                StopCoroutine(_showTooltipCoroutine);
                _showTooltipCoroutine = null;
            }
            // 만약 OnPointerExitAction이 즉시 호출되어야 한다면 아래 코드 추가
            // OnPointerExitAction?.Invoke(); 
        }

        /// <summary>
        /// 이 MonoBehaviour가 파괴될 때 호출됩니다.
        /// 실행 중인 코루틴이 있다면 정리합니다.
        /// </summary>
        private void OnDestroy()
        {
            if (_showTooltipCoroutine != null)
            {
                StopCoroutine(_showTooltipCoroutine);
                _showTooltipCoroutine = null;
            }
            // OnPointerEnterAction 및 OnPointerExitAction 참조 해제 (필요 시)
            OnPointerEnterAction = null;
            OnPointerExitAction = null;
        }
    }
}