import { describe, it, expect, beforeEach } from 'vitest';
import { draggable } from './draggable.js';
import { mountHost, connectTrait, spyEvent, resetDOM } from '../test-helpers.js';

function pointer(host, type, x, y) {
  const ev = new PointerEvent(type, { clientX: x, clientY: y, pointerId: 1, bubbles: true });
  host.dispatchEvent(ev);
}

describe('draggable', () => {
  beforeEach(resetDOM);

  it('pointerdown sets data-draggable-dragging', () => {
    const host = mountHost();
    connectTrait(draggable, host);
    pointer(host, 'pointerdown', 10, 10);
    expect(host.hasAttribute('data-draggable-dragging')).toBe(true);
  });

  it('pointermove during drag updates translate', () => {
    const host = mountHost();
    connectTrait(draggable, host);
    pointer(host, 'pointerdown', 10, 10);
    pointer(host, 'pointermove', 30, 50);
    expect(host.style.translate).toContain('20px');
    expect(host.style.translate).toContain('40px');
  });

  it('pointerup fires drag-end with x,y in detail and clears dragging', () => {
    const host = mountHost();
    connectTrait(draggable, host);
    const spy = spyEvent(host, 'drag-end');
    pointer(host, 'pointerdown', 0, 0);
    pointer(host, 'pointermove', 25, 75);
    pointer(host, 'pointerup', 25, 75);
    expect(host.hasAttribute('data-draggable-dragging')).toBe(false);
    expect(spy.count).toBe(1);
    expect(spy.last.x).toBe(25);
    expect(spy.last.y).toBe(75);
  });

  it('respects [disabled] — no drag, no event', () => {
    const host = mountHost('div', { disabled: '' });
    connectTrait(draggable, host);
    const spy = spyEvent(host, 'drag-end');
    pointer(host, 'pointerdown', 0, 0);
    pointer(host, 'pointermove', 50, 50);
    pointer(host, 'pointerup', 50, 50);
    expect(host.hasAttribute('data-draggable-dragging')).toBe(false);
    expect(spy.count).toBe(0);
  });

  it('disconnect removes listeners + dragging attribute', () => {
    const host = mountHost();
    const inst = connectTrait(draggable, host);
    pointer(host, 'pointerdown', 0, 0);
    inst.disconnect(host);
    expect(host.hasAttribute('data-draggable-dragging')).toBe(false);
  });
});
