<?php
/**
 * Shared companion memory text normalization helpers.
 *
 * @package Niwa_AI
 */

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

class Niwa_AI_Companion_Memory_Text {
	public static function normalize_inline( $text ) {
		$text = function_exists( 'wp_strip_all_tags' ) ? wp_strip_all_tags( (string) $text ) : strip_tags( (string) $text );
		$text = preg_replace( '/\s+/u', ' ', $text );
		return trim( (string) $text );
	}

	public static function normalize_candidate( $text, $limit = 220, $min_length = 4 ) {
		$text = self::normalize_inline( $text );
		$text = trim( (string) $text, " \t\n\r\0\x0B:-" );
		if ( '' === $text ) {
			return '';
		}

		$length = function_exists( 'mb_strlen' ) ? mb_strlen( $text, 'UTF-8' ) : strlen( $text );
		if ( $length < max( 1, intval( $min_length ) ) ) {
			return '';
		}

		return self::truncate( $text, $limit );
	}

	public static function canonical_key( $text ) {
		$text = self::normalize_candidate( $text, 320, 1 );
		if ( '' === $text ) {
			return '';
		}

		$text = self::strtolower( $text );
		if ( function_exists( 'iconv' ) ) {
			$ascii = @iconv( 'UTF-8', 'ASCII//TRANSLIT//IGNORE', $text );
			if ( is_string( $ascii ) && '' !== trim( $ascii ) ) {
				$text = $ascii;
			}
		}

		$text = preg_replace( '/[^\p{L}\p{N}]+/u', ' ', $text );
		$text = preg_replace( '/\s+/u', ' ', $text );

		return trim( (string) $text );
	}

	public static function merge_unique_items( $existing, $candidates, $limit = 10 ) {
		$items = array();
		foreach ( array_merge( (array) $existing, (array) $candidates ) as $item ) {
			$item = self::normalize_candidate( $item );
			if ( '' === $item ) {
				continue;
			}
			$items[] = $item;
		}

		$unique = array();
		$seen   = array();
		foreach ( array_reverse( $items ) as $item ) {
			$key = self::canonical_key( $item );
			if ( '' === $key || isset( $seen[ $key ] ) ) {
				continue;
			}
			$seen[ $key ] = true;
			array_unshift( $unique, $item );
		}

		return array_slice( $unique, -max( 1, intval( $limit ) ) );
	}

	public static function truncate( $text, $limit ) {
		$text  = (string) $text;
		$limit = max( 1, intval( $limit ) );
		if ( function_exists( 'mb_strlen' ) && function_exists( 'mb_substr' ) ) {
			return mb_strlen( $text, 'UTF-8' ) > $limit ? rtrim( mb_substr( $text, 0, $limit, 'UTF-8' ) ) : $text;
		}

		return strlen( $text ) > $limit ? rtrim( substr( $text, 0, $limit ) ) : $text;
	}

	public static function truncate_with_ellipsis( $text, $limit, $minimum = 1 ) {
		$text    = trim( (string) $text );
		$limit   = max( max( 1, intval( $minimum ) ), intval( $limit ) );
		$ellipsis = '...';
		if ( '' === $text ) {
			return '';
		}

		if ( function_exists( 'mb_strlen' ) && function_exists( 'mb_substr' ) ) {
			return mb_strlen( $text, 'UTF-8' ) > $limit
				? rtrim( mb_substr( $text, 0, max( 0, $limit - strlen( $ellipsis ) ), 'UTF-8' ) ) . $ellipsis
				: $text;
		}

		return strlen( $text ) > $limit
			? rtrim( substr( $text, 0, max( 0, $limit - strlen( $ellipsis ) ) ) ) . $ellipsis
			: $text;
	}

	private static function strtolower( $text ) {
		return function_exists( 'mb_strtolower' ) ? mb_strtolower( (string) $text, 'UTF-8' ) : strtolower( (string) $text );
	}
}
