using UnityEngine;
using UnityEngine.EventSystems;

public class PuzzlePieceHandler : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
  #region 拖拽相关变量
  private RectTransform rt;
  private PolygonCollider2D pc2d;
  private Canvas canvas;
  private CanvasGroup cg;
  private bool isDragging = false;
  private Vector2 dragOffset;
  #endregion

  private bool isPlaced = false;

  #region 吸附相关变量
  [SerializeField] private Vector2 targetPosition = Vector2.zero;
  private float snapThreshold = 100f;
  #endregion

  // ==================================================

  private void Start() => Init();
  public void OnPointerDown(PointerEventData ped) => WhenPointerDown(ped);
  public void OnDrag(PointerEventData ped) => WhenDrag(ped);
  public void OnPointerUp(PointerEventData ped) => WhenPointerUp(ped);

  // ==================================================

  private void Init()
  {
    rt = GetComponent<RectTransform>();
    pc2d = GetComponent<PolygonCollider2D>();
    canvas = GetComponentInParent<Canvas>();
    cg = GetComponent<CanvasGroup>();

    if (targetPosition == Vector2.zero) { targetPosition = rt.anchoredPosition; }
  }

  // ==================================================

  private void WhenPointerDown(PointerEventData ped)
  {
    if (isPlaced) { return; }
    if (!IsPointerOverCollider(ped)) { return; }

    isDragging = true;

    // 🎯 修复：在Canvas的坐标空间中计算偏移量
    Vector2 canvasLocalPoint;
    if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
        canvas.transform as RectTransform,
        ped.position,
        ped.pressEventCamera,
        out canvasLocalPoint))
    {
      // 计算鼠标位置与碎片当前位置在Canvas空间中的偏移量
      dragOffset = canvasLocalPoint - rt.anchoredPosition;
    }

    transform.SetAsLastSibling();

    if (cg != null)
    {
      cg.alpha = 0.8f;
      cg.blocksRaycasts = false;
    }
  }

  private void WhenDrag(PointerEventData ped)
  {
    if (!isDragging || isPlaced) { return; }

    // 将屏幕坐标转换为UI局部坐标
    Vector2 localPoint;
    if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
        canvas.transform as RectTransform,
        ped.position,
        ped.pressEventCamera,
        out localPoint))
    {
      // 🎯 修复：直接使用Canvas坐标减去偏移量
      rt.anchoredPosition = localPoint - dragOffset;
    }
  }

  private void WhenPointerUp(PointerEventData ped)
  {
    if (!isDragging) { return; }

    isDragging = false;

    if (cg != null)
    {
      cg.alpha = 1f;
      cg.blocksRaycasts = true;
    }

    CheckSnapToTarget();
  }

  // ==================================================

  /// <summary>
  /// 检查鼠标是否在PolygonCollider2D范围内
  /// </summary>
  private bool IsPointerOverCollider(PointerEventData eventData)
  {
    Vector3 worldPoint;
    RectTransformUtility.ScreenPointToWorldPointInRectangle(
        rt, eventData.position, eventData.pressEventCamera, out worldPoint);

    return pc2d.OverlapPoint(worldPoint);
  }

  /// <summary>
  /// 检查并执行吸附到目标位置
  /// </summary>
  private void CheckSnapToTarget()
  {
    if (isPlaced) { return; }

    float distance = Vector2.Distance(rt.anchoredPosition, targetPosition);

    if (distance <= snapThreshold)
    {
      SnapToTarget();
    }
  }

  // ==================================================

  /// <summary>
  /// 吸附到目标位置
  /// </summary>
  private void SnapToTarget()
  {
    rt.anchoredPosition = targetPosition;
    SetPlaced(true);
    // Debug.Log($"碎片 {gameObject.name} 已吸附到正确位置");
  }

  // 设置碎片为已放置状态
  public void SetPlaced(bool placed)
  {
    isPlaced = placed;
    if (cg != null)
    {
      cg.blocksRaycasts = !placed;
    }

    if (pc2d != null)
    {
      pc2d.enabled = !placed;
    }
  }

  public bool CheckPlaced() => isPlaced;

  // ==================================================

  [ContextMenu("DEBUG_SetTargetPosition")]
  private void DEBUG_SetTargetPosition() => targetPosition = rt.anchoredPosition;

  [ContextMenu("DEBUG_Move2TargetPosition")]
  private void DEBUG_Move2TargetPosition()
  {
    Init();
    rt.anchoredPosition = targetPosition;
  }
}