import { describe, it, expect, vi, afterEach } from 'vitest';
import { act, createElement, type ReactNode } from 'react';
import { createRoot } from 'react-dom/client';

( globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean } ).IS_REACT_ACT_ENVIRONMENT = true;

import EditorErrorBoundary from './EditorErrorBoundary';

function Boom(): null {
	throw new Error( 'kaboom' );
}

function render( child: ReactNode ) {
	const container = document.createElement( 'div' );
	document.body.appendChild( container );
	const root = createRoot( container );
	act( () => {
		root.render( createElement( EditorErrorBoundary, null, child ) );
	} );
	return {
		container,
		cleanup: () => {
			act( () => root.unmount() );
			container.remove();
		},
	};
}

afterEach( () => {
	vi.restoreAllMocks();
} );

describe( 'EditorErrorBoundary', () => {
	it( 'renders its children when they do not throw', () => {
		const { container, cleanup } = render(
			createElement( 'span', null, 'editor here' )
		);
		expect( container.textContent ).toContain( 'editor here' );
		cleanup();
	} );

	it( 'renders an alert fallback when a child throws instead of blanking', () => {
		// React logs the caught error to console.error; silence it for the run.
		vi.spyOn( console, 'error' ).mockImplementation( () => {} );
		const { container, cleanup } = render( createElement( Boom ) );
		const alert = container.querySelector( '[role="alert"]' );
		expect( alert ).not.toBeNull();
		expect( alert!.textContent ).toContain( 'The editor hit an error' );
		cleanup();
	} );
} );
