<?php
/**
 * Query Rewriter Service.
 *
 * Uses an LLM to rewrite user queries into optimized search terms for better RAG retrieval.
 *
 * @package Inqyra
 */

// If this file is called directly, abort.
if (!defined('WPINC')) {
    die;
}

/**
 * Query Rewriter class.
 */
class Inqyra_Query_Rewriter {

    /**
     * System prompt for query rewriting.
     *
     * Written in English for best LLM comprehension across all providers.
     * The "Preserve the original language" rule ensures the rewrite matches
     * the language of the user's query.
     */
    const SYSTEM_PROMPT = "You are a query rewriter for a search system. Your task is to optimize the user's question for search.\n\n"
        . "Rules:\n"
        . "- Keep ALL substantive search terms from the original question. NEVER remove them.\n"
        . "- Do NOT add new words that are not in the original question, unless clarifying a reference from the conversation history.\n"
        . "- Remove only stop words (the, a, an, which, have, you, can, do, etc.) and formulate as a search query.\n"
        . "- If the question is already clear enough, return the key words.\n"
        . "- Preserve the original language of the question.\n"
        . "- Reply ONLY with the rewritten query, no explanation.\n\n"
        . "Examples:\n"
        . "- \"do you have any job openings\" -> \"job openings\"\n"
        . "- \"what are the opening hours of your office\" -> \"opening hours office\"\n"
        . "- \"can you help me with my tax return\" -> \"tax return help\"";

    /**
     * The AI provider instance.
     *
     * @var Inqyra_AI_Provider_Interface|null
     */
    private $provider;

    /**
     * The model to use for rewriting.
     *
     * @var string
     */
    private $model;

    /**
     * Whether rewriting is enabled.
     *
     * @var bool
     */
    private $enabled;

    /**
     * Constructor.
     *
     * @param object $agent The agent configuration.
     */
    public function __construct($agent) {
        $this->enabled = !empty($agent->query_rewrite_enabled);

        if ($this->enabled) {
            $provider_name = $agent->query_rewrite_provider ?? 'claude';
            $this->model = $agent->query_rewrite_model ?? 'claude-3-haiku-20240307';

            try {
                $this->provider = Inqyra_AI_Provider_Factory::create($provider_name);
            } catch (Exception $e) {
                $this->enabled = false;
            }
        }
    }

    /**
     * Check if query rewriting is enabled and configured.
     *
     * @return bool Whether rewriting is available.
     */
    public function is_enabled(): bool {
        return $this->enabled && $this->provider && $this->provider->is_configured();
    }

    /**
     * Rewrite a query by reducing it to key search terms.
     *
     * Uses conversation history to resolve references in follow-up questions.
     *
     * @param string $query                The original user query.
     * @param string $language             The language (nl/en).
     * @param array  $conversation_history Conversation history with 'role' and 'content'.
     * @return array Result with 'original', 'rewritten', 'tokens', 'cost'.
     */
    public function rewrite(string $query, string $language = 'nl', array $conversation_history = []): array {
        $result = [
            'original' => $query,
            'rewritten' => $query,
            'tokens' => ['input' => 0, 'output' => 0],
            'cost' => 0.0,
            'used_rewriter' => false,
        ];

        if (!$this->is_enabled()) {
            return $result;
        }

        // Skip very short queries (likely greetings)
        if (mb_strlen(trim($query)) < 5) {
            return $result;
        }

        // Skip if query is already long enough (likely detailed)
        if (mb_strlen(trim($query)) > 200) {
            return $result;
        }

        // Build user content with optional conversation context
        $user_content = $query;
        if (!empty($conversation_history)) {
            $last_messages = array_slice($conversation_history, -4);
            $context_lines = array_map(
                function ($m) {
                    return $m['role'] . ': ' . $m['content'];
                },
                $last_messages
            );
            $user_content = "Recent conversation history:\n"
                . implode("\n", $context_lines)
                . "\n\nCurrent question: " . $query;
        }

        try {
            $response = $this->provider->chat(
                [
                    ['role' => 'system', 'content' => self::SYSTEM_PROMPT],
                    ['role' => 'user', 'content' => $user_content],
                ],
                [
                    'model' => $this->model,
                    'max_tokens' => 150,
                    'temperature' => 0.3,
                ]
            );

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

            // Validate the response - it should not be empty or too different
            if (!empty($rewritten) && mb_strlen($rewritten) < 500) {
                $result['rewritten'] = $rewritten;
                $result['used_rewriter'] = true;
            }

            $result['tokens'] = $response['tokens'] ?? ['input' => 0, 'output' => 0];
            $result['cost'] = $response['cost'] ?? 0.0;

        } catch (Exception $e) {
            // Log error but return original query
            if (defined('WP_DEBUG') && WP_DEBUG) {
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Gated behind WP_DEBUG.
                error_log('Inqyra Query Rewriter error: ' . $e->getMessage());
            }
        }

        return $result;
    }
}
