import { useRef, useState } from 'react';

export default function usePwaSheetSwipe(onClose, { threshold = 92, velocity = 0.55 } = {}) {
  const pointerId = useRef(null);
  const start = useRef({ x: 0, y: 0, time: 0 });
  const last = useRef({ y: 0, time: 0 });
  const suppressClick = useRef(false);
  const [offsetY, setOffsetY] = useState(0);
  const [isDragging, setIsDragging] = useState(false);
  const [isClosing, setIsClosing] = useState(false);

  const reset = () => {
    pointerId.current = null;
    setIsDragging(false);
    setOffsetY(0);
  };

  const closeWithMotion = () => {
    suppressClick.current = true;
    setIsDragging(false);
    setIsClosing(true);
    setOffsetY(Math.min(window.innerHeight, 720));
    window.setTimeout(() => {
      setIsClosing(false);
      setOffsetY(0);
      onClose();
    }, 170);
  };

  const onPointerDown = (event) => {
    if (event.pointerType === 'mouse' && event.button !== 0) return;

    pointerId.current = event.pointerId;
    const now = performance.now();
    start.current = { x: event.clientX, y: event.clientY, time: now };
    last.current = { y: event.clientY, time: now };
    suppressClick.current = false;
    setIsClosing(false);
    setIsDragging(false);
    setOffsetY(0);
  };

  const onPointerMove = (event) => {
    if (pointerId.current !== event.pointerId || isClosing) return;

    const dx = event.clientX - start.current.x;
    const dy = event.clientY - start.current.y;

    if (dy <= 0) {
      setOffsetY(0);
      return;
    }

    if (!isDragging && (dy < 8 || dy < Math.abs(dx))) return;

    event.currentTarget.setPointerCapture?.(event.pointerId);
    event.preventDefault();
    suppressClick.current = true;
    setIsDragging(true);
    setOffsetY(dy);
    last.current = { y: event.clientY, time: performance.now() };
  };

  const onPointerUp = (event) => {
    if (pointerId.current !== event.pointerId) return;

    const distance = Math.max(0, event.clientY - start.current.y);
    const elapsed = Math.max(1, performance.now() - start.current.time);
    const swipeVelocity = distance / elapsed;

    event.currentTarget.releasePointerCapture?.(event.pointerId);
    pointerId.current = null;

    if (distance >= threshold || swipeVelocity >= velocity) {
      closeWithMotion();
      return;
    }

    reset();
  };

  const onPointerCancel = (event) => {
    if (pointerId.current === event.pointerId) reset();
  };

  const onClickCapture = (event) => {
    if (!suppressClick.current) return;
    event.preventDefault();
    event.stopPropagation();
    suppressClick.current = false;
  };

  return {
    offsetY,
    isDragging,
    isClosing,
    swipeHandlers: {
      onPointerDown,
      onPointerMove,
      onPointerUp,
      onPointerCancel,
      onClickCapture,
    },
  };
}
