<?php
/**
 * Locates the real header row in a supplier price list (SPEC §4).
 *
 * @package EmberPrice
 */

namespace EmberPrice\Ingestion;

/**
 * Shared by CsvParser and XlsxParser: finds the row that looks like the
 * real header row, skipping title/vigencia/empty rows above it. Pure PHP,
 * no WordPress dependency.
 */
final class HeaderRowDetector {

	private const MAX_HEADER_CELL_LENGTH = 40;

	/**
	 * Finds the index of the row that looks like the real header row.
	 *
	 * @param array<int, string[]> $rows Parsed rows.
	 */
	public function detect( array $rows ): ?int {
		foreach ( $rows as $index => $row ) {
			if ( $this->looks_like_header_row( $row ) ) {
				return $index;
			}
		}

		return null;
	}

	/**
	 * A header row has multiple distinct, short, non-empty cells. Title
	 * rows ("LISTA DE PRECIOS...;;;"), vigencia rows and section banners
	 * ("*** SIN STOCK ***;;;") collapse to a single non-empty cell once
	 * split; empty rows have none.
	 *
	 * @param string[] $row A single parsed row.
	 */
	private function looks_like_header_row( array $row ): bool {
		$non_empty = array_values( array_filter( $row, static fn( $cell ) => '' !== $cell ) );

		if ( count( $non_empty ) < 2 || count( array_unique( $non_empty ) ) < 2 ) {
			return false;
		}

		foreach ( $non_empty as $cell ) {
			if ( mb_strlen( $cell ) > self::MAX_HEADER_CELL_LENGTH ) {
				return false;
			}
		}

		return true;
	}
}
