<?php

namespace AIPT\Api\BulkGenerator\Title\Core;

use AIPT\Utils\PromptFormatter;

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

/**
 * Title generator prompt factory.
 *
 * Extracts prompt construction from TitleGeneratorService for consistency
 * with DescriptionPromptFactory / StandardPromptFactory / SeoMetaPromptFactory patterns.
 *
 * @package AIPT\Api\BulkGenerator\Title\Core
 */
class TitlePromptFactory {

    /**
     * Build title generation prompts using XML hybrid structure.
     *
     * Updated in v2.6.2 based on prompt engineering research:
     * - Uses Markdown headers for structure (# Identity, # Rules)
     * - XML tags for data isolation (<product_data>, <task>, <output_format>)
     * - Positive instructions with clear quality gates
     * - Feature→Benefit transformation guidance
     *
     * @param array  $options       Generation options.
     * @param array  $product_data  Product data.
     * @param string $language      Target language.
     * @param string $writing_style Writing style.
     * @return array System and user prompts.
     */
	public function getTitlePrompts( $options, $product_data, $language, $writing_style ) {

		$default_options = array(
			'tone'              => 'SEO-Focused',
			'keywords'          => '',
			'mode'              => 'rewrite',
			'titleSources'      => array( 'product_description' ),
			'additional_prompt' => '',
		);

        /**
         * Filter title generator options.
         *
         * Premium features can extend these options via this filter hook.
         * Free version uses default values defined above.
         *
         * @since 2.5.0
         * @param array $default_options Default free options.
         * @param array $options         Options passed from request.
         * @param array $product_data    Current product data.
         */
        $filtered_options = apply_filters( 'aipt_title_generator_options', $default_options, $options, $product_data );

        $tone     = $filtered_options['tone'];
        $keywords = $filtered_options['keywords'];
        $mode     = $filtered_options['mode'];

        $options_for_sources          = $options;
        $options_for_sources['tone']  = $tone;
        $options_for_sources['mode']  = $mode;
        $options_for_sources['titleSources'] = $filtered_options['titleSources'];

		$source_data = $this->buildSourceData($options_for_sources, $product_data);
		$max_length = (string) max( 1, absint( $options['maxLength'] ?? 60 ) );

		$system_prompt = $this->buildTitleSystemPrompt( $language, $tone, $max_length, sanitize_text_field( (string) $writing_style ) );

        $user_prompt = $this->buildTitleUserPrompt($mode, $language, $source_data, $keywords, $filtered_options, $product_data);

        return [
            'system_prompt' => $system_prompt,
            'user_prompt' => $user_prompt
        ];
    }

	/**
	 * Build the optimized title system prompt using Markdown + XML hybrid structure.
	 *
	 * @param string $language      Target language.
	 * @param string $tone          Writing tone.
	 * @param string $max_length    Maximum character length.
	 * @param string $writing_style Optional global writing style preference (e.g. Storytelling, Minimalist).
	 * @return string System prompt.
	 */
	private function buildTitleSystemPrompt( string $language, string $tone, string $max_length, string $writing_style = '' ): string {
		$tone_guidance        = $this->getToneGuidance( $tone );
		$writing_style_clause = '' !== $writing_style ? "\n- Writing Style Preference: {$writing_style}" : '';

		return "# Identity
You are a product title specialist who creates click-worthy, SEO-optimized titles that drive sales.

# Language & Style
- Language: {$language}
- Tone: {$tone}
- {$tone_guidance}{$writing_style_clause}

# Core Rules
1. Lead with the PRIMARY benefit or unique selling point
2. Maximum {$max_length} characters (hard limit)
3. Include the most important keyword naturally
4. Each variant must use DIFFERENT wording, structure, and approach
5. Focus on what makes this product SPECIAL (not generic adjectives)

# Title Formulas (use different ones for variants)
- [Benefit] + [Product Type] + [Key Feature]
- [Audience] + [Product Type] + [Result]
- [Feature] + [Product Type] for [Use Case]
- [Adjective] + [Product Type] - [Unique Benefit]

# Quality Gate
Before finalizing, verify each title:
- Under {$max_length} characters? ✓
- Contains a specific benefit (not just \"high-quality\")? ✓
- Would a customer click on this in search results? ✓
- Different from other variants in structure AND wording? ✓

<output_format>
Return plain text only.
No quotes, numbering, or formatting.
Just the title itself.
</output_format>";
    }

    /**
     * Get tone-specific guidance for title generation.
     *
     * @param string $tone The selected tone.
     * @return string Tone guidance.
     */
    private function getToneGuidance(string $tone): string {
        $guidance = array(
            'SEO-Focused'   => 'Prioritize searchable keywords. Front-load important terms. Use natural language that matches search intent.',
            'Professional'  => 'Confident and authoritative. Use industry terms. Avoid casual language or exclamation marks.',
            'Casual'        => 'Friendly and approachable. Use conversational language. Can be slightly playful.',
            'Luxury'        => 'Understated elegance. Focus on craftsmanship and exclusivity. Never oversell.',
            'Technical'     => 'Lead with specifications. Use precise terminology. Appeal to informed buyers.',
            'Persuasive'    => 'Action-oriented words. Emphasize outcomes and benefits. Create subtle urgency.',
        );

        return $guidance[$tone] ?? $guidance['SEO-Focused'];
    }

    /**
     * Build the title user prompt with XML data isolation.
     *
     * @param string $mode             Generation mode (improve/rewrite).
     * @param string $language         Target language.
     * @param string $source_data      Product source data.
     * @param string $keywords         Target keywords.
     * @param array  $filtered_options Filtered options.
     * @param array  $product_data     Product data.
     * @return string User prompt.
     */
    private function buildTitleUserPrompt(string $mode, string $language, string $source_data, string $keywords, array $filtered_options, array $product_data): string {
        $parts = array();

        $parts[] = "<product_data>\n{$source_data}</product_data>";

		$keywords = trim( sanitize_textarea_field( (string) $keywords ) );
		if ( ! empty( $keywords ) ) {
			$parts[] = "<target_keywords>
{$keywords}

Incorporate these keywords naturally—the title should read smoothly, not be keyword-stuffed.
</target_keywords>";
        }

        $additional_prompt = $filtered_options['additional_prompt'];
        if (!empty(trim($additional_prompt))) {
            $clean_additional_prompt     = PromptFormatter::cleanContent($additional_prompt);
            $formatted_additional_prompt = PromptFormatter::formatProductVariables($clean_additional_prompt, $product_data);
            $parts[] = "<additional_instructions>\n{$formatted_additional_prompt}\n</additional_instructions>";
        }

        $task_action = ($mode === 'improve') 
            ? 'Improve the existing product title while preserving its core message.'
            : 'Create a new, compelling product title from scratch.';

        $parts[] = "<task>
{$task_action}

Write in {$language} language.

Requirements:
1. Use SPECIFIC details from the product data
2. Transform a key feature into a customer benefit
3. Ensure the title would stand out in search results
4. Sound natural, not templated or generic
</task>";

        return implode("\n\n", $parts);
    }

    /**
     * Build source data for title generation based on selected sources.
     *
     * @param array $options      Generation options.
     * @param array $product_data Product data.
     * @return string Source data formatted for prompt.
     */
    private function buildSourceData($options, $product_data) {
        $source_data = "";

        $selected_sources = $options['titleSources'] ?? array( 'product_description' );

		if ( in_array( 'existing_title', $selected_sources, true ) ) {
			$source_data .= "Current title: {title}\n";
		}

		if ( in_array( 'product_tags', $selected_sources, true ) ) {
			$source_data .= "Product tags: {TAGS}\n";
		}

		if ( in_array( 'product_description', $selected_sources, true ) ) {
			$source_data .= "Short description: {short_description}\n";
			$source_data .= "Long description: {long_description}\n";
		}

		if ( in_array( 'product_categories', $selected_sources, true ) ) {
			$source_data .= "Categories: {CATEGORIES}\n";
		}

		if ( in_array( 'product_attributes', $selected_sources, true ) ) {
			$source_data .= "Product attributes: {ATTRIBUTES}\n";
		}

        if (empty($source_data)) {
            $source_data = "Short description: {short_description}\nLong description: {long_description}\n";
        }

        return $source_data;
    }
}
