import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Dialog } from '../Dialog';

describe('<Dialog>', () => {
    it('renders nothing when closed', () => {
        render(
            <Dialog isOpen={false} onClose={() => {}} title="Hi">
                body
            </Dialog>,
        );
        expect(screen.queryByRole('dialog')).toBeNull();
    });

    it('renders a modal dialog with an accessible name when open', () => {
        render(
            <Dialog isOpen onClose={() => {}} title="Settings">
                body
            </Dialog>,
        );
        expect(screen.getByRole('dialog', { name: 'Settings' })).toBeInTheDocument();
    });

    it('closes on Escape and moves focus into the dialog', async () => {
        const onClose = jest.fn();
        render(
            <Dialog isOpen onClose={onClose} title="Settings">
                body
            </Dialog>,
        );
        expect(screen.getByRole('dialog').contains(document.activeElement)).toBe(true);
        await userEvent.keyboard('{Escape}');
        expect(onClose).toHaveBeenCalledTimes(1);
    });

    // Regression: parents pass an inline onClose (new identity every render).
    // The focus-management effect must NOT depend on onClose — otherwise it
    // re-runs on each parent re-render and panel.focus() steals focus out of an
    // input on every keystroke, blocking typing.
    it('does not re-steal focus when the parent re-renders (new onClose identity)', () => {
        const { rerender } = render(
            <Dialog isOpen onClose={() => {}} title="Form">
                <input aria-label="name" />
            </Dialog>,
        );
        const input = screen.getByLabelText('name');
        input.focus();
        expect(document.activeElement).toBe(input);

        // Re-render with a brand-new inline onClose, as a controlled parent does
        // on every keystroke.
        rerender(
            <Dialog isOpen onClose={() => {}} title="Form">
                <input aria-label="name" />
            </Dialog>,
        );

        expect(document.activeElement).toBe(input);
    });
});
