<?php
defined( 'ABSPATH' ) || exit;

/**
 * Deterministic inline image marker normalization and repair.
 */
final class Costudio_Pipeline_Image_Markers {

	private function __construct() {
	}

	public static function normalize_to_seo_filenames( string $output, string $keyword ): string {
		if ( ! function_exists( 'sanitize_title' ) ) {
			return $output;
		}

		$seen = array();

		$out = preg_replace_callback(
			'/\[IMG:\s*([^\|\]]+)\s*\|\s*([^\]]+)\]/',
			static function ( array $m ) use ( &$seen, $keyword ): string {
				$alt  = trim( $m[2] );
				$base = '' !== $alt ? $alt : trim( $keyword );
				if ( '' === $base ) {
					$base = 'imagem';
				}

				$slug = sanitize_title( $base );
				if ( '' === $slug || '-' === $slug ) {
					$slug = 'imagem';
				}
				if ( strlen( $slug ) > 50 ) {
					$slug = rtrim( substr( $slug, 0, 50 ), '-' );
				}

				$candidate = $slug . '.webp';
				$n         = 2;
				while ( isset( $seen[ strtolower( $candidate ) ] ) ) {
					$candidate = $slug . '-' . $n . '.webp';
					$n++;
				}
				$seen[ strtolower( $candidate ) ] = true;

				return '[IMG:' . $candidate . ' | ' . $alt . ']';
			},
			$output
		);

		return $out ?? $output;
	}

	public static function ensure_inline_markers(
		string $output,
		int $desired,
		string $keyword,
		int $production_id,
		callable $logger
	): string {
		if ( $desired < 1 || '' === $output ) {
			return $output;
		}

		preg_match_all(
			'/\[IMG:[^\]]+\]/',
			$output,
			$existing_matches,
			PREG_OFFSET_CAPTURE
		);
		$existing_count = is_array( $existing_matches[0] ?? null ) ? count( $existing_matches[0] ) : 0;

		preg_match_all(
			'/\[IMG:\s*imagem(\d+)\.webp\s*\|/i',
			$output,
			$num_matches
		);
		$used_numbers = isset( $num_matches[1] ) ? array_map( 'intval', $num_matches[1] ) : array();

		if ( $existing_count >= $desired ) {
			$logger(
				'info',
				'agent4.img_marker_check',
				array(
					'production_id' => $production_id,
					'desired'       => $desired,
					'existing'      => $existing_count,
					'action'        => 'skip',
				)
			);
			return $output;
		}

		$missing = $desired - $existing_count;

		$lines         = explode( "\n", $output );
		$h2_indexes    = array();
		$h2_has_marker = array();

		foreach ( $lines as $i => $line ) {
			if ( preg_match( '/^##\s+\S/', $line ) ) {
				$h2_indexes[]    = $i;
				$h2_has_marker[] = false;
			}
		}

		if ( empty( $h2_indexes ) ) {
			$logger(
				'info',
				'agent4.img_marker_check',
				array(
					'production_id' => $production_id,
					'desired'       => $desired,
					'existing'      => $existing_count,
					'action'        => 'no_h2_skip',
				)
			);
			return $output;
		}

		for ( $s = 0; $s < count( $h2_indexes ); $s++ ) {
			$section_start = $h2_indexes[ $s ];
			$section_end   = isset( $h2_indexes[ $s + 1 ] ) ? $h2_indexes[ $s + 1 ] : count( $lines );
			for ( $li = $section_start; $li < $section_end; $li++ ) {
				if ( false !== strpos( $lines[ $li ], '[IMG:' ) ) {
					$h2_has_marker[ $s ] = true;
					break;
				}
			}
		}

		$candidates = array();
		foreach ( $h2_indexes as $s => $idx ) {
			if ( ! $h2_has_marker[ $s ] ) {
				$candidates[] = $s;
			}
		}

		if ( empty( $candidates ) ) {
			$logger(
				'info',
				'agent4.img_marker_check',
				array(
					'production_id' => $production_id,
					'desired'       => $desired,
					'existing'      => $existing_count,
					'action'        => 'all_sections_taken',
				)
			);
			return $output;
		}

		$picked  = array();
		$count_c = count( $candidates );
		$needed  = min( $missing, $count_c );
		if ( $needed === $count_c ) {
			$picked = $candidates;
		} else {
			for ( $k = 0; $k < $needed; $k++ ) {
				$picked[] = $candidates[ (int) floor( $k * $count_c / $needed ) ];
			}
			$picked = array_values( array_unique( $picked ) );
		}

		$next_n        = 2;
		$assign_number = static function () use ( &$next_n, &$used_numbers ): int {
			while ( in_array( $next_n, $used_numbers, true ) ) {
				$next_n++;
			}
			$n              = $next_n++;
			$used_numbers[] = $n;
			return $n;
		};

		sort( $picked );

		$insertions = array();
		$kw         = trim( $keyword );
		foreach ( $picked as $section_idx ) {
			$h2_line  = (string) $lines[ $h2_indexes[ $section_idx ] ];
			$heading  = trim( preg_replace( '/^##\s+/', '', $h2_line ) );
			$heading  = preg_replace( '/[\*_`]+/', '', $heading );
			$heading  = trim( preg_replace( '/\s+/', ' ', $heading ) );
			$alt_base = '' !== $heading ? $heading : 'Ilustração da seção';
			$alt_text = ( '' !== $kw && false === stripos( $alt_base, $kw ) )
				? sprintf( '%s — %s', $alt_base, $kw )
				: $alt_base;
			if ( function_exists( 'mb_strlen' ) && mb_strlen( $alt_text ) > 125 ) {
				$alt_text = mb_substr( $alt_text, 0, 122 ) . '…';
			}

			$n            = $assign_number();
			$insertions[] = array(
				'after_line' => $h2_indexes[ $section_idx ],
				'marker'     => sprintf( '[IMG:imagem%d.webp | %s]', $n, $alt_text ),
			);
		}

		usort(
			$insertions,
			static function ( $a, $b ) {
				return $b['after_line'] <=> $a['after_line'];
			}
		);

		foreach ( $insertions as $ins ) {
			$at = (int) $ins['after_line'];
			array_splice( $lines, $at + 1, 0, array( '', $ins['marker'], '' ) );
		}

		$patched = implode( "\n", $lines );
		$patched = preg_replace( "/\n{3,}/", "\n\n", $patched );

		$logger(
			'info',
			'agent4.img_marker_check',
			array(
				'production_id' => $production_id,
				'desired'       => $desired,
				'existing'      => $existing_count,
				'inserted'      => count( $insertions ),
				'action'        => 'spliced',
			)
		);

		return $patched;
	}
}
