<?php
/**
 * Theme accessibility enhancements.
 *
 * @package Eryndo
 * @since 1.1.6
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Registers accessibility-related filters and theme supports.
 */
function eryndo_register_accessibility_features() {
	add_theme_support( 'html5', array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'style', 'script' ) );

	add_filter( 'render_block', 'eryndo_accessibility_render_block', 10, 2 );
	add_filter( 'enable_wp_skip_link', '__return_true' );
	add_filter( 'render_block', 'eryndo_announce_new_window_links_in_block', 20, 2 );
}
add_action( 'after_setup_theme', 'eryndo_register_accessibility_features' );

/**
 * Route block-specific accessibility fixes.
 *
 * @param string $block_content Rendered block HTML.
 * @param array  $block         Block data.
 * @return string
 */
function eryndo_accessibility_render_block( $block_content, $block ) {
	if ( empty( $block['blockName'] ) ) {
		return $block_content;
	}

	switch ( $block['blockName'] ) {
		case 'core/site-title':
			return eryndo_adjust_site_title_heading_level( $block_content, $block );
		case 'core/query-title':
			return eryndo_ensure_query_title_is_h1( $block_content, $block );
		case 'core/cover':
			return eryndo_mark_decorative_cover_images( $block_content );
		case 'core/image':
			return eryndo_improve_image_block_accessibility( $block_content, $block );
		case 'core/group':
			return eryndo_ensure_main_landmark_id( $block_content, $block );
		case 'core/navigation':
			return eryndo_ensure_navigation_aria_label( $block_content, $block );
		case 'eryndo/responsive-nav-menu':
			return eryndo_improve_responsive_nav_menu_block( $block_content, $block );
		case 'eryndo/button-widget':
			return eryndo_improve_button_widget_block( $block_content, $block );
		case 'eryndo/svg-icon':
			return eryndo_improve_svg_icon_block( $block_content, $block );
	}

	$block_content = eryndo_fix_empty_icon_links( $block_content );

	return $block_content;
}

/**
 * Ensure the main landmark keeps a stable skip-link target id.
 *
 * @param string $block_content Rendered block HTML.
 * @param array  $block         Block data.
 * @return string
 */
function eryndo_ensure_main_landmark_id( $block_content, $block ) {
	if ( empty( $block['attrs']['tagName'] ) || 'main' !== $block['attrs']['tagName'] ) {
		return $block_content;
	}

	if ( false !== strpos( $block_content, 'id="main-content"' ) ) {
		return $block_content;
	}

	return preg_replace( '/<main\b/i', '<main id="main-content" tabindex="-1"', $block_content, 1 );
}

/**
 * Add accessible names to icon-only action links in card widgets.
 *
 * @param string $block_content Rendered block HTML.
 * @return string
 */
function eryndo_fix_empty_icon_links( $block_content ) {
	if ( false === strpos( $block_content, 'action-button' ) ) {
		return $block_content;
	}

	return preg_replace_callback(
		'/<a\b([^>]*class="[^"]*action-button[^"]*"[^>]*)>(\s*<svg\b)/i',
		static function ( $matches ) {
			if ( false !== stripos( $matches[1], 'aria-label=' ) ) {
				return $matches[0];
			}

			$label = esc_attr__( 'View service details', 'eryndo' );

			return '<a' . $matches[1] . ' aria-label="' . $label . '">' . $matches[2];
		},
		$block_content
	);
}

/**
 * Mark cover background images as decorative when alt is empty.
 *
 * @param string $block_content Rendered block HTML.
 * @return string
 */
function eryndo_mark_decorative_cover_images( $block_content ) {
	if ( preg_match( '/<img\b[^>]*class="[^"]*wp-block-cover__image-background[^"]*"[^>]*alt=""[^>]*>/i', $block_content ) ) {
		$block_content = preg_replace(
			'/(<img\b[^>]*class="[^"]*wp-block-cover__image-background[^"]*")/i',
			'$1 aria-hidden="true"',
			$block_content,
			1
		);
	}

	return $block_content;
}

/**
 * Improve image blocks with missing alternative text.
 *
 * @param string $block_content Rendered block HTML.
 * @param array  $block         Block data.
 * @return string
 */
function eryndo_improve_image_block_accessibility( $block_content, $block ) {
	if ( empty( $block_content ) || false === strpos( $block_content, 'alt=""' ) ) {
		return $block_content;
	}

	$alt = '';

	if ( ! empty( $block['attrs']['alt'] ) ) {
		$alt = $block['attrs']['alt'];
	} elseif ( ! empty( $block['attrs']['id'] ) ) {
		$alt = get_post_meta( (int) $block['attrs']['id'], '_wp_attachment_image_alt', true );
	}

	if ( is_string( $alt ) && '' !== trim( $alt ) ) {
		return preg_replace( '/alt=""/i', 'alt="' . esc_attr( $alt ) . '"', $block_content, 1 );
	}

	if ( false !== stripos( $block_content, 'eryndo-logo' ) ) {
		$site_name = get_bloginfo( 'name' );
		if ( $site_name ) {
			return preg_replace( '/alt=""/i', 'alt="' . esc_attr( $site_name ) . '"', $block_content, 1 );
		}
	}

	if ( preg_match( '/<img\b[^>]*>/i', $block_content ) ) {
		$block_content = preg_replace( '/<img\b/i', '<img aria-hidden="true"', $block_content, 1 );
	}

	return $block_content;
}

/**
 * Ensure primary navigation landmarks have an accessible name.
 *
 * @param string $block_content Rendered block HTML.
 * @param array  $block         Block data.
 * @return string
 */
function eryndo_ensure_navigation_aria_label( $block_content, $block ) {
	if ( empty( $block_content ) || false !== stripos( $block_content, 'aria-label=' ) ) {
		return $block_content;
	}

	$label = ! empty( $block['attrs']['ariaLabel'] )
		? $block['attrs']['ariaLabel']
		: __( 'Primary', 'eryndo' );

	return preg_replace(
		'/<nav\b/i',
		'<nav aria-label="' . esc_attr( $label ) . '"',
		$block_content,
		1
	);
}

/**
 * Strip invalid accordion ARIA from saved markup; frontend script re-applies it in mobile mode.
 *
 * @param string $block_content Rendered block HTML.
 * @param array  $block         Block data.
 * @return string
 */
function eryndo_improve_responsive_nav_menu_block( $block_content, $block ) {
	if ( empty( $block_content ) ) {
		return $block_content;
	}

	$block_content = preg_replace( '/\srole="button"/i', '', $block_content );
	$block_content = preg_replace( '/\stabindex="0"/i', '', $block_content );
	$block_content = preg_replace( '/\saria-expanded="[^"]*"/i', '', $block_content );
	$block_content = preg_replace( '/\saria-controls="[^"]*"/i', '', $block_content );

	if ( ! empty( $block['attrs']['menuTitle'] ) && false === stripos( $block_content, 'aria-label=' ) ) {
		$menu_title = $block['attrs']['menuTitle'];
		$block_content = preg_replace(
			'/(<nav\b[^>]*class="[^"]*menu-items[^"]*")/i',
			'$1 aria-label="' . esc_attr( $menu_title ) . '"',
			$block_content,
			1
		);
	}

	return $block_content;
}

/**
 * Add an accessible name to newsletter email fields rendered by the button widget.
 *
 * @param string $block_content Rendered block HTML.
 * @param array  $block         Block data.
 * @return string
 */
function eryndo_improve_button_widget_block( $block_content, $block ) {
	if ( empty( $block_content ) || false === strpos( $block_content, 'email-input' ) ) {
		return $block_content;
	}

	if ( false !== strpos( $block_content, '<label' ) ) {
		return $block_content;
	}

	$label_text = __( 'Email address', 'eryndo' );

	if ( ! empty( $block['attrs']['buttonText'] ) ) {
		$label_text = $block['attrs']['buttonText'];
	} elseif ( preg_match( '/placeholder="([^"]*)"/i', $block_content, $matches ) ) {
		$label_text = html_entity_decode( $matches[1], ENT_QUOTES, 'UTF-8' );
	}

	$field_id = 'eryndo-email-' . wp_unique_id();

	$block_content = preg_replace(
		'/(<input\b[^>]*type=["\']email["\'][^>]*)(>)/i',
		'$1 id="' . esc_attr( $field_id ) . '"$2',
		$block_content,
		1
	);

	$label_markup = '<label class="screen-reader-text" for="' . esc_attr( $field_id ) . '">' . esc_html( $label_text ) . '</label>';

	return preg_replace( '/(<form\b[^>]*>)/i', '$1' . $label_markup, $block_content, 1 );
}

/**
 * Treat generic SVG icon alt text as decorative.
 *
 * @param string $block_content Rendered block HTML.
 * @return string
 */
function eryndo_improve_svg_icon_block( $block_content ) {
	if ( empty( $block_content ) ) {
		return $block_content;
	}

	if ( ! preg_match( '/alt="([^"]*)"/i', $block_content, $matches ) ) {
		return $block_content;
	}

	$alt = trim( html_entity_decode( $matches[1], ENT_QUOTES, 'UTF-8' ) );

	if ( '' !== $alt && 'svg icon' !== strtolower( $alt ) ) {
		return $block_content;
	}

	$block_content = preg_replace( '/alt="[^"]*"/i', 'alt=""', $block_content, 1 );

	if ( false === stripos( $block_content, 'aria-hidden="true"' ) ) {
		$block_content = preg_replace( '/<img\b/i', '<img aria-hidden="true"', $block_content, 1 );
	}

	return $block_content;
}

/**
 * Append screen reader text to links that open in a new tab.
 *
 * @param string $content HTML content.
 * @return string
 */
function eryndo_announce_new_window_links( $content ) {
	if ( false === strpos( $content, 'target="_blank"' ) ) {
		return $content;
	}

	$notice = '<span class="screen-reader-text"> ' . esc_html__( '(opens in a new tab)', 'eryndo' ) . '</span>';

	return preg_replace_callback(
		'/<a\b([^>]*target=["\']_blank["\'][^>]*)>(.*?)<\/a>/is',
		static function ( $matches ) use ( $notice ) {
			if ( false !== strpos( $matches[2], 'screen-reader-text' ) ) {
				return $matches[0];
			}

			return '<a' . $matches[1] . '>' . $matches[2] . $notice . '</a>';
		},
		$content
	);
}

/**
 * Announce new-tab links inside rendered blocks.
 *
 * @param string $block_content Rendered block HTML.
 * @param array  $block         Block data.
 * @return string
 */
function eryndo_announce_new_window_links_in_block( $block_content, $block ) {
	if ( empty( $block_content ) || false === strpos( $block_content, 'target="_blank"' ) ) {
		return $block_content;
	}

	return eryndo_announce_new_window_links( $block_content );
}

/**
 * Use a single H1 on the front page only; demote site title elsewhere.
 *
 * @param string $block_content Rendered block HTML.
 * @param array  $block         Block data.
 * @return string
 */
function eryndo_adjust_site_title_heading_level( $block_content, $block ) {
	if ( is_front_page() ) {
		return $block_content;
	}

	$block_content = preg_replace( '/<h1\b([^>]*)>/i', '<p class="site-title"$1>', $block_content, 1 );
	$block_content = preg_replace( '/<\/h1>/i', '</p>', $block_content, 1 );

	return $block_content;
}

/**
 * Ensure archive and search titles render as the page H1.
 *
 * @param string $block_content Rendered block HTML.
 * @param array  $block         Block data.
 * @return string
 */
function eryndo_ensure_query_title_is_h1( $block_content, $block ) {
	if ( empty( $block_content ) ) {
		return $block_content;
	}

	$block_content = preg_replace( '/<h2\b([^>]*)>/i', '<h1$1>', $block_content, 1 );
	$block_content = preg_replace( '/<\/h2>/i', '</h1>', $block_content, 1 );

	return $block_content;
}

/**
 * Skip-link focus styles for the core WordPress skip link.
 */
function eryndo_skip_link_styles() {
	$css = '
		.skip-link.screen-reader-text {
			position: absolute !important;
			top: -40px !important;
			left: 6px !important;
			background: #000 !important;
			color: #fff !important;
			padding: 8px 16px !important;
			text-decoration: none !important;
			border-radius: 4px !important;
			z-index: 100000 !important;
			font-weight: 700 !important;
			clip: rect(1px, 1px, 1px, 1px) !important;
			clip-path: inset(50%) !important;
			height: 1px !important;
			width: 1px !important;
			overflow: hidden !important;
			white-space: nowrap !important;
		}
		.skip-link.screen-reader-text:focus {
			top: 6px !important;
			clip: auto !important;
			clip-path: none !important;
			height: auto !important;
			width: auto !important;
			overflow: visible !important;
			white-space: normal !important;
			outline: 2px solid #fff !important;
			outline-offset: 2px !important;
		}
		#main-content:focus {
			outline: 2px solid var(--wp--preset--color--contrast, #C2410C);
			outline-offset: 2px;
		}
	';

	wp_add_inline_style( 'eryndo-style-index', $css );
}
add_action( 'wp_enqueue_scripts', 'eryndo_skip_link_styles', 20 );

/**
 * Pass translated strings to frontend accessibility scripts.
 */
function eryndo_enqueue_accessibility_script_strings() {
	if ( ! wp_script_is( 'eryndo-accessibility', 'enqueued' ) ) {
		return;
	}

	wp_localize_script(
		'eryndo-accessibility',
		'eryndoA11yStrings',
		array(
			'menuExpanded'  => __( 'Menu expanded', 'eryndo' ),
			'menuCollapsed' => __( 'Menu collapsed', 'eryndo' ),
		)
	);
}
add_action( 'wp_enqueue_scripts', 'eryndo_enqueue_accessibility_script_strings', 25 );

/**
 * Localize responsive nav strings after block view scripts register.
 */
function eryndo_localize_responsive_nav_on_print() {
	global $wp_scripts;

	if ( empty( $wp_scripts ) || empty( $wp_scripts->queue ) ) {
		return;
	}

	$strings = array(
		'menuExpanded'  => __( 'Menu expanded', 'eryndo' ),
		'menuCollapsed' => __( 'Menu collapsed', 'eryndo' ),
	);

	foreach ( $wp_scripts->queue as $handle ) {
		if ( false === strpos( $handle, 'responsive-nav-menu' ) ) {
			continue;
		}

		if ( ! wp_script_is( $handle, 'enqueued' ) && ! wp_script_is( $handle, 'registered' ) ) {
			continue;
		}

		wp_localize_script( $handle, 'eryndoA11yStrings', $strings );
	}
}
add_action( 'wp_enqueue_scripts', 'eryndo_localize_responsive_nav_on_print', 100 );
add_action( 'enqueue_block_assets', 'eryndo_localize_responsive_nav_on_print', 100 );
