<?php
/**
 * This file is part of the Wisewand WordPress plugin.
 *
 * Wisewand API Payload Builder - Simplified for Brief Config System
 *
 * @package Wisewand
 * @since 1.0.0
 * @updated 2.8.0 - Migrated to API brief config system
 * @license GPL-2.0-or-later
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
namespace Wisewand\Utils;

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Wisewand\Logging\Logger;

/**
 * Wisewand API Payload Builder (using native brief config system)
 *
 * Builds API request payloads with apply_project_brief_config=true.
 * Content generation settings (TOC, FAQ, images, audio, etc.) are now
 * managed in Wisewand project brief, not plugin settings.
 *
 * SIMPLIFIED IN v2.8.0:
 * - Removed 26 plugin-managed default settings
 * - Enabled API brief config system
 * - Kept calendar AI instructions fields
 * - Maintained project_id validation
 *
 * @package Wisewand
 * @since 1.0.0
 * @updated 2.8.0
 */
class Wisewand_Payload_Builder {

	/**
	 * Options manager
	 *
	 * @since 1.0.0
	 * @var Options
	 */
	private $options;

	/**
	 * Logger instance
	 *
	 * @since 1.0.0
	 * @var Logger
	 */
	private $logger;

	/**
	 * Constructor
	 *
	 * @since 1.0.0
	 * @param Options $options Options manager instance.
	 * @param Logger  $logger  Logger instance.
	 */
	public function __construct( Options $options, Logger $logger ) {
		$this->options = $options;
		$this->logger  = $logger;
	}

	/**
	 * Build payload for content generation with API brief config system
	 *
	 * Creates minimal payload with apply_project_brief_config=true.
	 * Content features (TOC, FAQ, images, audio) managed in Wisewand project brief.
	 *
	 * @since 1.0.0
	 * @updated 2.8.0 - Simplified for brief config system
	 *
	 * @param array $keyword_data Keyword information.
	 * @param array $user_overrides User-provided overrides from Calendar modal.
	 * @return array|WP_Error Payload array or error.
	 */
	public function build_payload( $keyword_data, $user_overrides = array() ) {
		$defaults    = $this->get_default_payload_settings( $keyword_data );
		$auto_config = $this->generate_auto_config( $keyword_data );

		// Merge: defaults → auto_config → user_overrides
		$payload = array_merge( $defaults, $auto_config, $user_overrides );

		// Validate critical fields
		$validation = $this->validate_payload( $payload );
		if ( is_wp_error( $validation ) ) {
			$this->logger->error(
				'Payload validation failed',
				array(
					'error'   => $validation->get_error_message(),
					'keyword' => $keyword_data['keyword'] ?? 'unknown',
				)
			);
			return $validation;
		}

		$this->logger->debug(
			'Built Wisewand payload with brief config',
			array(
				'keyword'    => $keyword_data['keyword'] ?? 'unknown',
				'type'       => $payload['type'] ?? 'unknown',
				'lang'       => $payload['lang'] ?? 'unknown',
				'project_id' => $payload['project_id'] ?? 'none',
				'brief_config_enabled' => true,
			)
		);

		return $payload;
	}

	/**
	 * Get default payload settings (simplified for brief config system)
	 *
	 * SIMPLIFIED IN v2.8.0:
	 * - Removed 26 content generation default settings
	 * - Added apply_project_brief_config: true
	 * - Kept only essential fields: lang, country, project_id, type, length
	 *
	 * @since 1.0.0
	 * @updated 2.8.0
	 *
	 * @param array $keyword_data Keyword information.
	 * @return array Default payload settings.
	 */
	private function get_default_payload_settings( $keyword_data = array() ) {
		// Get language from keyword first, fallback to settings
		$keyword_lang     = $keyword_data['language_code'] ?? null;
		$keyword_location = $keyword_data['location_code'] ?? null;

		// Determine language
		if ( $keyword_lang ) {
			$lang = $keyword_lang;
		} else {
			$lang = $this->options->get( 'wisewand_fallback_language', 'en' );
		}

		// Determine country
		if ( $keyword_location ) {
			// Map location_code to country
			if ( ! class_exists( 'Wisewand\\Utils\\Location_Mapper' ) ) {
				require_once WISEWAND_PLUGIN_DIR . 'includes/Utils/Location_Mapper.php';
			}
			$country = \Wisewand\Utils\Location_Mapper::location_to_country( $keyword_location );
		} else {
			$country = $this->options->get( 'wisewand_fallback_country', 'us' );
		}

		// SIMPLIFIED PAYLOAD (v2.8.0):
		// Only essential fields + apply_project_brief_config
		return array(
			// CRITICAL: Enable API brief config system
			'apply_project_brief_config' => true,

			// Essential fields
			'project_id' => $this->options->get( 'wisewand_default_project_id', '' ),
			'lang'       => $lang,
			'country'    => $country,
			'type'       => 'blog', // Default content type
			'length'     => 'auto', // Default length

			// AI Instructions (empty by default, set in Calendar modal)
			'search_intention_answer' => '',
			'additional_information'  => '',
			'avoid_information'       => '',
		);
	}

	/**
	 * Generate auto-config for required fields only
	 *
	 * Sets fields that MUST be auto-generated:
	 * - subject, title, target_keyword (from keyword)
	 * - AI instructions (if auto-generation enabled)
	 *
	 * Does NOT override feature settings (those come from API brief).
	 *
	 * @since 1.0.0
	 * @param array $keyword_data Keyword information.
	 * @return array Auto-generated configuration.
	 */
	private function generate_auto_config( $keyword_data ) {
		$keyword  = $keyword_data['keyword'] ?? '';
		$intent   = $keyword_data['search_intent'] ?? 'informational';
		$position = $keyword_data['current_position'] ?? null;

		// Auto-generate required content fields
		$config = array(
			'subject'        => $keyword,
			'title'          => $keyword,
			'target_keyword' => $keyword,
		);

		// Generate AI instructions only if setting enabled
		$auto_generate = $this->options->get( 'wisewand_default_auto_generate_instructions', false );

		if ( $auto_generate ) {
			// Auto-generate using templates
			if ( $position && $position <= 20 ) {
				// Improvement mode
				$config['search_intention_answer'] = $this->generate_intention_for_improvement( $keyword, $position );
				$config['additional_information']  = $this->generate_improvement_instructions( $keyword, $position );
			} else {
				// New content mode
				$config['search_intention_answer'] = $this->generate_intention_for_new( $keyword, $intent );
				$config['additional_information']  = $this->generate_new_content_instructions( $keyword, $intent );
			}

			$config['avoid_information'] = $this->generate_avoid_information( $keyword );
		}

		return $config;
	}

	/**
	 * Generate intention for ranking improvement
	 *
	 * @since 1.0.0
	 * @param string $keyword  Keyword.
	 * @param int    $position Current ranking position.
	 * @return string Intention text.
	 */
	private function generate_intention_for_improvement( $keyword, $position ) {
		return sprintf(
			'This article aims to improve our current ranking (position #%d) for "%s" by providing more comprehensive, up-to-date information and better user experience.',
			$position,
			$keyword
		);
	}

	/**
	 * Generate intention for new content
	 *
	 * @since 1.0.0
	 * @param string $keyword Keyword.
	 * @param string $intent  Search intent.
	 * @return string Intention text.
	 */
	private function generate_intention_for_new( $keyword, $intent ) {
		$intent_descriptions = array(
			'informational' => 'provide comprehensive, factual information to educate readers about',
			'commercial'    => 'help readers make informed purchase decisions regarding',
			'transactional' => 'guide users through the process of',
			'navigational'  => 'help users find resources and information about',
		);

		$description = $intent_descriptions[ $intent ] ?? $intent_descriptions['informational'];

		return sprintf( 'This article will %s "%s" with practical examples and actionable insights.', $description, $keyword );
	}

	/**
	 * Generate improvement instructions
	 *
	 * @since 1.0.0
	 * @param string $keyword  Keyword.
	 * @param int    $position Current position.
	 * @return string Instructions text.
	 */
	private function generate_improvement_instructions( $keyword, $position ) {
		return sprintf(
			'Focus on improving our existing content for "%s" (currently ranked #%d). ' .
			'Add fresh insights, update statistics to %s, include practical examples, ' .
			'and ensure the content is more comprehensive than competing pages. ' .
			'Identify gaps in our current coverage and fill them.',
			$keyword,
			$position,
			gmdate( 'Y' )
		);
	}

	/**
	 * Generate new content instructions
	 *
	 * @since 1.0.0
	 * @param string $keyword Keyword.
	 * @param string $intent  Search intent.
	 * @return string Instructions text.
	 */
	private function generate_new_content_instructions( $keyword, $intent ) {
		$instructions = array(
			'informational' => 'Provide in-depth, well-researched information with clear structure, practical examples, and actionable takeaways.',
			'commercial'    => 'Include detailed comparisons, pros/cons, pricing information, and clear recommendations to help buyers make decisions.',
			'transactional' => 'Create step-by-step guides with clear instructions, tips for success, and common pitfalls to avoid.',
			'navigational'  => 'Provide clear navigation to resources, comprehensive overview, and links to relevant sections.',
		);

		$base_instruction = $instructions[ $intent ] ?? $instructions['informational'];

		return sprintf(
			'Create comprehensive content about "%s". %s Focus on %s best practices and current trends.',
			$keyword,
			$base_instruction,
			gmdate( 'Y' )
		);
	}

	/**
	 * Generate avoid information
	 *
	 * @since 1.0.0
	 * @param string $keyword Keyword.
	 * @return string Avoid information text.
	 */
	private function generate_avoid_information( $keyword ) {
		return sprintf(
			'Avoid outdated information, unverified claims, and overly promotional content. ' .
			'Do not include generic filler content or information not directly relevant to "%s". ' .
			'Avoid speculation without factual basis.',
			$keyword
		);
	}

	/**
	 * Merge user edits into base payload
	 *
	 * @since 1.0.0
	 * @param array $base_payload Base payload.
	 * @param array $user_edits   User edits from Calendar modal.
	 * @return array Merged payload.
	 */
	public function merge_user_edits( $base_payload, $user_edits ) {
		foreach ( $user_edits as $key => $value ) {
			if ( null !== $value && '' !== $value ) {
				$base_payload[ $key ] = $value;
			}
		}

		return $base_payload;
	}

	/**
	 * Validate payload has required fields
	 *
	 * @since 1.0.0
	 * @param array $payload Payload to validate.
	 * @return true|WP_Error True if valid, WP_Error otherwise.
	 */
	private function validate_payload( $payload ) {
		// Critical validations
		if ( empty( $payload['project_id'] ) ) {
			return new \WP_Error(
				'missing_project_id',
				__( 'Project ID not configured. Please select a project in Settings.', 'wisewand-ai-content-writer-seo-content-generator' )
			);
		}

		$required_fields = array( 'subject', 'lang', 'type' );

		foreach ( $required_fields as $field ) {
			if ( empty( $payload[ $field ] ) ) {
				return new \WP_Error(
					'missing_field',
					sprintf(
						/* translators: %s: Field name */
						__( 'Required field "%s" is missing', 'wisewand-ai-content-writer-seo-content-generator' ),
						$field
					)
				);
			}
		}

		return true;
	}

	/**
	 * Generate AI-powered instructions using OpenAI GPT-4o-mini
	 *
	 * Uses structured output for high-quality, specific content briefs.
	 *
	 * @since 1.0.0
	 * @param array $keyword_data Keyword information with context.
	 * @return array|WP_Error Generated instructions or error.
	 */
	public function generate_ai_instructions( $keyword_data ) {
		// Check if OpenAI is available
		if ( ! class_exists( 'Wisewand\\Utils\\OpenAI_Client' ) ) {
			require_once WISEWAND_PLUGIN_DIR . 'includes/Utils/OpenAI_Client.php';
		}

		if ( ! \Wisewand\Utils\OpenAI_Client::is_configured() ) {
			return new \WP_Error(
				'no_api_key',
				__( 'OpenAI API key not configured', 'wisewand-ai-content-writer-seo-content-generator' )
			);
		}

		$api_key = \Wisewand\Utils\OpenAI_Client::get_stored_api_key();
		$openai  = new \Wisewand\Utils\OpenAI_Client( $api_key, $this->logger );

		$keyword    = $keyword_data['keyword'] ?? '';
		$intent     = $keyword_data['search_intent'] ?? 'informational';
		$volume     = $keyword_data['search_volume'] ?? 0;
		$difficulty = $keyword_data['difficulty'] ?? 50;
		$position   = $keyword_data['current_position'] ?? null;
		$language   = $keyword_data['language_code'] ?? 'en';

		// Build comprehensive prompt
		$messages = array(
			array(
				'role'    => 'system',
				'content' => $this->get_ai_instructions_system_prompt(),
			),
			array(
				'role'    => 'user',
				'content' => wp_json_encode(
					array(
						'task'         => 'generate_content_brief',
						'keyword_data' => array(
							'keyword'          => $keyword,
							'search_intent'    => $intent,
							'search_volume'    => $volume,
							'difficulty'       => $difficulty,
							'current_position' => $position,
							'language'         => $language,
						),
						'context'      => array(
							'is_ranking'    => ! empty( $position ),
							'target_action' => $position ? 'improve_ranking' : 'create_new_content',
							'year'          => gmdate( 'Y' ),
						),
					),
					JSON_PRETTY_PRINT
				),
			),
		);

		// Use structured output for guaranteed valid response
		$response = $openai->chat_completion(
			$messages,
			array(
				'temperature'     => 0.4,
				'max_tokens'      => 800,
				'response_format' => array(
					'type'        => 'json_schema',
					'json_schema' => array(
						'name'   => 'content_brief_generation',
						'strict' => true,
						'schema' => array(
							'type'                 => 'object',
							'properties'           => array(
								'search_intention'        => array(
									'type'        => 'string',
									'description' => 'Clear, specific purpose and target audience (1-2 sentences)',
								),
								'additional_instructions' => array(
									'type'        => 'string',
									'description' => 'Detailed, actionable content requirements (2-4 sentences)',
								),
								'avoid_information'       => array(
									'type'        => 'string',
									'description' => 'Specific pitfalls to avoid for this keyword (1-2 sentences)',
								),
								'confidence'              => array(
									'type'        => 'number',
									'description' => 'Confidence in recommendations 0.0-1.0',
								),
							),
							'required'             => array( 'search_intention', 'additional_instructions', 'avoid_information', 'confidence' ),
							'additionalProperties' => false,
						),
					),
				),
			)
		);

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

		return array(
			'search_intention_answer' => $response['search_intention'] ?? '',
			'additional_information'  => $response['additional_instructions'] ?? '',
			'avoid_information'       => $response['avoid_information'] ?? '',
			'confidence'              => $response['confidence'] ?? 0.8,
		);
	}

	/**
	 * Get system prompt for AI instructions generation
	 *
	 * @since 1.0.0
	 * @return string System prompt.
	 */
	private function get_ai_instructions_system_prompt() {
		return 'You are an expert SEO content strategist and editor.

MISSION: Generate a SPECIFIC, actionable content brief based on keyword analysis.

CRITICAL REQUIREMENTS:
- Analyze the keyword to infer target audience and intent
- Be SPECIFIC to this keyword - NOT generic advice
- Work for ANY website niche (don\'t assume specific industry)
- Base recommendations on search intent, volume, and difficulty data

ANALYZE AND DETERMINE:
1. WHO is searching (infer from keyword and intent)
2. WHY they are searching (what problem are they solving?)
3. WHAT content will satisfy them (topics, depth, format)
4. HOW to approach it (structure, tone, key points)

OUTPUT STRUCTURE:
{
  "search_intention": "1-2 sentences explaining WHO searches and WHY",
  "additional_instructions": "2-4 sentences with specific, actionable guidance",
  "avoid_information": "1-2 sentences about what NOT to include",
  "confidence": 0.0-1.0
}

Be adaptable, specific, and helpful for ANY website niche.';
	}
}
