<?php
/**
 * Livada SEO — Module Image SEO
 *
 * Automatically optimises images inside post content:
 *   - Fills empty alt attributes using the image filename + post title.
 *   - Adds loading="lazy" to all images except the first one in the content.
 *   - Adds decoding="async" to all images.
 *
 * Images that already have a non-empty alt attribute are not modified.
 *
 * Loader integration: add to $feature_map in class-loader.php:
 * 'image_seo' => ['class-image-seo.php', 'Livada_SEO_Image_SEO'],
 *
 * @package Livada_SEO
 */

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

class Livada_SEO_Image_SEO {

	// ── Bootstrap ─────────────────────────────────────────────────────────────

	/**
	 * Registers the content filter.
	 * Called once by Livada_SEO_Loader on `plugins_loaded`.
	 */
	public static function init(): void {
		add_filter( 'the_content', [ self::class, 'process_images' ], 20 );
	}

	// ── Content processing ────────────────────────────────────────────────────

	/**
	 * Processes all <img> tags in the content.
	 * Hooked to the_content at priority 20.
	 *
	 * @param string $content Filtered post content.
	 * @return string Content with improved image attributes.
	 */
	public static function process_images( string $content ): string {
		if ( '' === $content || false === stripos( $content, '<img' ) ) {
			return $content;
		}

		$image_index = 0;
		$post        = get_post();
		$post_title  = ( $post instanceof WP_Post ) ? get_the_title( $post->ID ) : '';

		return preg_replace_callback(
			'/<img\s[^>]*>/is',
			static function ( array $matches ) use ( &$image_index, $post_title ): string {
				$tag          = $matches[0];
				$is_first_img = ( 0 === $image_index );
				$image_index++;

				// ── alt attribute ──────────────────────────────────────────────

				$has_alt       = (bool) preg_match( '/\balt=["\']([^"\']*)["\']/', $tag, $alt_match );
				$alt_is_empty  = $has_alt && '' === trim( $alt_match[1] );
				$alt_is_absent = ! $has_alt;

				if ( $alt_is_empty || $alt_is_absent ) {
					$generated_alt = self::generate_alt( $tag, $post_title );

					if ( $alt_is_empty ) {
						// Replace empty alt="".
						$tag = preg_replace(
							'/\balt=["\'][^"\']*["\']/',
							'alt="' . esc_attr( $generated_alt ) . '"',
							$tag
						) ?? $tag;
					} else {
						// Insert alt attribute before the closing >.
						$tag = preg_replace(
							'/(\s*\/?>)$/',
							' alt="' . esc_attr( $generated_alt ) . '"$1',
							$tag
						) ?? $tag;
					}
				}

				// ── loading attribute ──────────────────────────────────────────

				$has_loading = (bool) preg_match( '/\bloading=["\'][^"\']*["\']/', $tag );

				if ( ! $has_loading && ! $is_first_img ) {
					$tag = preg_replace(
						'/(\s*\/?>)$/',
						' loading="lazy"$1',
						$tag
					) ?? $tag;
				}

				// ── decoding attribute ─────────────────────────────────────────

				$has_decoding = (bool) preg_match( '/\bdecoding=["\'][^"\']*["\']/', $tag );

				if ( ! $has_decoding ) {
					$tag = preg_replace(
						'/(\s*\/?>)$/',
						' decoding="async"$1',
						$tag
					) ?? $tag;
				}

				return $tag;
			},
			$content
		) ?? $content;
	}

	// ── Alt text generation ───────────────────────────────────────────────────

	/**
	 * Generates an alt text string from the image src filename and the post title.
	 *
	 * Example: src="laptop-repair.jpg" + "Depannage informatique"
	 *          → "Laptop repair - Depannage informatique"
	 *
	 * @param string $img_tag   Full <img> HTML tag.
	 * @param string $post_title Current post title.
	 * @return string
	 */
	private static function generate_alt( string $img_tag, string $post_title ): string {
		$filename_part = '';

		// Extract src value.
		if ( preg_match( '/\bsrc=["\']([^"\']+)["\']/', $img_tag, $src_match ) ) {
			$src      = $src_match[1];
			$basename = basename( wp_parse_url( $src, PHP_URL_PATH ) ?? $src );

			// Remove query string if any crept into the basename.
			$basename = strtok( $basename, '?' );

			// Strip extension.
			$name = (string) preg_replace( '/\.[a-z0-9]{2,6}$/i', '', $basename );

			// Replace dashes and underscores with spaces, then capitalise first letter.
			$name          = str_replace( [ '-', '_' ], ' ', $name );
			$filename_part = ucfirst( trim( $name ) );
		}

		if ( '' !== $filename_part && '' !== $post_title ) {
			return $filename_part . ' - ' . $post_title;
		}

		if ( '' !== $filename_part ) {
			return $filename_part;
		}

		return $post_title;
	}
}
