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

use core\Result;

require_once LCPN_PLUGIN_DIR . 'include/cls-ai-service.php';

/*
 * Azure OpenAI Chat Completion Options:
 * -------------------------------------
 * messages           (array)   - Required. Conversation history as array of messages (role: 'user'/'assistant'/'system', content: string)
 * max_tokens         (int)     - Maximum tokens to generate in the reply.
 * temperature        (float)   - Sampling temperature (creativity), 0-2. Higher = more random.
 * top_p              (float)   - Nucleus sampling parameter, 0-1. Lower = more conservative. Use with or instead of temperature.
 * stop               (string/array) - Up to 4 sequences where the API will stop generating further tokens.
 * presence_penalty   (float)   - -2.0 to 2.0. Penalizes new tokens based on their presence so far. Higher = more new topics.
 * frequency_penalty  (float)   - -2.0 to 2.0. Penalizes new tokens based on their frequency so far. Higher = less repetition.
 * user               (string)  - Unique user identifier (for abuse monitoring).
 * stream             (bool)    - If true, returns streaming responses (partial results).
 * tools              (array)   - Tool definitions for function calling or retrieval.
 * tool_choice        (string/object) - Controls tool/function selection behavior.
 * logit_bias         (object)  - Modify the likelihood of specific tokens appearing in completion.
 * seed               (int)     - Set random seed for reproducible results (if supported).
 */


class AzureOpenAIService extends AIServiceAbstract
{
    private $api_url;
    private $api_key;

    public function __construct()
    {
        $endpoint = untrailingslashit(get_option(LCPN_OPT_OPENAI_API_ENDPOINT));
        $version = get_option(LCPN_OPT_OPENAI_API_VERSION);
        $deployment = get_option(LCPN_OPT_OPENAI_DEPLOYMENT);
        $key = get_option(LCPN_OPT_OPENAI_API_KEY);

        $this->api_url = "$endpoint/openai/deployments/$deployment/chat/completions?api-version=$version";
        $this->api_key = $key;
        $this->set_default_options([
            'max_tokens' => 800,
            'temperature' => 0.8,
        ]);
    }

    protected static function get_profile(): array
    {
        return [
            'name' => 'azure',
            'description' => 'Azure OpenAI GPT-4',
        ];
    }

    /**
     * Make a chat completion call to Azure OpenAI.
     *
     * @param array $messages - Conversation history.
     * @param array $options - Optional params: max_tokens, temperature, etc.
     * @return array|WP_Error - Decoded response or WP_Error
     */

    public function chat(array $messages, array $options = null): Result
    {
        $payload = array_merge([
            'messages' => $messages
        ], $options ?: $this->get_default_options());

        $response = wp_remote_post($this->api_url, [
            'headers' => [
                'api-key' => $this->api_key,
                'Content-Type' => 'application/json',
            ],
            'body' => json_encode($payload),
            'timeout' => 30,
        ]);

        // Check for HTTP request error
        if (is_wp_error($response)) {
            $error_message = 'Azure OpenAI request error: ' . $response->get_error_message();
            Logger::error($error_message);
            return Result::failure($error_message);
        }

        // Retrieve and check response body
        $body_str = wp_remote_retrieve_body($response);
        if (empty($body_str)) {
            $error_message = 'Azure OpenAI: Empty response body.';
            Logger::error($error_message);
            return Result::failure($error_message);
        }

        $body = json_decode($body_str, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            $error_message = 'Azure OpenAI: JSON decode error: ' . json_last_error_msg();
            Logger::error($error_message . ' Body: ' . $body_str);
            return Result::failure($error_message, null, ['raw_response' => $body_str]);
        }

        // Validate expected structure
        if (!isset($body['choices'][0]['message']['content'])) {
            $error_message = 'Azure OpenAI: Missing content in response.';
            Logger::error($error_message . ' Full body: ' . $body_str);
            return Result::failure($error_message, null, ['raw_response' => $body_str]);
        }

        $reply = $body['choices'][0]['message']['content'];

        return Result::success('Success', $reply, ['raw_response' => $body_str]);
    }
}


/**
 * Register the Azure OpenAI service.
 * This should be called during plugin load, not in the constructor.
 */
AzureOpenAIService::setup_registration(); // called during load, not construction
