<?php
/**
 * Content length SEO strategy.
 *
 * @package SmartyPress_AI_Engine
 * @since 1.0.0
 */

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

/**
 * Expands short content with one focused supporting paragraph.
 */
class SmartyPress_AI_SEO_Strategy_Content_Length extends SmartyPress_AI_SEO_Strategy_Base {

	const MIN_WORDS = 600;

	public function get_test_id() {
		return 'lengthContent';
	}

	public function get_reason() {
		return 'content_length';
	}

	public function get_label() {
		return __( 'Content length', 'smartypress-ai-engine' );
	}

	public function get_context_scope() {
		return 'full';
	}

	public function get_strategy_rules() {
		return array_merge(
			parent::get_strategy_rules(),
			array(
				'Add one concise supporting paragraph after the selected block.',
				'The paragraph should add practical detail that fits the article, not a CTA, summary, sales pitch, or conclusion.',
				'Write 110-150 words when the current article is below 600 words.',
				'Include primary_keyword exactly once if it can be used naturally.',
			)
		);
	}

	public function is_applicable( $context, $analysis ) {
		return $this->get_word_count( $context ) < self::MIN_WORDS && ! empty( $this->select_context( $context, $analysis )['target_block'] );
	}

	public function select_context( $context, $analysis ) {
		$blocks       = $this->flatten_blocks( $this->get_blocks( $context ) );
		$target_block = null;

		foreach ( array_reverse( $blocks ) as $block ) {
			if ( 'core/paragraph' === ( $block['name'] ?? '' ) && ! empty( $block['text'] ) && ! empty( $block['clientId'] ) ) {
				$target_block = $block;
				break;
			}
		}

		return array(
			'testId'          => $this->get_test_id(),
			'reason'          => $this->get_reason(),
			'label'           => $this->get_label(),
			'context_scope'   => $this->get_context_scope(),
			'primary_keyword' => $this->get_primary_keyword( $context, $analysis ),
			'article_summary' => $analysis['content_summary'] ?? '',
			'current_words'   => $this->get_word_count( $context ),
			'target_words'    => self::MIN_WORDS,
			'target_block'    => $target_block,
		);
	}

	public function validate_response( $response, $context, $analysis ) {
		$operations = array();
		$warnings   = array_values( array_filter( array_map( 'sanitize_text_field', (array) ( $response['warnings'] ?? array() ) ) ) );
		$keyword    = $this->get_primary_keyword( $context, $analysis );

		foreach ( (array) ( $response['content_operations'] ?? array() ) as $operation ) {
			$operation = $this->normalize_operation( $operation );
			if ( 'insert_after' !== $operation['type'] || '' === $operation['blockClientId'] || '' === $operation['html'] ) {
				continue;
			}

			$text       = $this->normalize_text( $operation['html'] );
			$word_count = $this->count_words( $text );
			if ( $word_count < 80 ) {
				$warnings[] = __( 'The generated content length fix was too short to solve the issue.', 'smartypress-ai-engine' );
				continue;
			}

			if ( '' !== $keyword && ! $this->includes_keyword( $operation['html'], $keyword ) ) {
				$warnings[] = __( 'The generated content length fix does not include the exact focus keyword.', 'smartypress-ai-engine' );
				continue;
			}

			if ( $this->has_adjacent_word_duplication( $operation['html'] ) ) {
				$warnings[] = __( 'The generated content length fix was rejected because it contains duplicated adjacent words.', 'smartypress-ai-engine' );
				continue;
			}

			$operations[] = $operation;
			break;
		}

		return array(
			'status'             => ! empty( $operations ) ? 'success' : 'validation_failure',
			'testId'             => $this->get_test_id(),
			'reason'             => $this->get_reason(),
			'label'              => $this->get_label(),
			'content_operations' => $operations,
			'fixed_tests'        => ! empty( $operations ) ? array( $this->get_test_id() ) : array(),
			'skipped_tests'      => empty( $operations ) ? array( array( 'id' => $this->get_test_id(), 'reason' => $this->get_failure_reason( $warnings, __( 'AI could not safely expand the content.', 'smartypress-ai-engine' ) ) ) ) : array(),
			'warnings'           => array_values( array_unique( $warnings ) ),
		);
	}

	private function flatten_blocks( $blocks ) {
		$flat = array();

		foreach ( (array) $blocks as $block ) {
			if ( is_array( $block ) ) {
				$flat[] = $block;
				if ( ! empty( $block['innerBlocks'] ) ) {
					$flat = array_merge( $flat, $this->flatten_blocks( $block['innerBlocks'] ) );
				}
			}
		}

		return $flat;
	}

	private function get_word_count( $context ) {
		return $this->count_words( $context['post']['content_plain_text'] ?? '' );
	}

	private function count_words( $text ) {
		$words = preg_split( '/\s+/u', $this->normalize_text( $text ), -1, PREG_SPLIT_NO_EMPTY );

		return is_array( $words ) ? count( $words ) : 0;
	}
}
