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

// Minimal smoke coverage. The droppable trait is authored against the
// apps/tasks/ DnD coordinator and assumes a sibling
// `draggable-list-item` trait dispatches `dnd:drop-target-change` /
// `dnd:drop` on the document. The cases below only exercise the trait's
// own surface (schema, attribute lifecycle, registry entry, cleanup) so
// the verify:traits gate stays green; the higher-fidelity DnD-flow tests
// belong with the Tasks UI initiative that owns the coordinator.

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

  it('schema shape is defined', () => {
    expect(droppable.schema.name).toBe('droppable');
    expect(droppable.schema.category).toBe('input-interaction');
    expect(droppable.schema.description.length).toBeGreaterThanOrEqual(11);
    expect(droppable.schema.events).toContain('dnd-drop-enter');
    // Source-side `dnd-drop` (on document, from the lifter) and target-side
    // `dnd-drop-receive` (on host) MUST be distinct names — sharing the name
    // recurses infinitely when the host event bubbles back to the document.
    expect(droppable.schema.events).toContain('dnd-drop-receive');
    expect(droppable.schema.events).not.toContain('dnd-drop');
  });

  it('connect assigns an id + sets the host attribute', () => {
    const host = mountHost('div');
    connectTrait(droppable, host);
    expect(host.getAttribute('data-droppable-id')).toBeTruthy();
  });

  it('disconnect removes the over attribute if set', () => {
    const host = mountHost('div');
    const inst = droppable();
    inst.connect(host);
    host.setAttribute('data-droppable-over', '');
    inst.disconnect(host);
    expect(host.hasAttribute('data-droppable-over')).toBe(false);
  });

  it('reconnect with the same host does not throw', () => {
    const host = mountHost('div');
    const inst = droppable();
    inst.connect(host);
    inst.disconnect(host);
    expect(() => {
      const inst2 = droppable();
      inst2.connect(host);
      inst2.disconnect(host);
    }).not.toThrow();
  });
});
