<?php
/**
 * Single Post Generator Class
 *
 * Generates single post content using AI providers
 *
 * @package SmartyPress_AI_Engine
 * @since 1.0.0
 */

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

/**
 * Single Post Generator class
 */
class SmartyPress_AI_Single_Post_Generator extends SmartyPress_AI_Abstract_Post_Generator {

	/**
	 * Generate categories
	 *
	 * @param string $title Post title.
	 * @param string $content Post content.
	 * @param string $taxonomy Taxonomy name.
	 * @param string $provider_name Provider name.
	 * @param string $language Language for generation.
	 * @return array Response with categories or error.
	 */
	public function generate_categories( $title, $content, $taxonomy = 'category', $provider_name = '', $language = '' ) {
		$provider = $this->get_provider( $provider_name );

		if ( ! $provider ) {
			$error_response = array(
				'success'    => false,
				'error'      => __( 'API key not configured. Go to SmartyPress AI > Settings and add your OpenAI or Deepseek API key.', 'smartypress-ai-engine' ),
				'error_code' => 'api_key_missing',
			);
			
			// Add debug info if WP_DEBUG is enabled
			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				$error_response['debug_info'] = array(
					'requested_provider'  => $provider_name ?: ( $this->settings['default_provider'] ?? 'openai' ),
					'available_providers' => ! empty( $this->providers ) ? implode( ', ', array_keys( $this->providers ) ) : 'none',
					'has_settings'        => ! empty( $this->settings ),
					'settings_keys'       => ! empty( $this->settings ) ? array_keys( $this->settings ) : array(),
				);
			}
			
			return $error_response;
		}

		// Get existing categories
		$existing_terms = get_terms(
			array(
				'taxonomy'   => $taxonomy,
				'hide_empty' => false,
			)
		);

		if ( empty( $existing_terms ) || is_wp_error( $existing_terms ) ) {
			return array(
				'success'    => false,
				'error'      => __( 'No categories available', 'smartypress-ai-engine' ),
			);
		}

		$categories_list = array_map(
			function( $term ) {
				return $term->name;
			},
			$existing_terms
		);

		// Use provided language, settings default, or site language
		if ( empty( $language ) ) {
			$language = $this->settings['default_language'] ?? $this->get_site_language();
		}

		$system_prompt = sprintf(
			/* translators: %s: Language name */
			__( 'You are a content categorization expert. Select the most relevant categories from the provided list. Respond with a comma-separated list of category names only. Language: %s', 'smartypress-ai-engine' ),
			$language
		);

		$user_prompt = sprintf(
			/* translators: 1: Title, 2: Content preview, 3: Categories list */
			__( 'Based on this content - Title: "%1$s", Content preview: "%2$s" - select the most relevant categories (maximum 3) from this list: %3$s', 'smartypress-ai-engine' ),
			$title,
			wp_trim_words( wp_strip_all_tags( $content ), 50 ),
			implode( ', ', $categories_list )
		);

		$params = array(
			'system_prompt' => $this->add_cache_buster( $system_prompt ),
			'temperature'   => 0.3,
			'max_tokens'    => 100,
		);

		$result = $provider->generate_content( $user_prompt, $params );

		if ( $result['success'] ) {
			// Parse categories from response
			$suggested_categories = array_map( 'trim', explode( ',', $result['content'] ) );
			
			// Match with existing categories
			$matched_terms = array();
			foreach ( $suggested_categories as $cat_name ) {
				foreach ( $existing_terms as $term ) {
					if ( strcasecmp( $term->name, $cat_name ) === 0 ) {
						$matched_terms[] = $term->term_id;
						break;
					}
				}
			}

			$result['categories'] = $matched_terms;
		}

		return $result;
	}

	/**
	 * Generate complete post data (title, content, excerpt, categories)
	 *
	 * @param string $context Context for generation.
	 * @param string $provider_name Provider name.
	 * @param array  $options Additional options.
	 * @return array Response with post data or error.
	 */
	public function generate_post_data( $context, $provider_name = '', $options = array() ) {
		// Generate title
		$title_result = $this->generate_title( $context, $provider_name, $options );
		if ( ! $title_result['success'] ) {
			return $title_result;
		}
		$title = $title_result['title'];

		// Generate content
		$content_result = $this->generate_content( $title, $context, $provider_name, $options );
		if ( ! $content_result['success'] ) {
			return $content_result;
		}
		$content = $content_result['content'];

		// Generate excerpt
		$excerpt_options = array_merge( $options, array( 'title' => $title ) );
		$excerpt_result = $this->generate_excerpt( $content, $provider_name, $excerpt_options );
		$excerpt = $excerpt_result['success'] ? $excerpt_result['excerpt'] : '';

		// Generate categories
		$categories_result = $this->generate_categories( $title, $content, 'category', $provider_name );
		$categories = $categories_result['success'] ? $categories_result['categories'] : array();

		return array(
			'success'    => true,
			'title'      => $title,
			'content'    => $content,
			'excerpt'    => $excerpt,
			'categories' => $categories,
		);
	}

	/**
	 * Generate content with custom prompt (Wand functionality)
	 *
	 * @param string $action Action name.
	 * @param array  $arguments Arguments for generation.
	 * @param string $provider_name Provider name.
	 * @return array Response with generated content.
	 */
	public function generate_with_prompt( $action, $arguments, $provider_name = '' ) {
		$provider = $this->get_provider( $provider_name );

		if ( ! $provider ) {
			$error_response = array(
				'success'    => false,
				'error'      => __( 'API key not configured. Go to SmartyPress AI > Settings and add your OpenAI or Deepseek API key.', 'smartypress-ai-engine' ),
				'error_code' => 'api_key_missing',
			);
			
			// Add debug info if WP_DEBUG is enabled
			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				$error_response['debug_info'] = array(
					'requested_provider'  => $provider_name ?: ( $this->settings['default_provider'] ?? 'openai' ),
					'available_providers' => ! empty( $this->providers ) ? implode( ', ', array_keys( $this->providers ) ) : 'none',
					'has_settings'        => ! empty( $this->settings ),
					'settings_keys'       => ! empty( $this->settings ) ? array_keys( $this->settings ) : array(),
				);
			}
			
			return $error_response;
		}

		// Get feature configuration
		$feature = SmartyPress_AI_Wand_Features::get_feature( $action );
		
		if ( ! $feature ) {
			return array(
				'success' => false,
				'error'   => __( 'Invalid action', 'smartypress-ai-engine' ),
			);
		}

		// Build prompt
		$prompt = $this->build_wand_prompt( $action, $arguments, $feature );
		
		if ( empty( $prompt ) ) {
			return array(
				'success' => false,
				'error'   => __( 'Prompt is required', 'smartypress-ai-engine' ),
			);
		}

		// Apply filter for custom prompt modification
		$prompt = apply_filters( 'smartypress_ai_prompt_' . $action, $prompt, $arguments );

		// Get generation parameters
		$max_results = isset( $feature['results'] ) ? intval( $feature['results'] ) : 1;
		$mode        = isset( $feature['mode'] ) ? $feature['mode'] : 'replace';

		// Use temperature and model from arguments if provided, otherwise fall back to settings
		$temperature = isset( $arguments['temperature'] ) ? floatval( $arguments['temperature'] ) : ( $this->settings['temperature'] ?? 0.7 );
		$model       = ! empty( $arguments['model'] ) ? sanitize_text_field( $arguments['model'] ) : '';

		// Get language from settings or use site language
		$language = $this->settings['default_language'] ?? $this->get_site_language();

		// Build system prompt with format instructions based on action type
		$html_actions = array( 'enhanceText', 'longerText', 'shorterText', 'correctText', 'translateText' );
		$format_instruction = '';
		if ( in_array( $action, $html_actions, true ) ) {
			// Actions that modify existing block content - preserve HTML structure
			$format_instruction = ' If the input text contains HTML tags (like <strong>, <em>, <a>, <ul>, <li>, etc.), you MUST preserve all HTML tags and structure in your output. Only modify the text content between the tags, not the tags themselves.';
		} elseif ( 'generateContent' === $action ) {
			// Content generation - use Markdown format
			$format_instruction = ' FORMAT RULES (STRICT): Always use Markdown for formatting (## for headings, **bold**, *italic*, lists). NEVER use HTML tags. Use ## for section headings.';
		}

		// Prepare API parameters
		$params = array(
			'system_prompt' => $this->add_cache_buster( sprintf(
				/* translators: %s: Language name */
				__( 'You are a professional content assistant. Always respond in %s. Do not switch to any other language unless the user explicitly asks for translation.', 'smartypress-ai-engine' ),
				$language
			) . $format_instruction ),
			'temperature'   => $temperature,
			'max_tokens'    => $this->settings['max_tokens'] ?? 2000,
		);

		if ( ! empty( $model ) ) {
			$params['model'] = $model;
		}

		// Apply filter for parameters
		$params = apply_filters( 'smartypress_ai_wand_params', $params, $action );

		// Generate content
		$result = $provider->generate_content( $prompt, $params );

		if ( ! $result['success'] ) {
			return $result;
		}

		// Convert markdown to HTML for proper Gutenberg block rendering
		$html_content = SmartyPress_AI_Prompt_Processor::markdown_to_html( $result['content'] );

		// Check if original text contained <p> tags
		$original_text = $arguments['text'] ?? '';
		$original_has_p_tags = preg_match( '/<p[\s>]/i', $original_text );

		// If original text didn't have <p> tags, remove them from result
		if ( ! $original_has_p_tags ) {
			$html_content = $this->strip_single_paragraph_wrapper( $html_content );
		}

		// Handle different modes
		if ( $mode === 'suggest' && $max_results > 1 ) {
			// Generate multiple variants
			$results = array( $html_content );
			
			for ( $i = 1; $i < $max_results; $i++ ) {
				$variant_result = $provider->generate_content( $prompt, $params );
				if ( $variant_result['success'] ) {
					$variant_html = SmartyPress_AI_Prompt_Processor::markdown_to_html( $variant_result['content'] );
					// Apply same <p> tag removal logic
					if ( ! $original_has_p_tags ) {
						$variant_html = $this->strip_single_paragraph_wrapper( $variant_html );
					}
					$results[] = $variant_html;
				}
			}

			return array(
				'success' => true,
				'mode'    => 'suggest',
				'type'    => 'text',
				'result'  => $results[0],
				'results' => $results,
			);
		}

		// Replace mode
		return array(
			'success' => true,
			'mode'    => 'replace',
			'type'    => 'text',
			'result'  => $html_content,
			'results' => array( $html_content ),
		);
	}

	/**
	 * Strip a single paragraph wrapper when the original selection was inline text.
	 *
	 * @param string $content Generated HTML or escaped HTML.
	 * @return string
	 */
	private function strip_single_paragraph_wrapper( $content ) {
		$content = trim( (string) $content );

		if ( preg_match( '/^<p(?:\s[^>]*)?>(.*)<\/p>$/is', $content, $matches ) ) {
			return trim( $matches[1] );
		}

		if ( preg_match( '/^&lt;p(?:\s[^&]*)?&gt;(.*)&lt;\/p&gt;$/is', $content, $matches ) ) {
			return trim( $matches[1] );
		}

		return $content;
	}

	/**
	 * Build prompt for wand action
	 *
	 * @param string $action Action name.
	 * @param array  $arguments Arguments.
	 * @param array  $feature Feature configuration.
	 * @return string Built prompt.
	 */
	private function build_wand_prompt( $action, $arguments, $feature ) {
		// If custom prompt provided, use it with variable substitution
		if ( ! empty( $arguments['prompt'] ) ) {
			$prompt = $arguments['prompt'];

			// Build variables for substitution
			$variables = array();
			if ( ! empty( $arguments['text'] ) ) {
				$variables['TEXT'] = $arguments['text'];
			}
			if ( ! empty( $arguments['context'] ) ) {
				$variables['CONTEXT'] = $arguments['context'];
				$variables['TOPIC']   = $arguments['context'];
			}
			if ( ! empty( $arguments['content'] ) ) {
				$variables['CONTENT'] = wp_trim_words( wp_strip_all_tags( $arguments['content'] ), 100 );
			}
			if ( ! empty( $arguments['selectedText'] ) ) {
				$variables['SELECTED_TEXT'] = $arguments['selectedText'];
			}
			if ( ! empty( $arguments['language'] ) ) {
				$variables['LANGUAGE'] = $arguments['language'];
			} else {
				$variables['LANGUAGE'] = $this->get_site_language();
			}

			// Resolve variables in the custom prompt
			$prompt = SmartyPress_AI_Prompt_Processor::process_prompt( $prompt, $variables );

			// Fallback: if prompt doesn't contain {TEXT} placeholder and text is available,
			// append it so the AI still gets the text to work with
			if ( ! empty( $arguments['text'] ) && strpos( $arguments['prompt'], '{TEXT}' ) === false ) {
				$prompt .= "\n\nText: " . $arguments['text'];
			}

			return $prompt;
		}

		// Use default prompt with placeholders
		$placeholders = array();
		
		if ( ! empty( $arguments['text'] ) ) {
			$placeholders['TEXT'] = $arguments['text'];
		}
		
		if ( ! empty( $arguments['context'] ) ) {
			$placeholders['TOPIC'] = $arguments['context'];
			$placeholders['CONTEXT'] = $arguments['context'];
		}
		
		if ( ! empty( $arguments['content'] ) ) {
			$placeholders['CONTENT'] = wp_trim_words( wp_strip_all_tags( $arguments['content'] ), 100 );
		}
		
		if ( ! empty( $arguments['selectedText'] ) ) {
			$placeholders['SELECTED_TEXT'] = $arguments['selectedText'];
		}
		
		// Always populate LANGUAGE from arguments, settings, or site language
		if ( ! empty( $arguments['language'] ) ) {
			$placeholders['LANGUAGE'] = $arguments['language'];
		} else {
			$placeholders['LANGUAGE'] = $this->settings['default_language'] ?? $this->get_site_language();
		}

		return SmartyPress_AI_Wand_Features::get_default_prompt( $action, $placeholders );
	}

	// ========================================
	// REST API Helpers
	// ========================================

	/**
	 * Get appropriate HTTP status code based on error message.
	 *
	 * @param array $result Result array with 'success' and 'error' keys.
	 * @return int HTTP status code.
	 */
	private function get_error_status_code( $result ) {
		if ( $result['success'] ) {
			return 200;
		}
		$error = $result['error'] ?? '';
		if ( stripos( $error, 'api key' ) !== false || stripos( $error, 'authentication' ) !== false || stripos( $error, 'unauthorized' ) !== false ) {
			return 401;
		}
		if ( stripos( $error, 'rate limit' ) !== false || stripos( $error, '429' ) !== false ) {
			return 429;
		}
		if ( stripos( $error, 'not found' ) !== false || stripos( $error, '404' ) !== false ) {
			return 404;
		}
		return 422;
	}

	// ========================================
	// REST API Endpoints
	// ========================================

	/**
	 * REST API endpoint: Generate title
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_title_endpoint( $request ) {
		$context  = sanitize_text_field( $request->get_param( 'context' ) );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.7 );
		$prompt_template = sanitize_textarea_field( $request->get_param( 'prompt_template' ) );

		if ( empty( $context ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Context is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$current_title = sanitize_text_field( $request->get_param( 'current_title' ) );

		$options = array(
			'prompt_template' => $prompt_template,
			'language'        => $language,
			'temperature'     => $temperature,
			'current_title'   => $current_title,
		);

		$result = $this->generate_title( $context, $provider, $options );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate content
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_content_endpoint( $request ) {
		$title    = sanitize_text_field( $request->get_param( 'title' ) );
		$context  = sanitize_text_field( $request->get_param( 'context' ) );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );
		$sections = sanitize_textarea_field( $request->get_param( 'sections' ) );
		$paragraphs_per_section = sanitize_text_field( $request->get_param( 'paragraphs_per_section' ) ?: '3' );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.7 );
		$prompt_template = sanitize_textarea_field( $request->get_param( 'prompt_template' ) );

		if ( empty( $title ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Title is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$options = array(
			'prompt_template'      => $prompt_template,
			'language'            => $language,
			'sections'             => $sections,
			'paragraphs_per_section' => $paragraphs_per_section,
			'temperature'         => $temperature,
		);

		$result = $this->generate_content( $title, $context, $provider, $options );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate excerpt
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_excerpt_endpoint( $request ) {
		$content  = wp_kses_post( $request->get_param( 'content' ) );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$title    = sanitize_text_field( $request->get_param( 'title' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.5 );
		$prompt_template = sanitize_textarea_field( $request->get_param( 'prompt_template' ) );

		if ( empty( $content ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Content is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$current_excerpt = sanitize_text_field( $request->get_param( 'current_excerpt' ) );

		$options = array(
			'prompt_template' => $prompt_template,
			'title'           => $title,
			'language'        => $language,
			'temperature'     => $temperature,
			'current_excerpt' => $current_excerpt,
		);

		$result = $this->generate_excerpt( $content, $provider, $options );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate categories
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_categories_endpoint( $request ) {
		$title    = sanitize_text_field( $request->get_param( 'title' ) );
		$content  = wp_kses_post( $request->get_param( 'content' ) );
		$taxonomy = sanitize_text_field( $request->get_param( 'taxonomy' ) );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );

		if ( empty( $title ) || empty( $content ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Title and content are required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$result = $this->generate_categories( $title, $content, $taxonomy ?: 'category', $provider, $language );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate post data
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_post_data_endpoint( $request ) {
		$context  = sanitize_text_field( $request->get_param( 'context' ) );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.7 );
		$prompts = $request->get_param( 'prompts' );

		if ( empty( $context ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Context is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$options = array(
			'language'     => $language,
			'temperature'  => $temperature,
			'prompt_template' => is_array( $prompts ) && isset( $prompts['title'] ) ? $prompts['title'] : '',
		);

		$result = $this->generate_post_data( $context, $provider, $options );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Create post
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function create_post_endpoint( $request ) {
		$post_data = array(
			'post_title'   => sanitize_text_field( $request->get_param( 'title' ) ),
			'post_content' => wp_kses_post( $request->get_param( 'content' ) ),
			'post_excerpt' => sanitize_textarea_field( $request->get_param( 'excerpt' ) ),
			'post_status'  => sanitize_text_field( $request->get_param( 'status' ) ?: 'draft' ),
			'post_type'    => sanitize_text_field( $request->get_param( 'post_type' ) ?: 'post' ),
			'categories'   => $request->get_param( 'categories' ) ? array_map( 'absint', (array) $request->get_param( 'categories' ) ) : array(),
		);

		$result = $this->create_post( $post_data );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate editable post plan.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_post_plan_endpoint( $request ) {
		$topic       = sanitize_textarea_field( $request->get_param( 'topic' ) );
		$language    = sanitize_text_field( $request->get_param( 'language' ) );
		$post_type   = sanitize_text_field( $request->get_param( 'post_type' ) ?: 'post' );
		$provider    = $this->validate_provider( $request->get_param( 'provider' ) );
		$model       = sanitize_text_field( $request->get_param( 'model' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.7 );
		$max_tokens  = absint( $request->get_param( 'max_tokens' ) );
		$plan_expert_mode = rest_sanitize_boolean( $request->get_param( 'plan_expert_mode' ) );
		$plan_prompt_template = sanitize_textarea_field( $request->get_param( 'plan_prompt_template' ) );

		if ( empty( $topic ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Topic is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$result = $this->generate_post_plan(
			$topic,
			$provider,
			array(
				'language'    => $language,
				'post_type'   => $post_type,
				'model'       => $model,
				'temperature' => $temperature,
				'max_tokens'  => $max_tokens,
				'plan_expert_mode' => $plan_expert_mode,
				'plan_prompt_template' => $plan_prompt_template,
			)
		);

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Improve plan prompt template.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function improve_plan_prompt_template_endpoint( $request ) {
		$prompt      = sanitize_textarea_field( $request->get_param( 'prompt' ) );
		$language    = sanitize_text_field( $request->get_param( 'language' ) );
		$provider    = $this->validate_provider( $request->get_param( 'provider' ) );
		$model       = sanitize_text_field( $request->get_param( 'model' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.4 );
		$max_tokens  = absint( $request->get_param( 'max_tokens' ) );

		if ( empty( $prompt ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Prompt template is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$result = $this->improve_plan_prompt_template(
			$prompt,
			$provider,
			array(
				'language'    => $language,
				'model'       => $model,
				'temperature' => $temperature,
				'max_tokens'  => $max_tokens,
			)
		);

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Apply instruction to editable plan.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function apply_post_plan_instruction_endpoint( $request ) {
		$plan        = $request->get_param( 'plan' );
		$instruction = sanitize_textarea_field( $request->get_param( 'instruction' ) );
		$language    = sanitize_text_field( $request->get_param( 'language' ) );
		$provider    = $this->validate_provider( $request->get_param( 'provider' ) );
		$model       = sanitize_text_field( $request->get_param( 'model' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.5 );

		if ( empty( $plan ) || empty( $instruction ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Plan and instruction are required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$result = $this->apply_post_plan_instruction(
			is_array( $plan ) ? $plan : array(),
			$instruction,
			$provider,
			array(
				'language'    => $language,
				'model'       => $model,
				'temperature' => $temperature,
			)
		);

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate final draft from plan.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_draft_from_plan_endpoint( $request ) {
		$plan                   = $request->get_param( 'plan' );
		$topic                  = sanitize_textarea_field( $request->get_param( 'topic' ) );
		$language               = sanitize_text_field( $request->get_param( 'language' ) );
		$post_type              = sanitize_text_field( $request->get_param( 'post_type' ) ?: 'post' );
		$provider               = $this->validate_provider( $request->get_param( 'provider' ) );
		$model                  = sanitize_text_field( $request->get_param( 'model' ) );
		$temperature            = floatval( $request->get_param( 'temperature' ) ?: 0.7 );
		$max_tokens             = absint( $request->get_param( 'max_tokens' ) ?: 0 );
		$generate_image_markers = rest_sanitize_boolean( $request->get_param( 'generate_image_markers' ) ) && $this->is_image_generator_enabled();

		if ( empty( $plan ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Plan is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$result = $this->generate_draft_from_plan(
			is_array( $plan ) ? $plan : array(),
			$provider,
			array(
				'topic'                  => $topic,
				'language'               => $language,
				'post_type'              => $post_type,
				'model'                  => $model,
				'temperature'            => $temperature,
				'max_tokens'             => $max_tokens ?: null,
				'generate_image_markers' => $generate_image_markers,
			)
		);

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * Check whether the Image Generator module is currently enabled.
	 *
	 * @return bool
	 */
	private function is_image_generator_enabled() {
		global $smartypress_ai_plugin;

		$module_manager = $smartypress_ai_plugin ? $smartypress_ai_plugin->get_module_manager() : null;

		if ( $module_manager && method_exists( $module_manager, 'is_module_enabled' ) ) {
			return (bool) $module_manager->is_module_enabled( 'image_generator' );
		}

		return false;
	}

	/**
	 * REST API endpoint: Wand action
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function wand_endpoint( $request ) {
		$action   = sanitize_text_field( $request->get_param( 'action' ) );
		$data     = $request->get_param( 'data' );

		if ( empty( $action ) || empty( $data ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Action and data are required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		// Validate action
		if ( ! SmartyPress_AI_Wand_Features::is_valid_action( $action ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Invalid action', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		// Sanitize data
		$sanitized_data = array();
		
		if ( isset( $data['postId'] ) ) {
			$sanitized_data['postId'] = absint( $data['postId'] );
		}
		
		if ( isset( $data['prompt'] ) ) {
			$prompt = sanitize_textarea_field( $data['prompt'] );
			
			// Validate prompt length
			if ( strlen( $prompt ) > 5000 ) {
				return new WP_REST_Response(
					array(
						'success' => false,
						'error'   => __( 'Prompt is too long (max 5000 characters)', 'smartypress-ai-engine' ),
					),
					400
				);
			}
			
			$sanitized_data['prompt'] = $prompt;
		}
		
		if ( isset( $data['text'] ) ) {
			$sanitized_data['text'] = wp_kses_post( $data['text'] );
		}
		
		if ( isset( $data['context'] ) ) {
			$context = sanitize_textarea_field( $data['context'] );
			
			// Validate context length
			if ( strlen( $context ) > 10000 ) {
				return new WP_REST_Response(
					array(
						'success' => false,
						'error'   => __( 'Context is too long (max 10000 characters)', 'smartypress-ai-engine' ),
					),
					400
				);
			}
			
			$sanitized_data['context'] = $context;
		}
		
		if ( isset( $data['content'] ) ) {
			$sanitized_data['content'] = wp_kses_post( $data['content'] );
		}
		
		if ( isset( $data['selectedText'] ) ) {
			$sanitized_data['selectedText'] = sanitize_text_field( $data['selectedText'] );
		}
		
		if ( isset( $data['language'] ) ) {
			$sanitized_data['language'] = sanitize_text_field( $data['language'] );
		}

		if ( isset( $data['temperature'] ) ) {
			$sanitized_data['temperature'] = floatval( $data['temperature'] );
		}

		if ( isset( $data['model'] ) ) {
			$sanitized_data['model'] = sanitize_text_field( $data['model'] );
		}
		
		// Validate and sanitize provider
		$provider = $this->validate_provider( $data['provider'] ?? '' );

		// Generate with wand
		$result = $this->generate_with_prompt( $action, $sanitized_data, $provider );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate sections
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_sections_endpoint( $request ) {
		$topic    = sanitize_text_field( $request->get_param( 'topic' ) );
		$title    = sanitize_text_field( $request->get_param( 'title' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );
		$number_of_sections = sanitize_text_field( $request->get_param( 'number_of_sections' ) ?: '2' );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.8 );
		$prompt_template = sanitize_textarea_field( $request->get_param( 'prompt_template' ) );

		if ( empty( $topic ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Topic is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$options = array(
			'prompt_template'   => $prompt_template,
			'language'         => $language,
			'number_of_sections' => $number_of_sections,
			'temperature'      => $temperature,
		);

		$result = $this->generate_sections( $topic, $title, $provider, $options );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate content with sections
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_content_with_sections_endpoint( $request ) {
		$title    = sanitize_text_field( $request->get_param( 'title' ) );
		$sections = sanitize_textarea_field( $request->get_param( 'sections' ) );
		$topic    = sanitize_text_field( $request->get_param( 'topic' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );
		$paragraphs_per_section = sanitize_text_field( $request->get_param( 'paragraphs_per_section' ) ?: '3' );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.8 );
		$prompt_template = sanitize_textarea_field( $request->get_param( 'prompt_template' ) );

		if ( empty( $title ) || empty( $sections ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Title and sections are required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$options = array(
			'prompt_template'      => $prompt_template,
			'language'            => $language,
			'sections'             => $sections,
			'paragraphs_per_section' => $paragraphs_per_section,
			'temperature'         => $temperature,
		);

		$result = $this->generate_content( $title, $topic, $provider, $options );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate title with custom prompt
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_title_with_prompt_endpoint( $request ) {
		$topic    = sanitize_text_field( $request->get_param( 'topic' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.8 );
		$prompt_template = sanitize_textarea_field( $request->get_param( 'prompt_template' ) );

		if ( empty( $topic ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Topic is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$options = array(
			'prompt_template' => $prompt_template,
			'language'        => $language,
			'temperature'     => $temperature,
		);

		$result = $this->generate_title( $topic, $provider, $options );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate excerpt with custom prompt
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_excerpt_with_prompt_endpoint( $request ) {
		$title    = sanitize_text_field( $request->get_param( 'title' ) );
		$content  = wp_kses_post( $request->get_param( 'content' ) );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.5 );
		$prompt_template = sanitize_textarea_field( $request->get_param( 'prompt_template' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );

		if ( empty( $content ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Content is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$options = array(
			'prompt_template' => $prompt_template,
			'title'           => $title,
			'language'        => $language,
			'temperature'     => $temperature,
		);

		$result = $this->generate_excerpt( $content, $provider, $options );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}

	/**
	 * REST API endpoint: Generate full post
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function generate_full_post_endpoint( $request ) {
		$topic    = sanitize_text_field( $request->get_param( 'topic' ) );
		$language = sanitize_text_field( $request->get_param( 'language' ) );
		$post_type = sanitize_text_field( $request->get_param( 'post_type' ) ?: 'post' );
		$number_of_sections = sanitize_text_field( $request->get_param( 'number_of_sections' ) ?: '2' );
		$paragraphs_per_section = sanitize_text_field( $request->get_param( 'paragraphs_per_section' ) ?: '3' );
		$provider = $this->validate_provider( $request->get_param( 'provider' ) );
		$temperature = floatval( $request->get_param( 'temperature' ) ?: 0.8 );
		$prompts = $request->get_param( 'prompts' );

		if ( empty( $topic ) ) {
			return new WP_REST_Response(
				array(
					'success' => false,
					'error'   => __( 'Topic is required', 'smartypress-ai-engine' ),
				),
				400
			);
		}

		$settings = array(
			'provider'              => $provider,
			'language'             => $language,
			'post_type'            => $post_type,
			'number_of_sections'   => $number_of_sections,
			'paragraphs_per_section' => $paragraphs_per_section,
			'temperature'          => $temperature,
			'prompts'              => is_array( $prompts ) ? array_map( 'sanitize_textarea_field', $prompts ) : array(),
		);

		$result = $this->generate_full_post( $topic, $settings );

		return new WP_REST_Response( $result, $this->get_error_status_code( $result ) );
	}
}

