/**
 * Toggles for dropdowns, the mobile menu and inline expanders.
 *
 * Markup contract: a `<button data-disclosure aria-expanded="false" aria-controls="panel-id">`
 * and a `<div id="panel-id" data-disclosure-panel hidden>`. Only one disclosure is open at a
 * time; it closes on outside click, on link click inside the panel and on Escape.
 *
 * `data-disclosure="persistent"` opts out of the auto-closing: the panel only toggles when its
 * own trigger is clicked (e.g. "show more" sections).
 *
 * Inside a panel, `data-disclosure-close` marks a close button (focus returns to the trigger)
 * and `data-disclosure-autofocus` the element to focus when the panel opens.
 */
const TRIGGER = '[data-disclosure]';
const PANEL = '[data-disclosure-panel]';
const TRANSIENT_TRIGGER = `${TRIGGER}:not([data-disclosure="persistent"])`;

function setOpen(trigger: HTMLElement, open: boolean) {
	trigger.setAttribute('aria-expanded', String(open));

	const panelId = trigger.getAttribute('aria-controls');
	const panel = panelId ? document.getElementById(panelId) : null;
	panel?.toggleAttribute('hidden', !open);
	if (open) panel?.querySelector<HTMLElement>('[data-disclosure-autofocus]')?.focus();
}

function isPersistent(trigger: HTMLElement) {
	return trigger.dataset.disclosure === 'persistent';
}

function openTriggers() {
	return [...document.querySelectorAll<HTMLElement>(`${TRANSIENT_TRIGGER}[aria-expanded="true"]`)];
}

function closeAll(except?: HTMLElement) {
	for (const trigger of openTriggers()) {
		if (trigger !== except) setOpen(trigger, false);
	}
}

document.addEventListener('click', (event) => {
	if (!(event.target instanceof Element)) return;

	const closer = event.target.closest(`${PANEL} [data-disclosure-close]`);
	if (closer) {
		const panelId = closer.closest(PANEL)?.id;
		const owner = panelId ? document.querySelector<HTMLElement>(`${TRIGGER}[aria-controls="${panelId}"]`) : null;
		closeAll();
		owner?.focus();
		return;
	}

	const trigger = event.target.closest<HTMLElement>(TRIGGER);
	if (trigger) {
		const willOpen = trigger.getAttribute('aria-expanded') !== 'true';
		if (!isPersistent(trigger)) closeAll(trigger);
		setOpen(trigger, willOpen);
		return;
	}

	const panel = event.target.closest(PANEL);
	if (!panel || event.target.closest('a')) closeAll();
});

document.addEventListener('keydown', (event) => {
	if (event.key !== 'Escape') return;

	const [trigger] = openTriggers();
	if (!trigger) return;

	setOpen(trigger, false);
	trigger.focus();
});
