(function ($) {
	const ACCORDION_SELECTOR = '.wp-block-crispycohd-advanced-accordion';
	const CARET_BUTTON_CLASS = 'crispycohd-accordion-caret-button';

	function prefersReducedMotion() {
		return !!(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches);
	}

	function svgToDataUrl(svg) {
		if (!svg) return '';
		const encoded = encodeURIComponent(String(svg).trim())
			.replace(/%0A/g, '')
			.replace(/%09/g, '')
			.replace(/%20/g, ' ');
		return `url("data:image/svg+xml;utf8,${encoded}")`;
	}

	function ensureCaretCssVar(acc) {
		const existing = acc.style.getPropertyValue('--cc-caret-icon');
		if (existing && existing.trim()) return;

		const type = acc.dataset.iconType;
		if (type === 'svg' && acc.dataset.iconSvg) {
			acc.style.setProperty('--cc-caret-icon', svgToDataUrl(acc.dataset.iconSvg));
			return;
		}
		if (type === 'image' && acc.dataset.iconImg) {
			acc.style.setProperty('--cc-caret-icon', `url("${acc.dataset.iconImg}")`);
		}
	}

	function getDuration(acc) {
		if (prefersReducedMotion()) return 0;
		const duration = parseInt(acc.dataset.duration, 10);
		return Number.isFinite(duration) ? duration : 300;
	}

	function isFade(acc) {
		return acc.classList.contains('crispycohd-accordion--fade');
	}

	function getHeader(acc) {
		return acc.querySelector('.crispycohd-accordion-header');
	}

	function getContent(acc) {
		return acc.querySelector('.crispycohd-accordion-content');
	}

	function getStableId(acc, index) {
		const saved = (acc.dataset.ccId || '').trim();
		if (saved) return saved;
		// Fallback for legacy blocks without uniqueId.
		return `legacy-${index}`;
	}

	function ensureCaretButton(header) {
		if (!header) return null;
		const existing = header.querySelector(`.${CARET_BUTTON_CLASS}`);
		if (existing) return existing;

		const btn = document.createElement('button');
		btn.type = 'button';
		btn.className = CARET_BUTTON_CLASS;
		btn.setAttribute('aria-label', 'Toggle accordion');
		// Visual icon is purely decorative.
		btn.innerHTML = '';
		header.appendChild(btn);
		return btn;
	}

	function applyA11y(acc, index) {
		const header = getHeader(acc);
		const content = getContent(acc);
		if (!header || !content) return null;

		const btn = ensureCaretButton(header);
		const stableId = getStableId(acc, index);
		const buttonId = `cc-accordion-${stableId}-btn`;
		const panelId = `cc-accordion-${stableId}-panel`;

		btn.id = buttonId;
		btn.setAttribute('aria-controls', panelId);
		content.id = panelId;
		content.setAttribute('role', 'region');
		content.setAttribute('aria-labelledby', buttonId);

		const isOpen = acc.classList.contains('is-open');
		btn.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
		if (isOpen) {
			content.removeAttribute('hidden');
		} else {
			content.setAttribute('hidden', '');
		}

		return btn;
	}

	function closeAccordion(acc) {
		const duration = getDuration(acc);
		acc.style.setProperty('--crispycohd-duration', `${duration}ms`);

		const content = getContent(acc);
		const header = getHeader(acc);
		const btn = header ? header.querySelector(`.${CARET_BUTTON_CLASS}`) : null;
		if (!content) return;
		const $content = $(content);

		acc.classList.remove('is-open');
		if (btn) btn.setAttribute('aria-expanded', 'false');

		if (isFade(acc)) {
			$content.removeClass('cc-fade-visible');
			window.setTimeout(() => {
				$content.hide();
				content.setAttribute('hidden', '');
			}, duration);
		} else {
			$content.stop(true, false).slideUp(duration, () => {
				content.setAttribute('hidden', '');
			});
		}
	}

	function openAccordion(acc) {
		const duration = getDuration(acc);
		acc.style.setProperty('--crispycohd-duration', `${duration}ms`);

		const content = getContent(acc);
		const header = getHeader(acc);
		const btn = header ? header.querySelector(`.${CARET_BUTTON_CLASS}`) : null;
		if (!content) return;
		const $content = $(content);

		acc.classList.add('is-open');
		if (btn) btn.setAttribute('aria-expanded', 'true');
		content.removeAttribute('hidden');

		if (isFade(acc)) {
			$content.stop(true, true).show(0);
			requestAnimationFrame(() => $content.addClass('cc-fade-visible'));
		} else {
			$content.stop(true, false).slideDown(duration);
		}
	}

	function toggleAccordion(acc) {
		const willOpen = !acc.classList.contains('is-open');
		if (willOpen) {
			if (acc.dataset.exclusive === 'true') {
				$(ACCORDION_SELECTOR + '.is-open').each(function () {
					if (this !== acc) closeAccordion(this);
				});
			}
			openAccordion(acc);
		} else {
			closeAccordion(acc);
		}
	}

	function isInteractiveElement(el) {
		if (!el) return false;
		return !!$(el).closest('a,button,input,textarea,select,label,[role="button"]').length;
	}

	function bindInteractions(acc, caretButton, buttonsList) {
		const header = getHeader(acc);
		const content = getContent(acc);
		if (!header || !content || !caretButton) return;

		if (header.dataset.ccBound) return;
		header.dataset.ccBound = '1';

		// 1) Button interaction (keyboard + mouse).
		$(caretButton).on('click', (e) => {
			e.preventDefault();
			toggleAccordion(acc);
		});

		$(caretButton).on('keydown', (e) => {
			// Toggle
			if (e.key === 'Enter' || e.key === ' ') {
				e.preventDefault();
				toggleAccordion(acc);
				return;
			}

			// Navigation between accordions (WAI-ARIA style)
			const idx = buttonsList.indexOf(caretButton);
			if (idx < 0) return;

			let next = null;
			if (e.key === 'ArrowDown') next = buttonsList[idx + 1] || buttonsList[0];
			if (e.key === 'ArrowUp') next = buttonsList[idx - 1] || buttonsList[buttonsList.length - 1];
			if (e.key === 'Home') next = buttonsList[0];
			if (e.key === 'End') next = buttonsList[buttonsList.length - 1];

			if (next) {
				e.preventDefault();
				next.focus();
			}
		});

		// 2) Header click for mouse users.
		$(header).on('click', (e) => {
			// Let links/buttons inside header behave normally.
			if (isInteractiveElement(e.target)) return;
			// Avoid toggling when user is selecting text.
			const sel = window.getSelection ? window.getSelection() : null;
			if (sel && String(sel).trim()) return;
			toggleAccordion(acc);
		});
	}

	function initAccordion(acc, index, allButtons) {
		ensureCaretCssVar(acc);

		const duration = getDuration(acc);
		acc.style.setProperty('--crispycohd-duration', `${duration}ms`);

		const content = getContent(acc);
		if (!content) return;
		const $content = $(content);

		// Initial visibility
		if (acc.classList.contains('is-open')) {
			$content.show();
			content.removeAttribute('hidden');
			if (isFade(acc)) $content.addClass('cc-fade-visible');
		} else {
			if (isFade(acc)) {
				$content.removeClass('cc-fade-visible').hide();
			} else {
				$content.hide();
			}
			content.setAttribute('hidden', '');
		}

		const caretBtn = applyA11y(acc, index);
		if (caretBtn) {
			allButtons.push(caretBtn);
		}
	}

	$(function () {
		const buttons = [];
		const accordions = Array.from(document.querySelectorAll(ACCORDION_SELECTOR));
		accordions.forEach((acc, index) => initAccordion(acc, index, buttons));
		accordions.forEach((acc) => {
			const header = getHeader(acc);
			const btn = header ? header.querySelector(`.${CARET_BUTTON_CLASS}`) : null;
			if (btn) bindInteractions(acc, btn, buttons);
		});
	});
})(jQuery);
