// Drag-and-drop hook for cards — supports:
// - Reorder within the hand (drop on another card)
// - Drag a card from hand into staging area (drop on .staging-drop)
// - Drag a card from staging back to hand
// - Drag to discard pile (drop on .discard-drop)

const { useRef: dndUseRef, useState: dndUseS, useEffect: dndUseE, useCallback: dndUseC } = React;

function useCardDrag({ onReorder, onStage, onUnstage, onDiscardDrop, canInteract }) {
  const stateRef = dndUseRef({ dragging: null, origin: null, ghost: null, lastOverId: null });
  const [dragId, setDragId] = dndUseS(null);
  const [hoverId, setHoverId] = dndUseS(null);
  const [hoverZone, setHoverZone] = dndUseS(null);

  function startDrag(e, cardId, source /* 'hand' | 'staging' */) {
    if (!canInteract()) return;
    // only primary button for mouse
    if (e.button !== undefined && e.button !== 0) return;
    const target = e.currentTarget;
    const rect = target.getBoundingClientRect();
    const point = e.touches ? e.touches[0] : e;

    stateRef.current = {
      dragging: cardId,
      source,
      origin: { x: point.clientX, y: point.clientY, cardLeft: rect.left, cardTop: rect.top },
      target,
      ghost: null,
      started: false,
      lastZone: null
    };

    document.addEventListener('pointermove', onMove);
    document.addEventListener('pointerup', onUp);
    document.addEventListener('pointercancel', onUp);
  }

  function beginDragVisual(s) {
    const target = s.target;
    if (!target) return;
    const rect = target.getBoundingClientRect();
    const ghost = target.cloneNode(true);
    ghost.classList.add('drag-ghost');
    ghost.style.position = 'fixed';
    ghost.style.left = rect.left + 'px';
    ghost.style.top = rect.top + 'px';
    ghost.style.width = rect.width + 'px';
    ghost.style.height = rect.height + 'px';
    ghost.style.pointerEvents = 'none';
    ghost.style.zIndex = 9999;
    ghost.style.transform = 'scale(1.08) rotate(-2deg)';
    ghost.style.transition = 'transform .15s ease';
    ghost.style.boxShadow = '0 24px 48px -8px rgba(0,0,0,.7), 0 0 0 2px rgba(62,244,255,.5)';
    document.body.appendChild(ghost);
    target.classList.add('card-being-dragged');
    s.ghost = ghost;
    s.started = true;
    setDragId(s.dragging);
  }

  function onMove(e) {
    const s = stateRef.current;
    if (!s.dragging) return;
    const dx = e.clientX - s.origin.x;
    const dy = e.clientY - s.origin.y;

    // Threshold: only begin dragging after 5px movement (so taps still fire click)
    if (!s.started) {
      if (Math.hypot(dx, dy) < 6) return;
      beginDragVisual(s);
    }

    if (s.ghost) {
      s.ghost.style.transform = `translate(${dx}px, ${dy}px) scale(1.08) rotate(-2deg)`;
    }
    // Determine hover target
    const el = document.elementFromPoint(e.clientX, e.clientY);
    if (!el) return;

    // Zones
    const stagingZone = el.closest('.staging-drop');
    const discardZone = el.closest('.discard-drop');
    const handCard = el.closest('.player-hand .card');

    if (discardZone) {
      setHoverZone('discard'); setHoverId(null); s.lastZone = 'discard';
    } else if (stagingZone) {
      setHoverZone('staging'); setHoverId(null); s.lastZone = 'staging';
    } else if (handCard && handCard.dataset.cardId !== s.dragging) {
      setHoverZone('hand'); setHoverId(handCard.dataset.cardId); s.lastZone = 'hand';
    } else if (handCard) {
      setHoverZone('hand'); setHoverId(null); s.lastZone = 'hand';
    } else {
      setHoverZone(null); setHoverId(null); s.lastZone = null;
    }
  }

  function onUp(e) {
    const s = stateRef.current;
    if (!s.dragging) return;
    document.removeEventListener('pointermove', onMove);
    document.removeEventListener('pointerup', onUp);
    document.removeEventListener('pointercancel', onUp);

    // If drag never started (just a tap), let click fire naturally
    if (!s.started) {
      stateRef.current = { dragging: null, origin: null, ghost: null };
      return;
    }

    const dragId = s.dragging;
    const zone = s.lastZone;
    const el = e ? document.elementFromPoint(e.clientX, e.clientY) : null;

    if (zone === 'staging' && s.source === 'hand') {
      onStage && onStage(dragId);
    } else if (zone === 'hand' && s.source === 'staging') {
      onUnstage && onUnstage(dragId);
    } else if (zone === 'hand' && s.source === 'hand') {
      const handCard = el && el.closest('.player-hand .card');
      if (handCard && handCard.dataset.cardId && handCard.dataset.cardId !== dragId) {
        onReorder && onReorder(dragId, handCard.dataset.cardId);
      }
    } else if (zone === 'discard' && s.source === 'hand') {
      onDiscardDrop && onDiscardDrop(dragId);
    }

    // Cleanup visuals
    document.querySelectorAll('.card-being-dragged').forEach(el => el.classList.remove('card-being-dragged'));
    if (s.ghost) {
      s.ghost.style.transition = 'all .2s ease';
      s.ghost.style.opacity = '0';
      s.ghost.style.transform += ' scale(.8)';
      const g = s.ghost;
      setTimeout(() => g.remove(), 200);
    }
    stateRef.current = { dragging: null, origin: null, ghost: null };
    setDragId(null); setHoverId(null); setHoverZone(null);

    // Suppress the click that would follow this pointerup after a real drag
    const suppressClick = (ev) => { ev.stopPropagation(); ev.preventDefault(); };
    window.addEventListener('click', suppressClick, { capture: true, once: true });
  }

  return { startDrag, dragId, hoverId, hoverZone };
}

window.useCardDrag = useCardDrag;
