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

describe('scroll-lock', () => {
  beforeEach(() => {
    resetDOM();
    document.body.style.overflow = '';
  });

  it('connect sets body overflow:hidden + active attribute', () => {
    const host = mountHost();
    const inst = connectTrait(scrollLock, host);
    expect(document.body.style.overflow).toBe('hidden');
    expect(host.hasAttribute('data-scroll-lock-active')).toBe(true);
    // Balanced disconnect to keep the module-level lockCount honest for sibling tests.
    inst.disconnect(host);
  });

  it('disconnect restores body overflow + clears attribute', () => {
    document.body.style.overflow = 'auto';
    const host = mountHost();
    const inst = connectTrait(scrollLock, host);
    inst.disconnect(host);
    expect(document.body.style.overflow).toBe('auto');
    expect(host.hasAttribute('data-scroll-lock-active')).toBe(false);
  });

  it('refcounted — disconnect order does not unlock until last consumer leaves', () => {
    // The trait is module-scoped (lockCount + savedOverflow live in module state).
    // Snapshot the current state so this assertion is independent of test order.
    const startOverflow = document.body.style.overflow;
    const a = mountHost();
    const b = mountHost();
    const instA = connectTrait(scrollLock, a);
    const instB = connectTrait(scrollLock, b);
    expect(document.body.style.overflow).toBe('hidden');
    instA.disconnect(a);
    // Still locked because b is still active
    expect(document.body.style.overflow).toBe('hidden');
    instB.disconnect(b);
    // Restored to whatever it was when the *first* lock acquired it
    expect(document.body.style.overflow).toBe(startOverflow);
  });
});
