using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

namespace KitsuneCafe.UI
{
  public class DragManipulator : PointerManipulator
  {
    public event Action Started = delegate { };
    public event Action Stopped = delegate { };
    public event Action<Vector2> Dragged = delegate { };

    private bool isDragging = false;
    private bool globalDrag = true;

    private VisualElement releaseTarget;

    public DragManipulator(VisualElement element, bool globalDrag = true)
    {
      target = element;
      this.globalDrag = globalDrag;
    }

    protected override void RegisterCallbacksOnTarget()
    {
      target.RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
    }

    private void OnAttachToPanel(AttachToPanelEvent evt)
    {
      releaseTarget = globalDrag ? target.panel.visualTree : target;
      target.RegisterCallback<PointerDownEvent>(OnPointerDown);
      releaseTarget.RegisterCallback<PointerMoveEvent>(OnPointerMove);
      releaseTarget.RegisterCallback<PointerUpEvent>(OnPointerUp);
    }

    protected override void UnregisterCallbacksFromTarget()
    {
      target.UnregisterCallback<AttachToPanelEvent>(OnAttachToPanel);
      target.UnregisterCallback<PointerDownEvent>(OnPointerDown);
      releaseTarget?.UnregisterCallback<PointerMoveEvent>(OnPointerMove);
      releaseTarget?.UnregisterCallback<PointerUpEvent>(OnPointerUp);
    }

    private void OnPointerDown(PointerDownEvent _)
    {
      isDragging = true;
      Started?.Invoke();
    }

    private void OnPointerMove(PointerMoveEvent evt)
    {
      if (isDragging)
      {
        Dragged?.Invoke(evt.deltaPosition);
      }
    }

    private void OnPointerUp(PointerUpEvent evt)
    {
      isDragging = false;
      Stopped?.Invoke();
    }
  }
}
