// useDragScroll — make any horizontally-scrollable element draggable with the mouse.
// Touch already works natively via overflow-x: auto. This adds desktop drag.
//
// Usage:
//   const ref = React.useRef(null);
//   useDragScroll(ref);
//   <div ref={ref} style={{overflowX:'auto'}}>...</div>
//
// Notes:
//   - Ignores drags that start on form controls (button, a, input, video, label).
//   - Only activates after >5px movement so plain clicks still work.
//   - Adds `cursor: grab` on idle, `grabbing` while dragging.

const useDragScroll = (ref) => {
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return undefined;

    // Skip on touch-primary devices — native overflow scroll handles it,
    // and adding pointer listeners can interfere with iOS Safari pan gestures.
    if (typeof window !== 'undefined' && window.matchMedia &&
        window.matchMedia('(hover: none) and (pointer: coarse)').matches) {
      return undefined;
    }

    let isDown = false;
    let isDragging = false;
    let startX = 0;
    let startScroll = 0;
    const THRESHOLD = 5;

    const setCursor = (c) => { el.style.cursor = c; };
    setCursor('grab');

    const isInteractive = (target) => {
      if (!target) return false;
      // Walk up a few levels for safety
      let node = target;
      for (let i = 0; i < 4 && node && node !== el; i++) {
        const tag = node.tagName;
        if (tag === 'BUTTON' || tag === 'A' || tag === 'INPUT' ||
            tag === 'TEXTAREA' || tag === 'SELECT' || tag === 'VIDEO' ||
            tag === 'LABEL') return true;
        node = node.parentNode;
      }
      return false;
    };

    const onPointerDown = (e) => {
      if (e.pointerType === 'touch') return; // native touch handles this
      if (e.button !== 0) return;
      if (isInteractive(e.target)) return;
      isDown = true;
      isDragging = false;
      startX = e.clientX;
      startScroll = el.scrollLeft;
    };

    const onPointerMove = (e) => {
      if (!isDown) return;
      const dx = e.clientX - startX;
      if (!isDragging && Math.abs(dx) > THRESHOLD) {
        isDragging = true;
        setCursor('grabbing');
        try { el.setPointerCapture(e.pointerId); } catch (err) {}
        // suppress text selection during drag
        document.body.style.userSelect = 'none';
      }
      if (isDragging) {
        e.preventDefault();
        el.scrollLeft = startScroll - dx;
      }
    };

    const finish = (e) => {
      if (!isDown) return;
      const wasDragging = isDragging;
      isDown = false;
      isDragging = false;
      setCursor('grab');
      document.body.style.userSelect = '';
      if (e && e.pointerId !== undefined) {
        try { el.releasePointerCapture(e.pointerId); } catch (err) {}
      }
      // If the drag actually moved, swallow the click that follows so cards don't open accidentally.
      if (wasDragging) {
        const swallow = (ev) => { ev.stopPropagation(); ev.preventDefault(); };
        el.addEventListener('click', swallow, { capture: true, once: true });
      }
    };

    el.addEventListener('pointerdown', onPointerDown);
    el.addEventListener('pointermove', onPointerMove);
    el.addEventListener('pointerup', finish);
    el.addEventListener('pointercancel', finish);
    el.addEventListener('pointerleave', finish);

    return () => {
      el.removeEventListener('pointerdown', onPointerDown);
      el.removeEventListener('pointermove', onPointerMove);
      el.removeEventListener('pointerup', finish);
      el.removeEventListener('pointercancel', finish);
      el.removeEventListener('pointerleave', finish);
      document.body.style.userSelect = '';
    };
  }, [ref]);
};

window.useDragScroll = useDragScroll;
