/**
 * 마우스·터치·펜 입력을 통합한 드래그/포인터 좌표 유틸
 */

export interface ClientXY {
  x: number;
  y: number;
}

type ReactPointerLike =
  | React.MouseEvent
  | React.TouchEvent
  | React.PointerEvent;

/** React 합성 이벤트에서 client 좌표 추출 */
export function clientXYFromReact(e: ReactPointerLike): ClientXY {
  if ('touches' in e && e.touches.length > 0) {
    return { x: e.touches[0].clientX, y: e.touches[0].clientY };
  }
  if ('changedTouches' in e && e.changedTouches.length > 0) {
    return { x: e.changedTouches[0].clientX, y: e.changedTouches[0].clientY };
  }
  const pe = e as React.MouseEvent | React.PointerEvent;
  return { x: pe.clientX, y: pe.clientY };
}

/** window/document 네이티브 이벤트에서 client 좌표 추출 */
export function clientXYFromNative(e: Event): ClientXY | null {
  if (e instanceof TouchEvent) {
    const t = e.touches[0] ?? e.changedTouches[0];
    if (!t) return null;
    return { x: t.clientX, y: t.clientY };
  }
  if (e instanceof MouseEvent || e instanceof PointerEvent) {
    return { x: e.clientX, y: e.clientY };
  }
  return null;
}

export interface BindWindowDragOptions {
  /** 터치 드래그 중 페이지 스크롤 방지 (기본 true) */
  preventTouchScroll?: boolean;
}

/**
 * 드래그 시작 후 window 에 move/end 리스너 등록.
 * pointer + mouse + touch 모두 수신 (구형 브라우저·iOS 대응).
 */
export function bindWindowDrag(
  onMove: (xy: ClientXY, ev: Event) => void,
  onEnd: () => void,
  options: BindWindowDragOptions = {},
): () => void {
  const { preventTouchScroll = true } = options;

  const move = (ev: Event) => {
    const xy = clientXYFromNative(ev);
    if (!xy) return;
    if (preventTouchScroll && ev.cancelable && (ev instanceof TouchEvent || ev.type === 'touchmove')) {
      ev.preventDefault();
    }
    onMove(xy, ev);
  };

  const end = () => onEnd();

  window.addEventListener('pointermove', move);
  window.addEventListener('pointerup', end);
  window.addEventListener('pointercancel', end);
  window.addEventListener('mousemove', move);
  window.addEventListener('mouseup', end);
  window.addEventListener('touchmove', move, { passive: !preventTouchScroll });
  window.addEventListener('touchend', end);
  window.addEventListener('touchcancel', end);

  return () => {
    window.removeEventListener('pointermove', move);
    window.removeEventListener('pointerup', end);
    window.removeEventListener('pointercancel', end);
    window.removeEventListener('mousemove', move);
    window.removeEventListener('mouseup', end);
    window.removeEventListener('touchmove', move);
    window.removeEventListener('touchend', end);
    window.removeEventListener('touchcancel', end);
  };
}

/** 드래그 핸들(타이틀바 등)에 붙일 공통 스타일 */
export const DRAG_HANDLE_TOUCH_STYLE: React.CSSProperties = {
  touchAction: 'none',
};

/** primary 버튼(마우스 왼쪽 / 터치)만 허용 */
export function isPrimaryPointerButton(e: { button: number; pointerType: string }): boolean {
  return e.button === 0;
}
