/**
 * @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md.
 */

import { isFocusable } from './is-focusable';
import { timeout } from './timeout';

/**
 * Focuses the first interactive/focusable element within a container.
 * If the container itself is focusable, it will be focused.
 * Otherwise, the first focusable child element will be focused.
 *
 * @param container - The DOM element to search within
 * @param [options] - Configuration options
 * @param [options.includeContainer=true] - Whether to include the container element itself as a focus candidate
 * @param [options.selector='a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])'] - Selector for focusable elements
 * @returns The element that was focused, or null if no focusable element was found
 */
export async function focusFirstInteractive( container, options = {} ) {
	const {
		includeContainer = true,
		selector = 'a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])'
	} = options;

	// Find the first focusable element in the container
	const focusableElements = container.querySelectorAll( selector );

	if ( focusableElements.length > 0 ) {
		return focusAndWait( focusableElements[ 0 ] );
	}

	// Check if the container itself is focusable
	if ( includeContainer && isFocusable( container ) ) {
		return focusAndWait( container );
	}

	return null;
}

/**
 * Let's wait short period of the time to make the browser apply focus.
 */
async function focusAndWait( element ) {
	element.focus();

	await timeout( 20 );

	return element;
}
