import { defineTrait } from '../define.js';

export const draggable = defineTrait({
  name: 'draggable',
  category: 'motion-positioning',
  description: 'Pointer drag to reposition',
  attributes: ['data-draggable-dragging'],
  events: ['drag-end'],
  config: [],
  setup({ host }) {
    let dragging = false;
    let startX = 0;
    let startY = 0;
    let originX = 0;
    let originY = 0;

    function isDisabled() {
      return host.hasAttribute('disabled');
    }

    function onPointerDown(e) {
      if (isDisabled()) return;
      dragging = true;
      startX = e.clientX;
      startY = e.clientY;

      // Parse current translate values. The trait writes to `style.translate`
      // (independent of `transform` in the modern CSS model). Read translate
      // first so subsequent drags pick up the current position, then fall back
      // to the transform matrix for callers that nudged via `transform`.
      const style = getComputedStyle(host);
      const t = style.translate;
      if (t && t !== 'none') {
        const parts = t.split(/\s+/).map(parseFloat);
        originX = parts[0] || 0;
        originY = parts[1] || 0;
      } else {
        const matrix = new DOMMatrixReadOnly(style.transform);
        originX = matrix.m41;
        originY = matrix.m42;
      }

      host.setPointerCapture(e.pointerId);
      host.setAttribute('data-draggable-dragging', '');
      host.style.touchAction = 'none';
    }

    function onPointerMove(e) {
      if (!dragging) return;
      const dx = e.clientX - startX;
      const dy = e.clientY - startY;
      const x = originX + dx;
      const y = originY + dy;
      host.style.translate = `${x}px ${y}px`;
    }

    function onPointerUp(e) {
      if (!dragging) return;
      dragging = false;
      host.removeAttribute('data-draggable-dragging');

      const dx = e.clientX - startX;
      const dy = e.clientY - startY;
      const x = originX + dx;
      const y = originY + dy;

      host.dispatchEvent(new CustomEvent('drag-end', {
        bubbles: true,
        detail: { x, y },
      }));
    }

    host.addEventListener('pointerdown', onPointerDown);
    host.addEventListener('pointermove', onPointerMove);
    host.addEventListener('pointerup', onPointerUp);

    return () => {
      host.removeEventListener('pointerdown', onPointerDown);
      host.removeEventListener('pointermove', onPointerMove);
      host.removeEventListener('pointerup', onPointerUp);
      host.removeAttribute('data-draggable-dragging');
      host.style.touchAction = '';
    };
  },
});
