import {userEvent} from 'vitest/browser';
import {createElementFromHTML} from '../utils/dom.ts';
import {hideModal, initGlobalModal, showModal} from './modal.ts';
import {showErrorToast} from './toast.ts';
test('showModal blocks the page and restores focus until closed by actions, backdrop or unconsumed Escape on the topmost modal', async () => {
initGlobalModal();
document.body.innerHTML = `
`;
const opener = document.querySelector('#opener')!;
const modal = document.querySelector('.modal-dialog')!;
const onHidden = vi.fn();
let approve = false;
opener.focus();
showModal(modal, {onApprove: () => approve, onHidden});
const backdrop = modal.parentElement!;
expect(opener.inert).toBe(true);
expect(backdrop.inert).toBe(false);
expect(modal.getAttribute('aria-labelledby')).toBe(modal.querySelector('.header')!.id);
expect(document.body.classList.contains('modal-page-blocked')).toBe(true);
expect(modal.querySelector('.cancel')!.getAttribute('type')).toBe('button');
modal.querySelector('input')!.value = 'changed';
modal.querySelector('.ok')!.click();
expect(modal.open).toBe(true);
approve = true;
modal.querySelector('.ok')!.click();
expect(onHidden).toHaveBeenCalledOnce();
expect(modal.querySelector('input')!.value).toBe('');
expect(document.body.classList.contains('modal-page-blocked')).toBe(false);
expect(opener.inert).toBe(false);
expect(document.activeElement).toBe(opener);
for (const selector of ['.cancel', '.close-modal']) {
showModal(modal);
modal.querySelector(selector)!.click();
expect(modal.open).toBe(false);
}
showModal(modal);
await userEvent.click(modal.querySelector('input')!);
expect(modal.open).toBe(true);
backdrop.dispatchEvent(new PointerEvent('pointerdown'));
backdrop.click();
expect(modal.open).toBe(false);
showModal(modal);
document.addEventListener('keydown', (e) => e.preventDefault(), {once: true});
await userEvent.keyboard('{Escape}');
expect(modal.open).toBe(true);
const nested = createElementFromHTML('');
showModal(nested, {onHidden: () => nested.remove()});
const nestedBackdrop = nested.parentElement!;
expect(backdrop.inert).toBe(true);
await userEvent.keyboard('{Escape}');
expect(nestedBackdrop.isConnected).toBe(false);
expect(modal.open).toBe(true);
expect(backdrop.inert).toBe(false);
expect(opener.inert).toBe(true);
expect(modal.contains(document.activeElement)).toBe(true);
showErrorToast('error in modal');
expect(document.querySelector('.toastify.on')).not.toBeNull();
await userEvent.keyboard('{Escape}');
expect(modal.open).toBe(false);
expect(document.querySelector('.toastify.on')).toBeNull();
(document.activeElement as HTMLElement).blur();
showModal(modal);
hideModal(modal);
expect(document.activeElement).toBe(document.body);
showModal(modal, {onHidden: () => modal.remove()});
hideModal(modal);
opener.focus();
expect(backdrop.isConnected).toBe(false);
expect(document.activeElement).toBe(opener);
});