<?php
/**
 * WordPress AI Client Integration
 *
 * Provides backward-compatible AI functionality that leverages WordPress 7.0's
 * native AI Client SDK when available, with fallback to legacy implementation.
 *
 * @package WP_Agentic_Writer
 */

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

/**
 * Check if WordPress AI Client SDK is available
 *
 * @return bool True if wp_ai_client_prompt() function exists.
 */
function wpaw_is_wp_ai_client_available() {
	return function_exists( 'wp_ai_client_prompt' );
}

/**
 * Check if WordPress AI Client supports text generation
 *
 * @return bool True if text generation is supported.
 */
function wpaw_wp_ai_supports_text() {
	if ( ! wpaw_is_wp_ai_client_available() ) {
		return false;
	}

	$builder = wp_ai_client_prompt( 'test' );
	return $builder->is_supported_for_text_generation();
}

/**
 * Check if WordPress AI Client supports image generation
 *
 * @return bool True if image generation is supported.
 */
function wpaw_wp_ai_supports_images() {
	if ( ! wpaw_is_wp_ai_client_available() ) {
		return false;
	}

	$builder = wp_ai_client_prompt( 'test' );
	return $builder->is_supported_for_image_generation();
}

/**
 * Check if WordPress AI Client supports speech generation
 *
 * @return bool True if speech generation is supported.
 */
function wpaw_wp_ai_supports_speech() {
	if ( ! wpaw_is_wp_ai_client_available() ) {
		return false;
	}

	$builder = wp_ai_client_prompt( 'test' );
	return $builder->is_supported_for_speech_generation();
}

/**
 * WPAW_WP_AI_Client class
 *
 * Provides unified AI interface with WordPress 7.0 integration.
 * Falls back to legacy providers when core AI is unavailable.
 */
class WPAW_WP_AI_Client {

	/**
	 * Singleton instance
	 *
	 * @var WPAW_WP_AI_Client
	 */
	private static $instance = null;

	/**
	 * Whether WordPress AI Client is available
	 *
	 * @var bool
	 */
	private $core_available;

	/**
	 * Model preferences for different tasks
	 *
	 * @var array
	 */
	private $model_preferences = array(
		'chat' => array( 'claude-sonnet-4-20250514', 'gpt-4o', 'gemini-2.5-flash' ),
		'clarity' => array( 'claude-haiku-4-20250514', 'gpt-4o-mini', 'gemini-2.0-flash' ),
		'planning' => array( 'claude-sonnet-4-20250514', 'gpt-4o', 'gemini-2.5-flash' ),
		'writing' => array( 'claude-sonnet-4-20250514', 'gpt-4o', 'gemini-2.5-flash' ),
		'refinement' => array( 'claude-haiku-4-20250514', 'gpt-4o-mini', 'gemini-2.0-flash' ),
		'seo' => array( 'claude-sonnet-4-20250514', 'gpt-4o', 'gemini-2.5-flash' ),
		'title' => array( 'claude-haiku-4-20250514', 'gpt-4o-mini', 'gemini-2.0-flash' ),
	);

	/**
	 * Temperature settings for different tasks
	 *
	 * @var array
	 */
	private $temperature_settings = array(
		'chat' => 0.7,
		'clarity' => 0.3,
		'planning' => 0.6,
		'writing' => 0.7,
		'refinement' => 0.5,
		'seo' => 0.5,
		'title' => 0.5,
	);

	/**
	 * Get singleton instance
	 *
	 * @return WPAW_WP_AI_Client
	 */
	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor
	 */
	private function __construct() {
		$this->core_available = wpaw_is_wp_ai_client_available();
	}

	/**
	 * Check if using WordPress AI Client (true) or legacy (false)
	 *
	 * @return bool
	 */
	public function using_core() {
		return $this->core_available;
	}

	/**
	 * Get available AI mode
	 *
	 * @return string 'core', 'openrouter', or 'local'
	 */
	public function get_ai_mode() {
		if ( $this->core_available && wpaw_wp_ai_supports_text() ) {
			return 'core';
		}

		$settings = get_option( 'wp_agentic_writer_settings', array() );
		$provider = $settings['default_provider'] ?? 'openrouter';

		if ( $provider === 'local_backend' && class_exists( 'WP_Agentic_Writer_Local_Backend_Provider' ) ) {
			$local = new WP_Agentic_Writer_Local_Backend_Provider();
			if ( $local->is_configured() ) {
				return 'local';
			}
		}

		return 'openrouter';
	}

	/**
	 * Generate text using WordPress AI Client or fallback
	 *
	 * @param string $prompt  The prompt text.
	 * @param array  $options Additional options (task_type, temperature, max_tokens).
	 * @return string|WP_Error Generated text or error.
	 */
	public function generate_text( $prompt, $options = array() ) {
		$task_type = $options['task_type'] ?? 'chat';
		$temperature = $options['temperature'] ?? ( $this->temperature_settings[ $task_type ] ?? 0.7 );
		$max_tokens = $options['max_tokens'] ?? 4096;

		// Try WordPress AI Client first
		if ( $this->core_available && wpaw_wp_ai_supports_text() ) {
			$models = $this->model_preferences[ $task_type ] ?? $this->model_preferences['chat'];

			$builder = wp_ai_client_prompt()
				->with_text( $prompt )
				->using_temperature( $temperature )
				->using_max_tokens( $max_tokens )
				->using_model_preference( ...$models );

			$result = $builder->generate_text();

			if ( ! is_wp_error( $result ) ) {
				// Track usage if cost tracker available
				if ( class_exists( 'WP_Agentic_Writer_Cost_Tracker' ) ) {
					$cost = $this->estimate_cost( $result->get_usage() ?? array(), $models[0] );
					WP_Agentic_Writer_Cost_Tracker::get_instance()->record_usage_full(
						$options['post_id'] ?? 0,
						$models[0], // actual model used
						$task_type,
						$result->get_usage()['input_tokens'] ?? 0,
						$result->get_usage()['output_tokens'] ?? 0,
						$cost,
						'core', // WP AI Client provider
						$options['session_id'] ?? '',
						'success'
					);
				}

				return $result->get_text();
			}

			error_log( 'WP Agentic Writer: Core AI failed, falling back to legacy. Error: ' . $result->get_error_message() );
		}

		// Fallback to legacy implementation
		return $this->generate_text_legacy( $prompt, $options );
	}

	/**
	 * Generate text using legacy provider
	 *
	 * @param string $prompt  The prompt text.
	 * @param array  $options Additional options.
	 * @return string|WP_Error Generated text or error.
	 */
	public function generate_text_legacy( $prompt, $options = array() ) {
		$task_type = $options['task_type'] ?? 'chat';

		$provider_result = WP_Agentic_Writer_Provider_Manager::get_provider_for_task( $task_type );
		$provider = $provider_result->provider;

		$messages = array(
			array(
				'role' => 'user',
				'content' => $prompt,
			),
		);

		$params = array(
			'temperature' => $options['temperature'] ?? ( $this->temperature_settings[ $task_type ] ?? 0.7 ),
			'max_tokens' => $options['max_tokens'] ?? 4096,
		);

		$response = $provider->chat( $messages, $params, $task_type );

		if ( is_wp_error( $response ) ) {
			return $response;
		}

		// Track usage
		if ( class_exists( 'WP_Agentic_Writer_Cost_Tracker' ) ) {
			$cost = $response['cost'] ?? 0;
			WP_Agentic_Writer_Cost_Tracker::get_instance()->record_usage_full(
				$options['post_id'] ?? 0,
				$provider_result->selected_provider . '/' . ($response['model'] ?? 'unknown'),
				$task_type,
				$response['input_tokens'] ?? 0,
				$response['output_tokens'] ?? 0,
				$cost,
				$provider_result->actual_provider,
				$options['session_id'] ?? '',
				'success'
			);
		}

		return $response['content'] ?? '';
	}

	/**
	 * Generate text with streaming callback
	 *
	 * @param string   $prompt    The prompt text.
	 * @param callable $callback   Callback function for each chunk.
	 * @param array    $options    Additional options.
	 * @return bool True on success.
	 */
	public function generate_text_streaming( $prompt, $callback, $options = array() ) {
		$task_type = $options['task_type'] ?? 'chat';

		// Note: WordPress AI Client doesn't support streaming yet
		// Use legacy provider for streaming
		$provider_result = WP_Agentic_Writer_Provider_Manager::get_provider_for_task( $task_type );
		$provider = $provider_result->provider;

		if ( method_exists( $provider, 'chat_stream' ) ) {
			$params = array(
				'temperature' => $options['temperature'] ?? ( $this->temperature_settings[ $task_type ] ?? 0.7 ),
				'max_tokens' => $options['max_tokens'] ?? 8192,
			);

			$result = $provider->chat_stream(
				array(
					array(
						'role' => 'user',
						'content' => $prompt,
					),
				),
				$params,
				$task_type,
				$callback
			);

			return ! is_wp_error( $result );
		}

		// Fallback to non-streaming
		$result = $this->generate_text_legacy( $prompt, $options );
		if ( is_wp_error( $result ) ) {
			return false;
		}

		// Call back with full result
		call_user_func( $callback, $result );
		return true;
	}

	/**
	 * Generate image using WordPress AI Client or fallback
	 *
	 * @param string $prompt   The image prompt.
	 * @param array  $options  Additional options (size, style).
	 * @return array|WP_Error Image data or error.
	 */
	public function generate_image( $prompt, $options = array() ) {
		$size = $options['size'] ?? '1024x1024';
		$style = $options['style'] ?? 'natural';

		// Try WordPress AI Client first
		if ( $this->core_available && wpaw_wp_ai_supports_images() ) {
			$builder = wp_ai_client_prompt()
				->with_text( $prompt )
				->as_output_modality_image();

			$result = $builder->generate_image();

			if ( ! is_wp_error( $result ) ) {
				return array(
					'url' => $result->get_url(),
					'data_uri' => $result->get_data_uri(),
					'revised_prompt' => method_exists( $result, 'get_revised_prompt' ) ? $result->get_revised_prompt() : $prompt,
				);
			}

			error_log( 'WP Agentic Writer: Core image generation failed: ' . $result->get_error_message() );
		}

		// Fallback to legacy image manager
		if ( class_exists( 'WP_Agentic_Writer_Image_Manager' ) ) {
			$manager = WP_Agentic_Writer_Image_Manager::get_instance();
			return $manager->generate_image( $prompt, $options );
		}

		return new WP_Error(
			'image_generation_unavailable',
			__( 'Image generation is not available. Configure AI provider in WordPress Settings.', 'wp-agentic-writer' ),
			array( 'status' => 400 )
		);
	}

	/**
	 * Generate structured JSON response
	 *
	 * @param string $prompt   The prompt.
	 * @param array  $schema   JSON schema for response.
	 * @param array  $options  Additional options.
	 * @return array|WP_Error Parsed JSON or error.
	 */
	public function generate_json( $prompt, $schema, $options = array() ) {
		$task_type = $options['task_type'] ?? 'chat';

		// Try WordPress AI Client first
		if ( $this->core_available && wpaw_wp_ai_supports_text() ) {
			$models = $this->model_preferences[ $task_type ] ?? $this->model_preferences['chat'];

			$builder = wp_ai_client_prompt()
				->with_text( $prompt )
				->using_temperature( $options['temperature'] ?? 0.3 )
				->as_json_response( $schema )
				->using_model_preference( ...$models );

			$result = $builder->generate_text();

			if ( ! is_wp_error( $result ) ) {
				$json = json_decode( $result->get_text(), true );
				if ( json_last_error() === JSON_ERROR_NONE ) {
					return $json;
				}
				error_log( 'WP Agentic Writer: JSON parse error: ' . json_last_error_msg() );
			}
		}

		// Fallback to legacy with manual JSON extraction
		$text = $this->generate_text_legacy( $prompt . "\n\nRespond with ONLY valid JSON, no additional text.", $options );

		if ( is_wp_error( $text ) ) {
			return $text;
		}

		// Try to extract JSON from response
		$text = trim( $text );

		// Remove code block markers if present
		$text = preg_replace( '/^```(?:json)?\s*/i', '', $text );
		$text = preg_replace( '/\s*```$/i', '', $text );

		$result = json_decode( $text, true );

		if ( json_last_error() === JSON_ERROR_NONE ) {
			return $result;
		}

		return new WP_Error(
			'json_parse_error',
			__( 'Failed to parse JSON response', 'wp-agentic-writer' ),
			array( 'status' => 500 )
		);
	}

	/**
	 * Detect user intent from message
	 *
	 * @param string $message    User message.
	 * @param bool   $has_plan   Whether user has an existing plan.
	 * @param string $mode       Current agent mode.
	 * @return array Intent result with type and cost.
	 */
	public function detect_intent( $message, $has_plan = false, $mode = 'chat' ) {
		$options = array(
			'task_type' => 'clarity',
			'max_tokens' => 50,
			'temperature' => 0.1,
		);

		$prompt = "Based on the user's message, determine their intent. Choose ONE:

1. \"create_outline\" - User wants to create an article outline/structure
2. \"start_writing\" - User wants to write the full article
3. \"refine_content\" - User wants to improve existing content
4. \"add_section\" - User wants to add a new section
5. \"continue_chat\" - User wants to continue discussing/exploring
6. \"clarify\" - User is asking questions or needs clarification

Consider:
- The user's explicit request
- Whether they have an outline already (has_plan: " . ( $has_plan ? 'true' : 'false' ) . ")
- Current mode (current_mode: {$mode})

User's message: \"{$message}\"

Respond with ONLY the intent code (e.g., \"create_outline\"). No explanation.";

		$result = $this->generate_text( $prompt, $options );

		if ( is_wp_error( $result ) ) {
			return array(
				'intent' => 'continue_chat',
				'cost' => 0,
				'error' => $result->get_error_message(),
			);
		}

		// Validate intent
		$intent = trim( strtolower( $result ) );
		$intent = preg_replace( '/["\'\\s]/', '', $intent );

		$valid_intents = array( 'create_outline', 'start_writing', 'refine_content', 'add_section', 'continue_chat', 'clarify' );

		if ( ! in_array( $intent, $valid_intents, true ) ) {
			$intent = 'continue_chat';
		}

		return array(
			'intent' => $intent,
			'cost' => 0.001, // Estimated cost
		);
	}

	/**
	 * Generate title for content
	 *
	 * @param string $content   Content to generate title for.
	 * @param array  $options    Additional options.
	 * @return string|WP_Error Generated title or error.
	 */
	public function generate_title( $content, $options = array() ) {
		$options['task_type'] = 'title';
		$options['max_tokens'] = 60;

		$prompt = "Generate a catchy, SEO-friendly title (max 60 characters) for the following content. Only return the title, no additional text:\n\n" . substr( $content, 0, 1000 );

		return $this->generate_text( $prompt, $options );
	}

	/**
	 * Generate excerpt for content
	 *
	 * @param string $content   Content to generate excerpt for.
	 * @param array  $options    Additional options.
	 * @return string|WP_Error Generated excerpt or error.
	 */
	public function generate_excerpt( $content, $options = array() ) {
		$options['task_type'] = 'title';
		$options['max_tokens'] = 160;

		$prompt = "Generate a compelling excerpt (max 160 characters) for the following content. Only return the excerpt, no additional text:\n\n" . substr( $content, 0, 2000 );

		return $this->generate_text( $prompt, $options );
	}

	/**
	 * Summarize context for token optimization
	 *
	 * @param array  $messages   Chat messages to summarize.
	 * @param int    $max_tokens Maximum tokens for summary.
	 * @return string|WP_Error Summary or error.
	 */
	public function summarize_context( $messages, $max_tokens = 1000 ) {
		$options = array(
			'task_type' => 'clarity',
			'max_tokens' => $max_tokens,
			'temperature' => 0.3,
		);

		// Build context string
		$context = '';
		foreach ( $messages as $msg ) {
			$role = $msg['role'] ?? 'user';
			$content = $msg['content'] ?? '';
			if ( is_array( $content ) ) {
				$content = $content[0]['text'] ?? '';
			}
			$context .= "[{$role}]: " . substr( $content, 0, 500 ) . "\n\n";
		}

		$prompt = "Summarize the following conversation, preserving key information and context. Focus on:\n- Topic and goal\n- Key decisions or plans made\n- Important details or constraints\n\nConversation:\n{$context}\n\nProvide a concise summary:";

		return $this->generate_text( $prompt, $options );
	}

	/**
	 * Estimate cost based on usage
	 *
	 * @param array  $usage    Token usage data.
	 * @param string $model    Model name.
	 * @return float Estimated cost in USD.
	 */
	private function estimate_cost( $usage, $model ) {
		// Simple cost estimation
		$input_tokens = $usage['input_tokens'] ?? 0;
		$output_tokens = $usage['output_tokens'] ?? 0;

		// Rough estimates per 1M tokens (in USD)
		$rates = array(
			'claude-sonnet' => 3.00,
			'claude-haiku' => 0.25,
			'gpt-4o' => 5.00,
			'gpt-4o-mini' => 0.15,
			'gemini' => 0.50,
		);

		$rate = 1.00; // Default rate
		foreach ( $rates as $key => $value ) {
			if ( stripos( $model, $key ) !== false ) {
				$rate = $value;
				break;
			}
		}

		return ( ( $input_tokens + $output_tokens ) / 1000000 ) * $rate;
	}

	/**
	 * Get capability status
	 *
	 * @return array Capabilities status.
	 */
	public function get_capabilities() {
		return array(
			'core_available' => $this->core_available,
			'text_support' => wpaw_wp_ai_supports_text(),
			'image_support' => wpaw_wp_ai_supports_images(),
			'speech_support' => wpaw_wp_ai_supports_speech(),
			'current_mode' => $this->get_ai_mode(),
			'streaming_available' => false, // Core doesn't support streaming yet
		);
	}
}