<?php
if (!defined('ABSPATH')) exit;

/**
 * Prompt testing — ask the configured AI model real user-style prompts
 * ("Recommend a detailing company in Poznań", "Best hotel in Zakopane") and detect
 * whether the brand (and competitors) appear in the answer.
 *
 * Manual single runs are free (BYOK). Saved history + scheduled monitoring are Pro/Agency.
 *
 * Honesty note: this queries YOUR configured model (OpenAI/Claude/Gemini) — it reflects
 * what that model says today, used as an in-WordPress proxy for AI visibility.
 */
class AIVT_Prompt_Test {

    const OPT_PROMPTS = 'aivt_monitored_prompts';

    public static function init() {
        add_action('aivt_prompt_monitor', [__CLASS__, 'run_scheduled']);
        self::maybe_schedule();
    }

    public static function maybe_schedule() {
        $s = aivt_get_settings();
        $sched = $s['prompt_schedule'] ?? 'off';
        $scheduled = wp_next_scheduled('aivt_prompt_monitor');
        $sched_off = ($sched === 'off');
        if ($sched_off) {
            if ($scheduled) {
                wp_clear_scheduled_hook('aivt_prompt_monitor');
            }
            return;
        }
        $recurrence = $sched === 'monthly' ? 'aivt_monthly' : 'weekly';
        if (!$scheduled) {
            wp_schedule_event(time() + HOUR_IN_SECONDS, $recurrence, 'aivt_prompt_monitor');
        }
    }

    /** AI-suggested prompts tailored to the configured business/location. */
    public static function suggest_prompts($count = 6) {
        $s = aivt_get_settings();
        $brand = aivt_site_brand();
        $type = $s['business_type'] ?? '';
        $loc = $s['location'] ?? '';
        $count = max(3, min(12, (int) $count));

        $p  = "Generate {$count} realistic prompts that potential customers would type into an AI assistant (ChatGPT, Perplexity, Gemini) when looking for a business like this — WITHOUT naming the brand. Mix recommendation, comparison and 'best X in {location}' styles.\n";
        $p .= "Business: " . ($type ?: 'unknown') . ". Location/market: " . ($loc ?: 'unknown') . ". Brand (for your reference, do not include it in prompts): {$brand}.\n";
        $p .= "Return ONLY JSON: {\"prompts\":[\"\"]}\n";

        $json = AIVT_API::complete_json($p, 700);
        if (is_wp_error($json)) {
            return $json;
        }
        $out = array_values(array_filter(array_map('sanitize_text_field', (array) ($json['prompts'] ?? []))));
        return array_slice($out, 0, $count);
    }

    /**
     * Run a single prompt and analyze brand/competitor presence.
     *
     * @return array|WP_Error
     */
    public static function run($prompt) {
        $prompt = trim((string) $prompt);
        if ($prompt === '') {
            return new WP_Error('aivt_empty_prompt', __('Enter a prompt to test.', 'pewit-geo-analysis-tool'));
        }
        $answer = AIVT_API::complete_text("Answer this as a helpful assistant giving specific named recommendations where relevant:\n\n" . $prompt, 800);
        if (is_wp_error($answer)) {
            return $answer;
        }
        $analysis = self::analyze_answer($answer);
        $result = array_merge([
            'prompt'   => sanitize_text_field($prompt),
            'answer'   => wp_kses_post($answer),
            'provider' => AIVT_LLM_API::provider_label(aivt_get_settings()['provider'] ?? 'openai'),
        ], $analysis);
        return $result;
    }

    /** Detect brand + aliases + competitor mentions inside an answer. */
    public static function analyze_answer($answer) {
        $answer_l = function_exists('mb_strtolower') ? mb_strtolower($answer) : strtolower($answer);
        $brand_terms = array_merge([aivt_site_brand()], aivt_brand_aliases());
        $brand_terms = array_values(array_filter(array_map('trim', $brand_terms)));

        $mentioned = false;
        $position = -1;
        foreach ($brand_terms as $term) {
            if ($term === '') {
                continue;
            }
            $pos = aivt_mb_strpos($answer_l, function_exists('mb_strtolower') ? mb_strtolower($term) : strtolower($term));
            if ($pos !== false) {
                $mentioned = true;
                $position = $position < 0 ? $pos : min($position, $pos);
            }
        }

        $competitors_found = [];
        foreach (aivt_competitors_list() as $comp) {
            $needle = function_exists('mb_strtolower') ? mb_strtolower($comp) : strtolower($comp);
            if ($needle !== '' && aivt_mb_strpos($answer_l, $needle) !== false) {
                $competitors_found[] = $comp;
            }
        }

        $len = max(1, strlen($answer));
        return [
            'mentioned'         => $mentioned,
            'position_pct'      => $mentioned ? (int) round(($position / $len) * 100) : null,
            'competitors_found' => $competitors_found,
        ];
    }

    /** Pro: run + persist to history for trend tracking. */
    public static function run_and_store($prompt) {
        $result = self::run($prompt);
        if (is_wp_error($result)) {
            return $result;
        }
        if (aivt_prompt_history_enabled()) {
            AIVT_Store::add_prompt_run([
                'prompt'            => $result['prompt'],
                'mentioned'         => $result['mentioned'],
                'position_pct'      => $result['position_pct'],
                'competitors_found' => $result['competitors_found'],
                'provider'          => $result['provider'],
            ]);
        }
        return $result;
    }

    /** Cron: run the monitored prompt set and store results. */
    public static function run_scheduled() {
        if (!aivt_api_ready()) {
            return;
        }
        $prompts = get_option(self::OPT_PROMPTS, []);
        if (!is_array($prompts) || empty($prompts)) {
            return;
        }
        foreach (array_slice($prompts, 0, 25) as $prompt) {
            self::run_and_store($prompt);
        }
    }

    public static function get_monitored_prompts() {
        $p = get_option(self::OPT_PROMPTS, []);
        return is_array($p) ? $p : [];
    }

    public static function set_monitored_prompts($prompts) {
        $clean = array_values(array_filter(array_map('sanitize_text_field', (array) $prompts)));
        update_option(self::OPT_PROMPTS, array_slice($clean, 0, 25), false);
        return $clean;
    }
}

if (!function_exists('aivt_mb_strpos')) {
    /** mb_strpos with graceful fallback. */
    function aivt_mb_strpos($haystack, $needle) {
        if (function_exists('mb_strpos')) {
            return mb_strpos($haystack, $needle);
        }
        return strpos($haystack, $needle);
    }
}
