<?php
/**
 * Optional LLM provider API keys (Settings → LLM Setup) and admin AJAX tests.
 */

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

/**
 * Supported providers (id => admin label).
 *
 * @return array<string, string>
 */
function askagento_llm_provider_registry(): array {
    return [
        'openai'     => __('OpenAI', 'askagento'),
        'anthropic'  => __('Anthropic', 'askagento'),
        'google'     => __('Google', 'askagento'),
        'openrouter' => __('OpenRouter', 'askagento'),
    ];
}

/**
 * Default OpenAI model (aligned with the hosted AskAgento chatbot service).
 */
function askagento_llm_openai_default_model(): string {
    return 'gpt-5-mini';
}

/**
 * OpenAI models available in LLM Setup (id => admin label).
 *
 * @return array<string, string>
 */
function askagento_llm_openai_model_registry(): array {
    return [
        'gpt-5-mini' => __('GPT-5 Mini', 'askagento'),
        'gpt-5.5'    => __('GPT-5.5', 'askagento'),
    ];
}

/**
 * @return string OpenAI model id from the registry.
 */
function askagento_get_llm_openai_model(): string {
    $saved = get_option('askagento_llm_openai_model', askagento_llm_openai_default_model());
    $saved = is_string($saved) ? trim($saved) : '';
    $registry = askagento_llm_openai_model_registry();
    if ($saved !== '' && isset($registry[$saved])) {
        return $saved;
    }

    return askagento_llm_openai_default_model();
}

/**
 * @param mixed $input Posted option value.
 */
function askagento_sanitize_llm_openai_model($input): string {
    $model = is_string($input) ? trim($input) : '';
    $registry = askagento_llm_openai_model_registry();
    if ($model !== '' && isset($registry[$model])) {
        return $model;
    }

    return askagento_llm_openai_default_model();
}

/**
 * @return array<string, string>
 */
function askagento_get_llm_provider_api_keys(): array {
    $raw = get_option('askagento_llm_provider_api_keys', []);
    if (!is_array($raw)) {
        $raw = [];
    }
    $out = [];
    foreach (array_keys(askagento_llm_provider_registry()) as $id) {
        $out[$id] = isset($raw[$id]) ? (string) $raw[$id] : '';
    }

    return $out;
}

/**
 * Human-readable masked hint for a stored key (never returns the raw key).
 */
function askagento_llm_mask_saved_key_display(string $key): string {
    $key = trim($key);
    if ($key === '') {
        return __('No key saved', 'askagento');
    }
    $len = strlen($key);
    if ($len <= 8) {
        return str_repeat('•', min(8, $len));
    }

    return substr($key, 0, 4) . str_repeat('•', 6) . substr($key, -4);
}

/**
 * @param mixed $input Posted option value.
 * @return array<string, string>
 */
function askagento_sanitize_llm_provider_api_keys($input): array {
    $existing = askagento_get_llm_provider_api_keys();
    if (!is_array($input)) {
        return $existing;
    }
    $out = [];
    foreach (array_keys(askagento_llm_provider_registry()) as $id) {
        $raw = isset($input[$id]) ? trim((string) wp_unslash($input[$id])) : '';
        if ($raw === '') {
            $out[$id] = $existing[$id] ?? '';
        } else {
            $out[$id] = $raw;
        }
    }

    foreach (array_keys($out) as $slot_id) {
        if (($out[$slot_id] ?? '') === '') {
            unset($out[$slot_id]);
        }
    }

    return $out;
}

/**
 * @param array|WP_Error $response HTTP response.
 * @return string Short error text for JSON responses.
 */
function askagento_llm_format_http_failure($response): string {
    if (is_wp_error($response)) {
        return $response->get_error_message();
    }
    $code = (int) wp_remote_retrieve_response_code($response);
    $body = (string) wp_remote_retrieve_body($response);
    $snippet = '';
    if ($body !== '') {
        $decoded = json_decode($body, true);
        if (is_array($decoded)) {
            if (!empty($decoded['error']['message'])) {
                $snippet = (string) $decoded['error']['message'];
            } elseif (!empty($decoded['message'])) {
                $snippet = (string) $decoded['message'];
            }
        }
        if ($snippet === '') {
            $snippet = mb_substr(wp_strip_all_tags($body), 0, 200);
        }
    }
    if ($snippet !== '') {
        /* translators: 1: HTTP status code, 2: server message snippet */
        return sprintf(__('HTTP %1$d - %2$s', 'askagento'), $code, $snippet);
    }

    /* translators: %d: HTTP status code */
    return sprintf(__('HTTP %d (empty body).', 'askagento'), $code);
}

/**
 * @param string $api_key Trimmed API key.
 * @return true|WP_Error
 */
function askagento_llm_test_openai(string $api_key) {
    $response = wp_remote_get(
        'https://api.openai.com/v1/models',
        [
            'timeout' => 20,
            'headers' => [
                'Authorization' => 'Bearer ' . $api_key,
            ],
        ]
    );
    if (is_wp_error($response)) {
        return $response;
    }
    $code = (int) wp_remote_retrieve_response_code($response);
    if ($code >= 200 && $code < 300) {
        return true;
    }

    return new WP_Error('openai_http', askagento_llm_format_http_failure($response));
}

/**
 * @param string $api_key Trimmed API key.
 * @return true|WP_Error
 */
function askagento_llm_test_anthropic(string $api_key) {
    $response = wp_remote_get(
        'https://api.anthropic.com/v1/models',
        [
            'timeout' => 20,
            'headers' => [
                'x-api-key'         => $api_key,
                'anthropic-version' => '2023-06-01',
            ],
        ]
    );
    if (is_wp_error($response)) {
        return $response;
    }
    $code = (int) wp_remote_retrieve_response_code($response);
    if ($code >= 200 && $code < 300) {
        return true;
    }

    return new WP_Error('anthropic_http', askagento_llm_format_http_failure($response));
}

/**
 * @param string $api_key Trimmed API key.
 * @return true|WP_Error
 */
function askagento_llm_test_google(string $api_key) {
    $url = add_query_arg(
        'key',
        rawurlencode($api_key),
        'https://generativelanguage.googleapis.com/v1/models'
    );
    $response = wp_remote_get($url, ['timeout' => 20]);
    if (is_wp_error($response)) {
        return $response;
    }
    $code = (int) wp_remote_retrieve_response_code($response);
    if ($code >= 200 && $code < 300) {
        return true;
    }

    return new WP_Error('google_http', askagento_llm_format_http_failure($response));
}

/**
 * @param string $api_key Trimmed API key.
 * @return true|WP_Error
 */
function askagento_llm_test_openrouter(string $api_key) {
    $response = wp_remote_get(
        'https://openrouter.ai/api/v1/models',
        [
            'timeout' => 20,
            'headers' => [
                'Authorization' => 'Bearer ' . $api_key,
            ],
        ]
    );
    if (is_wp_error($response)) {
        return $response;
    }
    $code = (int) wp_remote_retrieve_response_code($response);
    if ($code >= 200 && $code < 300) {
        return true;
    }

    return new WP_Error('openrouter_http', askagento_llm_format_http_failure($response));
}

/**
 * @param string $provider_id Provider slug.
 * @param string $api_key     Key to test (trimmed).
 * @return true|WP_Error
 */
function askagento_llm_test_provider_key(string $provider_id, string $api_key) {
    $api_key = trim($api_key);
    if ($api_key === '') {
        return new WP_Error('empty_key', __('Enter an API key to test.', 'askagento'));
    }
    $registry = askagento_llm_provider_registry();
    if (!isset($registry[$provider_id])) {
        return new WP_Error('bad_provider', __('Unknown provider.', 'askagento'));
    }
    switch ($provider_id) {
        case 'openai':
            return askagento_llm_test_openai($api_key);
        case 'anthropic':
            return askagento_llm_test_anthropic($api_key);
        case 'google':
            return askagento_llm_test_google($api_key);
        case 'openrouter':
            return askagento_llm_test_openrouter($api_key);
        default:
            return new WP_Error('bad_provider', __('Unknown provider.', 'askagento'));
    }
}

add_action('wp_ajax_askagento_test_llm_provider_key', static function () {
    if (!check_ajax_referer('askagento_admin', 'nonce', false)) {
        wp_send_json_error(['message' => __('Security check failed. Please reload the page.', 'askagento')], 403);
    }
    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('Permission denied.', 'askagento')], 403);
    }
    // Use dedicated POST keys: generic `provider` / `api_key` are sometimes stripped or altered by proxies or security rules.
    $posted_provider = isset($_POST['llm_provider']) ? sanitize_key(wp_unslash($_POST['llm_provider'])) : '';
    if ($posted_provider === '' && isset($_POST['provider'])) {
        $posted_provider = sanitize_key(wp_unslash($_POST['provider']));
    }
    $provider_id = sanitize_key($posted_provider);
    $posted_key   = isset($_POST['llm_api_key']) ? sanitize_text_field(wp_unslash($_POST['llm_api_key'])) : '';
    if ($posted_key === '' && isset($_POST['api_key'])) {
        $posted_key = sanitize_text_field(wp_unslash($_POST['api_key']));
    }
    $posted_key = trim($posted_key);
    if ($provider_id === '' || !array_key_exists($provider_id, askagento_llm_provider_registry())) {
        wp_send_json_error(['message' => __('Unknown provider.', 'askagento')]);
    }
    $keys    = askagento_get_llm_provider_api_keys();
    $api_key = $posted_key !== '' ? $posted_key : ($keys[$provider_id] ?? '');
    $result  = askagento_llm_test_provider_key($provider_id, $api_key);
    if (is_wp_error($result)) {
        wp_send_json_error(['message' => $result->get_error_message()]);
    }
    wp_send_json_success(['message' => __('Key is valid.', 'askagento')]);
});

add_action('wp_ajax_askagento_clear_llm_provider_key', static function () {
    if (!check_ajax_referer('askagento_admin', 'nonce', false)) {
        wp_send_json_error(['message' => __('Security check failed. Please reload the page.', 'askagento')], 403);
    }
    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('Permission denied.', 'askagento')], 403);
    }
    $posted_provider = isset($_POST['llm_provider']) ? sanitize_key(wp_unslash($_POST['llm_provider'])) : '';
    $provider_id     = sanitize_key($posted_provider);
    if ($provider_id === '' || !array_key_exists($provider_id, askagento_llm_provider_registry())) {
        wp_send_json_error(['message' => __('Unknown provider.', 'askagento')]);
    }
    $stored = get_option('askagento_llm_provider_api_keys', []);
    if (!is_array($stored)) {
        $stored = [];
    }
    unset($stored[$provider_id]);
    update_option('askagento_llm_provider_api_keys', $stored);

    if (function_exists('wp_clean_option_cache')) {
        wp_clean_option_cache('askagento_llm_provider_api_keys');
    }
    wp_cache_delete('askagento_llm_provider_api_keys', 'options');
    wp_cache_delete('alloptions', 'options');

    wp_send_json_success(
        [
            'message' => __('Saved API key cleared.', 'askagento'),
            'mask'    => askagento_llm_mask_saved_key_display(''),
        ]
    );
});
