<?php
/**
 * Extracts the text layer of a supplier PDF price list (SPEC §11/T-404).
 *
 * @package EmberPrice
 */

namespace EmberPrice\Ingestion;

use EmberPrice\Vendor\Smalot\PdfParser\Parser;

/**
 * Thin wrapper over Strauss-prefixed smalot/pdfparser: reads a PDF's text,
 * page by page. Pure PHP, no WordPress dependency (imports the
 * Strauss-prefixed PdfParser library only), same as CsvParser/XlsxParser.
 * A scanned/image-only PDF (no text on any page) throws
 * PdfTextLayerMissingException -- SPEC §11 explicitly leaves that out of
 * v1, this only extracts a text layer that already exists.
 */
final class PdfParser {

	/**
	 * The underlying library's entry point.
	 *
	 * @var Parser
	 */
	private Parser $parser;

	/**
	 * Constructor.
	 *
	 * @param Parser|null $parser Defaults to a new instance.
	 */
	public function __construct( ?Parser $parser = null ) {
		$this->parser = $parser ?? new Parser();
	}

	/**
	 * Extracts each page's text, in page order.
	 *
	 * @param string $path Path to the PDF file.
	 *
	 * @return string[] One entry per page (may be an empty string for a
	 *                   blank page, as long as at least one other page has text).
	 *
	 * @throws PdfTextLayerMissingException If no page has any extractable text.
	 */
	public function extract_pages( string $path ): array {
		$document = $this->parser->parseFile( $path );
		$pages    = array();

		foreach ( $document->getPages() as $page ) {
			$pages[] = trim( $page->getText() );
		}

		$has_any_text = array_filter( $pages, static fn( string $text ): bool => '' !== $text );

		if ( empty( $has_any_text ) ) {
			// phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped -- relayed as a REST error message by JobsController::create_job(), already escaped there.
			throw new PdfTextLayerMissingException(
				__( 'Scanned PDF (no text layer) is not supported in v1.', 'emberprice' )
			);
			// phpcs:enable WordPress.Security.EscapeOutput.ExceptionNotEscaped
		}

		return $pages;
	}
}
