<?php
/**
 * Legacy post generation service.
 *
 * @package SmartyPress_AI_Engine
 */

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

/**
 * Orchestrates the legacy bulk flow: title, sections, content, excerpt.
 */
class SmartyPress_AI_Content_Generator_Legacy_Post_Generation_Service {

	/**
	 * Generated title validator.
	 *
	 * @var SmartyPress_AI_Content_Generator_Generated_Title_Validator
	 */
	private $title_validator;

	/**
	 * SEO content fallback optimizer.
	 *
	 * @var SmartyPress_AI_Content_Generator_SEO_Content_Optimization_Service
	 */
	private $seo_content_optimizer;

	/**
	 * Constructor.
	 *
	 * @param SmartyPress_AI_Content_Generator_Generated_Title_Validator|null       $title_validator Title validator.
	 * @param SmartyPress_AI_Content_Generator_SEO_Content_Optimization_Service|null $seo_content_optimizer SEO content optimizer.
	 */
	public function __construct( $title_validator = null, $seo_content_optimizer = null ) {
		$this->title_validator       = $title_validator instanceof SmartyPress_AI_Content_Generator_Generated_Title_Validator ? $title_validator : new SmartyPress_AI_Content_Generator_Generated_Title_Validator();
		$this->seo_content_optimizer = $seo_content_optimizer instanceof SmartyPress_AI_Content_Generator_SEO_Content_Optimization_Service ? $seo_content_optimizer : new SmartyPress_AI_Content_Generator_SEO_Content_Optimization_Service();
	}

	/**
	 * Generate a full post through the legacy prompt chain.
	 *
	 * @param object $generator Step service with title, sections, content, and excerpt methods.
	 * @param string $topic Topic/context.
	 * @param array  $settings Generation settings.
	 * @param string $site_language Site language fallback.
	 * @param float  $default_temperature Default temperature.
	 * @return array
	 */
	public function generate_full_post( $generator, $topic, $settings, $site_language, $default_temperature ) {
		$provider_name          = $settings['provider'] ?? '';
		$language               = $settings['language'] ?? $site_language;
		$number_of_sections     = $settings['number_of_sections'] ?? '2';
		$paragraphs_per_section = $settings['paragraphs_per_section'] ?? '3';
		$temperature            = $settings['temperature'] ?? $default_temperature;
		$context                = $settings['context'] ?? '';
		$model                  = sanitize_text_field( $settings['model'] ?? '' );

		$prompts         = $settings['prompts'] ?? array();
		$title_prompt    = $prompts['title'] ?? '';
		$sections_prompt = $prompts['sections'] ?? '';
		$content_prompt  = $prompts['content'] ?? '';
		$excerpt_prompt  = $prompts['excerpt'] ?? '';

		$title_options = array(
			'prompt_template' => $title_prompt,
			'language'        => $language,
			'model'           => $model,
			'temperature'     => $temperature,
			'context'         => $context,
		);
		$title_options['context'] = $this->append_title_generation_context( $title_options['context'], $topic, $language );
		$title_result  = $generator->generate_title( $topic, $provider_name, $title_options );

		if ( empty( $title_result['success'] ) ) {
			return $title_result;
		}

		$title = trim( $title_result['title'] ?? '' );

		if ( '' === $title && '' !== $title_prompt ) {
			$title_options['prompt_template'] = '';
			$title_result = $generator->generate_title( $topic, $provider_name, $title_options );

			if ( empty( $title_result['success'] ) ) {
				return $title_result;
			}

			$title = trim( $title_result['title'] ?? '' );
		}

		if ( $this->title_validator->is_placeholder_or_copied_title( $title, $topic ) ) {
			$retry_options                    = $title_options;
			$retry_options['prompt_template'] = $this->get_title_language_retry_prompt();
			$retry_options['current_title']   = $title;
			$title_result                     = $generator->generate_title( $topic, $provider_name, $retry_options );

			if ( ! empty( $title_result['success'] ) ) {
				$retry_title = trim( $title_result['title'] ?? '' );
				if ( '' !== $retry_title && ! $this->title_validator->is_placeholder_or_copied_title( $retry_title, $topic ) ) {
					$title = $retry_title;
				}
			}

			if ( $this->title_validator->is_placeholder_or_copied_title( $title, $topic ) ) {
				$retry_options['prompt_template'] = '';
				$title_result                     = $generator->generate_title( $topic, $provider_name, $retry_options );

				if ( ! empty( $title_result['success'] ) ) {
					$retry_title = trim( $title_result['title'] ?? '' );
					if ( '' !== $retry_title && ! $this->title_validator->is_placeholder_or_copied_title( $retry_title, $topic ) ) {
						$title = $retry_title;
					}
				}
			}
		}

		$title_was_fallback = false;

		if ( $this->title_validator->is_placeholder_or_copied_title( $title, $topic ) ) {
			return array(
				'success' => false,
				'error'   => __( 'AI returned a copied or placeholder title. Please try another model or adjust the bulk generation title prompt.', 'smartypress-ai-engine' ),
			);
		}

		if ( '' === $title ) {
			$title = $this->build_fallback_title( $settings['item'] ?? array() );

			if ( '' === $title ) {
				return array(
					'success' => false,
					'error'   => __( 'AI did not return a valid title. Please try another model or add a focus keyword to the bulk item.', 'smartypress-ai-engine' ),
				);
			}

			$title_was_fallback = true;
		}

		$sections_options = array(
			'prompt_template'    => $sections_prompt,
			'language'           => $language,
			'model'              => $model,
			'number_of_sections' => $number_of_sections,
			'temperature'        => $temperature,
			'context'            => $context,
		);
		$sections_result  = $generator->generate_sections( $topic, $title, $provider_name, $sections_options );

		if ( empty( $sections_result['success'] ) ) {
			return $sections_result;
		}

		$sections = trim( $sections_result['sections'] ?? '' );

		if ( '' === $sections && '' !== $sections_prompt ) {
			$sections_options['prompt_template'] = '';
			$sections_result = $generator->generate_sections( $topic, $title, $provider_name, $sections_options );

			if ( empty( $sections_result['success'] ) ) {
				return $sections_result;
			}

			$sections = trim( $sections_result['sections'] ?? '' );
		}

		$content_options = array(
			'prompt_template'        => $content_prompt,
			'language'               => $language,
			'model'                  => $model,
			'sections'               => $sections,
			'paragraphs_per_section' => $paragraphs_per_section,
			'temperature'            => $temperature,
			'context'                => $context,
			'max_tokens'             => $this->resolve_content_max_tokens( $settings ),
		);
		$content_result  = $generator->generate_content( $title, $topic, $provider_name, $content_options );

		if ( empty( $content_result['success'] ) ) {
			return $content_result;
		}

		$content = trim( $content_result['content'] ?? '' );
		if ( $this->is_content_response_truncated( $content_result, $content ) ) {
			return $this->get_truncated_content_error();
		}

		if ( '' === $content && '' !== $content_prompt ) {
			$content_options['prompt_template'] = '';
			$content_result = $generator->generate_content( $title, $topic, $provider_name, $content_options );

			if ( empty( $content_result['success'] ) ) {
				return $content_result;
			}

			$content = trim( $content_result['content'] ?? '' );
			if ( $this->is_content_response_truncated( $content_result, $content ) ) {
				return $this->get_truncated_content_error();
			}
		}

		if ( '' === $content ) {
			return array(
				'success' => false,
				'error'   => __( 'AI returned empty content. Please try another model or adjust the bulk generation prompt.', 'smartypress-ai-engine' ),
			);
		}

		$excerpt_options = array(
			'prompt_template' => $excerpt_prompt,
			'title'           => $title,
			'language'        => $language,
			'model'           => $model,
			'temperature'     => $temperature,
			'topic'           => $topic,
			'context'         => $context,
		);
		$excerpt_result  = $generator->generate_excerpt( $content, $provider_name, $excerpt_options );
		$excerpt         = ! empty( $excerpt_result['success'] ) ? $excerpt_result['excerpt'] : '';
		$stage_callback  = $settings['stage_callback'] ?? null;

		if ( is_callable( $stage_callback ) ) {
			call_user_func( $stage_callback, 'seo_optimizing' );
		}

		$seo_rules = method_exists( $generator, 'get_post_type_seo_rules' )
			? $generator->get_post_type_seo_rules( $settings['post_type'] ?? 'post', $settings )
			: array();
		$seo_result = array( 'seo_keywords' => $this->build_keywords( $topic, $title, $settings['item'] ?? array() ), 'seo_metadata' => array() );

		if ( empty( $settings['disable_seo_optimization'] ) && apply_filters( 'smartypress_ai_bulk_seo_optimization_enabled', true, $settings ) && method_exists( $generator, 'optimize_generated_post_for_seo' ) ) {
			$seo_result = $generator->optimize_generated_post_for_seo(
				array(
					'provider'      => $provider_name,
					'model'         => $model,
					'temperature'   => min( 0.4, (float) $temperature ),
					'topic'         => $topic,
					'title'         => $title,
					'sections'      => $sections,
					'content'       => $content,
					'excerpt'       => $excerpt,
					'language'      => $language,
					'context'       => $context,
					'post_type'     => $settings['post_type'] ?? 'post',
					'post_status'   => $settings['post_status'] ?? 'draft',
					'seo_keywords'  => $this->build_keywords( $topic, $title, $settings['item'] ?? array() ),
					'seo_rules'     => $seo_rules,
					'item'          => $settings['item'] ?? array(),
				)
			);
		}

		if ( $title_was_fallback && ! empty( $seo_result['seo_metadata']['seo_title'] ) ) {
			$title = sanitize_text_field( $seo_result['seo_metadata']['seo_title'] );
		}

		$primary_keyword = sanitize_text_field( $seo_result['seo_metadata']['primary_keyword'] ?? ( $seo_result['seo_keywords'][0] ?? '' ) );
		if ( '' !== $primary_keyword ) {
			$content = $this->seo_content_optimizer->optimize(
				$content,
				$primary_keyword,
				array(
					'seo_source' => $seo_result['source'] ?? 'fallback',
					'language'   => $language,
					'topic'      => $topic,
					'title'      => $title,
				)
			);
		}

		return array(
			'success'      => true,
			'title'        => $title,
			'sections'     => $sections,
			'content'      => $content,
			'excerpt'      => $excerpt,
			'seo_keywords' => $seo_result['seo_keywords'] ?? $this->build_keywords( $topic, $title, $settings['item'] ?? array() ),
			'seo_metadata' => $seo_result['seo_metadata'] ?? array(),
			'seo_source'   => $seo_result['source'] ?? 'fallback',
		);
	}

	/**
	 * Build a minimal keyword list for legacy bulk generation.
	 *
	 * @param string $topic Topic.
	 * @param string $title Title.
	 * @param array  $item Bulk item metadata.
	 * @return array
	 */
	private function build_keywords( $topic, $title, $item = array() ) {
		$items = array();
		$item  = is_array( $item ) ? $item : array();

		if ( ! empty( $item['focus_keyword'] ) ) {
			$items[] = sanitize_text_field( $item['focus_keyword'] );
		}

		foreach ( array( $title, $topic ) as $value ) {
			$value = trim( preg_replace( '/\s+/u', ' ', wp_strip_all_tags( (string) $value ) ) );
			if ( '' === $value ) {
				continue;
			}

			$words = preg_split( '/\s+/u', $value, -1, PREG_SPLIT_NO_EMPTY );
			if ( is_array( $words ) && count( $words ) > 3 ) {
				$value = implode( ' ', array_slice( $words, 0, 3 ) );
			}

			$items[] = sanitize_text_field( $value );
		}

		return array_values( array_unique( array_filter( $items ) ) );
	}

	/**
	 * Build a neutral fallback title when the model returns an empty title.
	 *
	 * @param array $item Bulk item metadata.
	 * @return string
	 */
	private function build_fallback_title( $item ) {
		$item    = is_array( $item ) ? $item : array();
		$keyword = sanitize_text_field( $item['focus_keyword'] ?? '' );

		if ( '' === $keyword ) {
			return '';
		}

		return ucwords( strtolower( $keyword ) );
	}

	/**
	 * Resolve a safe token budget for bulk article body generation.
	 *
	 * @param array $settings Generation settings.
	 * @return int
	 */
	private function resolve_content_max_tokens( $settings ) {
		$explicit = absint( $settings['max_tokens'] ?? 0 );
		if ( $explicit > 0 ) {
			return $explicit;
		}

		$sections   = max( 1, absint( $settings['number_of_sections'] ?? 2 ) );
		$paragraphs = max( 1, absint( $settings['paragraphs_per_section'] ?? 3 ) );
		$estimated  = 2000 + ( $sections * $paragraphs * 800 );

		return min( 12000, max( 6000, $estimated ) );
	}

	/**
	 * Check whether the AI content response was cut before completion.
	 *
	 * @param array  $result  Provider result.
	 * @param string $content Cleaned content.
	 * @return bool
	 */
	private function is_content_response_truncated( $result, $content ) {
		$finish_reason = strtolower( sanitize_text_field( $result['finish_reason'] ?? '' ) );
		if ( in_array( $finish_reason, array( 'length', 'max_tokens', 'token_limit' ), true ) ) {
			return true;
		}

		if ( ! empty( $result['expects_content_marker'] ) && empty( $result['has_content_end_marker'] ) ) {
			return true;
		}

		return $this->has_incomplete_content_ending( $content );
	}

	/**
	 * Detect obviously unfinished article endings as a final safety net.
	 *
	 * @param string $content Cleaned Markdown content.
	 * @return bool
	 */
	private function has_incomplete_content_ending( $content ) {
		$plain = trim( preg_replace( '/\s+/u', ' ', wp_strip_all_tags( (string) $content ) ) );
		if ( '' === $plain ) {
			return false;
		}

		$last_char = function_exists( 'mb_substr' ) ? mb_substr( $plain, -1 ) : substr( $plain, -1 );
		if ( preg_match( '/[.!?…)"\']$/u', $last_char ) ) {
			return false;
		}

		$words = preg_split( '/\s+/u', $plain, -1, PREG_SPLIT_NO_EMPTY );
		if ( ! is_array( $words ) || empty( $words ) ) {
			return false;
		}

		$last_word = strtolower( trim( end( $words ), " \t\n\r\0\x0B,;:-" ) );

		return (bool) preg_match( '/^(a|an|the|and|or|but|if|when|while|with|without|for|from|to|of|in|on|at|by|as|that|this|these|those|your|their|our|its)$/i', $last_word );
	}

	/**
	 * Build a consistent error for truncated AI content.
	 *
	 * @return array
	 */
	private function get_truncated_content_error() {
		return array(
			'success' => false,
			'error'   => __( 'AI response was truncated by the token limit. Increase Max Tokens or reduce sections/paragraphs.', 'smartypress-ai-engine' ),
		);
	}

	/**
	 * Append explicit title generation rules.
	 *
	 * @param string $context Context.
	 * @param string $topic Topic.
	 * @param string $language Target language.
	 * @return string
	 */
	private function append_title_generation_context( $context, $topic, $language ) {
		$context .= "\n\n" . sprintf(
			'Title generation rule: the source topic is an idea, not a ready title. Generate a new natural article title in %s. If the source topic is written in another language, translate or adapt its meaning first. Do not copy the source topic verbatim as the title.',
			trim( (string) $language )
		);

		return trim( $context );
	}

	/**
	 * Get a strict retry prompt for title language repair.
	 *
	 * @return string
	 */
	private function get_title_language_retry_prompt() {
		return 'Generate a new natural article title in {LANGUAGE} for the source topic below. Treat the source topic as an idea, not as a ready title. If the source topic is written in another language, translate or adapt its meaning first. Do not copy the source topic verbatim. Return only the title, no formatting.
IMPORTANT: Wrap your response with ===CONTENT_START=== and ===CONTENT_END=== markers.

### SOURCE TOPIC:
{TOPIC}

### CONTEXT:
{CONTEXT}';
	}

}
