<?php
/**
 * Sanitizes label text fields for plain-text PDF output.
 *
 * @package PhoenixWP\PriceLabels
 */

declare(strict_types=1);

namespace PhoenixWP\PriceLabels\Labels;

use WC_Product;

defined( 'ABSPATH' ) || exit;

/**
 * Normalizes WooCommerce text for offline label PDFs.
 */
final class Label_Text_Sanitizer {

	/** @var string[] Fields sanitized before PDF render. */
	private const TEXT_FIELDS = array(
		'brand',
		'name',
		'variation_text',
		'unit_price',
		'stock',
	);

	/**
	 * Sanitizes all text fields on a label data row.
	 *
	 * @param array<string, mixed> $data    Label row.
	 * @param WC_Product|null      $product Source product.
	 * @return array<string, mixed>
	 */
	public static function sanitize_label_data( array $data, ?WC_Product $product = null ): array {
		foreach ( self::TEXT_FIELDS as $field ) {
			if ( ! isset( $data[ $field ] ) || ! is_scalar( $data[ $field ] ) ) {
				continue;
			}

			$data[ $field ] = self::sanitize_field( (string) $data[ $field ], $field, $product );
		}

		return $data;
	}

	/**
	 * Sanitizes one label text field.
	 *
	 * @param string           $text    Raw text.
	 * @param string           $field   Field key, e.g. `name`.
	 * @param WC_Product|null  $product Source product.
	 */
	public static function sanitize_field( string $text, string $field, ?WC_Product $product = null ): string {
		/**
		 * Filters label text before default sanitization.
		 *
		 * @param string           $text    Raw field text.
		 * @param string           $field   Field key.
		 * @param WC_Product|null  $product Source product.
		 */
		$text = (string) apply_filters( 'phoenix_wp_price_labels_sanitize_text_before', $text, $field, $product );

		$text = self::normalize_break_tags( $text );
		$text = wp_strip_all_tags( $text );

		$text = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
		$text = preg_replace( '/\s+/u', ' ', $text ) ?? $text;
		$text = trim( $text );

		/**
		 * Filters label text after default sanitization.
		 *
		 * @param string           $text    Sanitized field text.
		 * @param string           $field   Field key.
		 * @param WC_Product|null  $product Source product.
		 */
		return (string) apply_filters( 'phoenix_wp_price_labels_sanitize_text', $text, $field, $product );
	}

	/**
	 * Converts HTML line breaks to plain-text spaces.
	 */
	private static function normalize_break_tags( string $text ): string {
		$text = preg_replace( '/<br\s*\/?>/i', ' ', $text ) ?? $text;

		return str_replace( array( "\r\n", "\r", "\n" ), ' ', $text );
	}
}
