<?php
/**
 * Content Chunker for Context Awareness.
 *
 * @package Replyan_AI
 */

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

class Replyan_AI_Content_Chunker {

	private const CHUNK_SIZE_TOKENS = 500;
	private const OVERLAP_TOKENS    = 50;
	private const CHARS_PER_TOKEN   = 4;

	/**
	 * Splits the cleaned content into smaller chunks.
	 *
	 * @param string $content The cleaned content.
	 * @return array Array of string chunks.
	 */
	public function chunk( string $content ): array {
		$content = trim( $content );
		if ( empty( $content ) ) {
			return array();
		}

		$chunk_size_chars = self::CHUNK_SIZE_TOKENS * self::CHARS_PER_TOKEN;
		$overlap_chars    = self::OVERLAP_TOKENS * self::CHARS_PER_TOKEN;

		// If content comfortably fits within one chunk, preserve entire structure intact
		if ( strlen( $content ) <= $chunk_size_chars ) {
			return array( $content );
		}

		// Split by paragraphs/blocks first
		$blocks  = explode( "\n\n", $content );
		$chunks  = array();
		$current = '';

		foreach ( $blocks as $block ) {
			$block = trim( $block );
			if ( empty( $block ) ) {
				continue;
			}

			// If a single block exceeds chunk size, split by lines/words
			if ( strlen( $block ) > $chunk_size_chars ) {
				$sub_lines = explode( "\n", wordwrap( $block, $chunk_size_chars, "\n", false ) );
			} else {
				$sub_lines = array( $block );
			}

			foreach ( $sub_lines as $line ) {
				$line = trim( $line );
				if ( empty( $line ) ) {
					continue;
				}

				if ( strlen( $current ) + strlen( $line ) + 2 > $chunk_size_chars ) {
					if ( ! empty( $current ) ) {
						$chunks[] = trim( $current );
						$overlap_text = substr( $current, -$overlap_chars );
						$current      = $overlap_text . "\n\n" . $line;
					} else {
						$current = $line;
					}
				} else {
					$current .= ( empty( $current ) ? '' : "\n\n" ) . $line;
				}
			}
		}

		if ( ! empty( $current ) ) {
			$chunks[] = trim( $current );
		}

		return $chunks;
	}
	
	public function estimate_tokens( string $text ): int {
		return (int) ceil( strlen( $text ) / self::CHARS_PER_TOKEN );
	}
}
