// @vitest-environment jsdom
/**
 * Hook test for useBackdropClose — closes only when BOTH mousedown and the
 * subsequent click land on the backdrop itself (currentTarget === target).
 * Guards the drag-inside-release-on-backdrop case that a plain onClick would
 * wrongly treat as a backdrop click.
 */
import '../test/dom-setup';
import { describe, it, expect, vi } from 'vitest';
import { renderHook } from '@testing-library/react';
import { useBackdropClose } from './useBackdropClose';

// e.target === e.currentTarget when `onBackdrop` is true.
function mouseEvt(onBackdrop: boolean) {
  const node = {};
  return {
    target: onBackdrop ? node : {},
    currentTarget: node,
  } as unknown as React.MouseEvent;
}

describe('useBackdropClose', () => {
  it('closes on a genuine backdrop click (down + up on backdrop)', () => {
    const onClose = vi.fn();
    const { result } = renderHook(() => useBackdropClose(onClose));
    result.current.onMouseDown(mouseEvt(true));
    result.current.onClick(mouseEvt(true));
    expect(onClose).toHaveBeenCalledTimes(1);
  });

  it('does NOT close when mousedown started inside the modal', () => {
    const onClose = vi.fn();
    const { result } = renderHook(() => useBackdropClose(onClose));
    result.current.onMouseDown(mouseEvt(false)); // press inside content
    result.current.onClick(mouseEvt(true)); // released on backdrop
    expect(onClose).not.toHaveBeenCalled();
  });

  it('does NOT close when the click target is inside the modal', () => {
    const onClose = vi.fn();
    const { result } = renderHook(() => useBackdropClose(onClose));
    result.current.onMouseDown(mouseEvt(true));
    result.current.onClick(mouseEvt(false));
    expect(onClose).not.toHaveBeenCalled();
  });

  it('resets the down flag between interactions', () => {
    const onClose = vi.fn();
    const { result } = renderHook(() => useBackdropClose(onClose));
    // First: a backdrop click (closes once)
    result.current.onMouseDown(mouseEvt(true));
    result.current.onClick(mouseEvt(true));
    // Second: click without a fresh mousedown must not close again
    result.current.onClick(mouseEvt(true));
    expect(onClose).toHaveBeenCalledTimes(1);
  });
});
