<?php
/**
 * Keyword Suggester Helper
 *
 * @package WP_Agentic_Writer
 * @since 0.1.0
 */

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

/**
 * Class WP_Agentic_Writer_Keyword_Suggester
 *
 * Helper class for AI-powered keyword suggestions.
 *
 * @since 0.1.0
 */
class WP_Agentic_Writer_Keyword_Suggester {

	/**
	 * Suggest keywords based on outline and title.
	 *
	 * @since 0.1.0
	 * @param string $title Article title.
	 * @param array  $sections Outline sections.
	 * @param string $language Language code.
	 * @param int    $post_id Post ID for cost tracking.
	 * @return array|WP_Error Array with focus_keyword, secondary_keywords, reasoning, and cost.
	 */
	public static function suggest_keywords( $title, $sections, $language = 'english', $post_id = 0 ) {
		$provider_result = WP_Agentic_Writer_Provider_Manager::get_provider_for_task( 'clarity' );
		$provider = $provider_result->provider;

		// Build outline text from sections
		$outline_text = '';
		if ( is_array( $sections ) ) {
			foreach ( $sections as $section ) {
				// Support both 'heading' (new format) and 'title' (legacy)
				$section_title = $section['heading'] ?? $section['title'] ?? '';
				if ( ! empty( $section_title ) ) {
					$outline_text .= "- {$section_title}\n";
				}
			}
		}

		if ( empty( $outline_text ) ) {
			return new WP_Error( 'no_outline', 'No outline available for keyword analysis' );
		}

		// Build language-specific instruction
		$language_instruction = self::build_language_instruction( $language );

		// Build prompt for keyword suggestion
		$prompt = "Analyze this article outline and suggest optimal SEO keywords.\n\n";
		$prompt .= "ARTICLE TITLE:\n{$title}\n\n";
		$prompt .= "OUTLINE SECTIONS:\n{$outline_text}\n\n";
		$prompt .= "TASK:\n";
		$prompt .= "1. Suggest ONE focus keyword (2-4 words) that best represents the main topic\n";
		$prompt .= "2. Suggest 3-5 secondary keywords (related terms, variations, or supporting topics)\n";
		$prompt .= "3. Provide brief reasoning (1-2 sentences) for your suggestions\n\n";
		$prompt .= "REQUIREMENTS:\n";
		$prompt .= "- Focus keyword should be specific and searchable\n";
		$prompt .= "- Secondary keywords should complement the focus keyword\n";
		$prompt .= "- Consider search intent and user queries\n";
		$prompt .= "- Keywords should match the outline content\n\n";
		$prompt .= "{$language_instruction}\n\n";
		$prompt .= "Respond ONLY with valid JSON in this exact format:\n";
		$prompt .= "{\n";
		$prompt .= "  \"focus_keyword\": \"your suggested focus keyword\",\n";
		$prompt .= "  \"secondary_keywords\": [\"keyword1\", \"keyword2\", \"keyword3\"],\n";
		$prompt .= "  \"reasoning\": \"Brief explanation of why these keywords are optimal\"\n";
		$prompt .= "}\n\n";
		$prompt .= "Do not include any text outside the JSON structure.";

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

		// Use planning model for keyword suggestion (fast and cheap)
		$response = $provider->chat( $messages, array( 'temperature' => 0.3 ), 'planning' );

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

		$content = trim( $response['content'] ?? '' );

		// Try to extract JSON from response
		$json_start = strpos( $content, '{' );
		$json_end = strrpos( $content, '}' );

		if ( false === $json_start || false === $json_end ) {
			return new WP_Error( 'invalid_response', 'AI response is not valid JSON' );
		}

		$json_string = substr( $content, $json_start, $json_end - $json_start + 1 );
		$suggestions = json_decode( $json_string, true );

		if ( null === $suggestions || ! is_array( $suggestions ) ) {
			return new WP_Error( 'parse_error', 'Failed to parse keyword suggestions' );
		}

		// Validate required fields
		if ( empty( $suggestions['focus_keyword'] ) || empty( $suggestions['secondary_keywords'] ) ) {
			return new WP_Error( 'incomplete_suggestions', 'Keyword suggestions are incomplete' );
		}

		// Ensure secondary_keywords is an array
		if ( ! is_array( $suggestions['secondary_keywords'] ) ) {
			$suggestions['secondary_keywords'] = array();
		}

		// Track cost with full nine-argument contract including provider attribution.
		$cost = $response['cost'] ?? 0;
		if ( $cost > 0 && $post_id > 0 ) {
			$actual_provider = 'unknown';
			$provider_name = '';

			// Extract provider info from provider_result.
			if ( is_object( $provider_result ) && isset( $provider_result->actual_provider ) ) {
				$actual_provider = $provider_result->actual_provider;
				$provider_name = is_object( $provider ) ? get_class( $provider ) : 'unknown';
			}

			// Get session ID for this post if available.
			$session_id = '';
			if ( $post_id > 0 ) {
				$manager = WP_Agentic_Writer_Conversation_Manager::get_instance();
				$session = $manager->get_session_by_post_id( $post_id );
				if ( $session && isset( $session['session_id'] ) ) {
					$session_id = $session['session_id'];
				}
			}

			do_action(
				'wp_aw_after_api_request',
				$post_id,
				$response['model'] ?? 'unknown',
				'suggest_keyword',
				$response['input_tokens'] ?? 0,
				$response['output_tokens'] ?? 0,
				$cost,
				$actual_provider,
				$session_id,
				'success'
			);
		}

		return array(
			'focus_keyword'       => $suggestions['focus_keyword'],
			'secondary_keywords'  => $suggestions['secondary_keywords'],
			'reasoning'           => $suggestions['reasoning'] ?? '',
			'cost'                => $cost,
			'provider_result'     => $provider_result,
			'model'               => $response['model'] ?? '',
		);
	}

	/**
	 * Build language instruction for keyword suggestion.
	 *
	 * @since 0.1.0
	 * @param string $language Language code.
	 * @return string Language instruction.
	 */
	private static function build_language_instruction( $language ) {
		$language = trim( (string) $language );

		// If auto or empty, match article language
		if ( empty( $language ) || 'auto' === strtolower( $language ) ) {
			return 'Suggest keywords in the same language as the article topic and outline.';
		}

		// Pass any language name directly - AI understands all languages
		return "IMPORTANT: Suggest keywords in {$language}. Consider {$language} search queries and terms used by {$language} speakers.";
	}
}
