<?php

namespace RistrettoApps\Spawnster\Services;

use Orhanerday\OpenAi\OpenAi;
use RistrettoApps\Spawnster\Base\Constants;

/**
 * Entry point for OpenAI service.
 *
 * Handles the Open AI request and response.
 *
 * @package    Spawnster
 * @subpackage Spawnster/public
 * @author     Ristretto Apps
 */
class OpenAiService
{
    public string $content;

    /**
     * Get the reponse from OpenAI.
     *
     * @return string|null
     *
     * @throws \Exception
     * @since 1.0.0
     */
    public function getResponse(): ?string
    {
        try {
            //$client = OpenAI::client(get_option(Constants::SPAWNSTER_OPTION_OPENAPI_KEY));
            $client = new OpenAi(get_option(Constants::SPAWNSTER_OPTION_OPENAPI_KEY));
            $result = $client->chat([
                'model' => 'gpt-4o-mini',
                'messages' => [
                    [
                        'role' => 'user',
                        'content' => $this->content,
                    ],
                ],
            ]);

            $response = json_decode($result, true);
            
            // Check for API errors in the response
            if (isset($response['error'])) {
                throw new \Exception('OpenAI API Error: ' . $response['error']['message']);
            }
            
            // Check if we have a valid response structure
            if (!isset($response['choices'][0]['message']['content'])) {
                throw new \Exception('Invalid response from OpenAI API: Missing content in response');
            }

            return $response['choices'][0]['message']['content'];
        } catch (\Exception $e) {
            // Log the error for debugging
            self::log('OpenAI Service Error: ' . $e->getMessage());
            
            // Re-throw with a more user-friendly message if it's a generic error
            if (strpos($e->getMessage(), 'OpenAI API Error:') === false && 
                strpos($e->getMessage(), 'Invalid response') === false) {
                throw new \Exception('Failed to connect to AI service. Please check your API key and try again.');
            }
            
            throw $e;
        }
    }

    /**
     * Creates an embedding using the OpenAI API.
     *
     * @param string $input   The input text to create an embedding for.
     * @param array  $options Additional options for the request.
     * @return array|\WP_Error The response from the API or an error message.
     */
    public function create_embedding( string $input, array $options = array() ): array|\WP_Error {
        $client = new OpenAi(get_option(Constants::SPAWNSTER_OPTION_OPENAPI_KEY));
        
        $data = array_merge(
            array(
                'input' => $input,
                'model' => 'text-embedding-3-small',
            ),
            $options
        );

        $result = $client->embeddings($data);
        $response = json_decode($result, true);

        if (isset($response['error'])) {
            return new \WP_Error('openai_embedding_error', $response['error']['message']);
        }

        return $response;
    }

    /**
     * Generates a response using the OpenAI API with custom options.
     *
     * @param string $prompt  The prompt to send to the API.
     * @param array  $options Additional options for the request.
     * @return array|\WP_Error The response from the API or an error message.
     */
    public function generate_response_with_options( string $prompt, array $options = array() ): array|\WP_Error {
        $client = new OpenAi(get_option(Constants::SPAWNSTER_OPTION_OPENAPI_KEY));
        
        $data = array_merge(
            array(
                'model' => 'gpt-4o',
                'messages' => [
                    [
                        'role' => 'user',
                        'content' => $prompt,
                    ],
                ],
            ),
            $options
        );

        $result = $client->chat($data);
        $response = json_decode($result, true);

        if (isset($response['error'])) {
            return new \WP_Error('openai_generation_error', $response['error']['message']);
        }

        return $response;
    }

    /**
     * Get the language instruction based on the selected default language.
     *
     * @return string The language instruction to append to prompts.
     */
    public function get_language_instruction(): string {
        $default_language = get_option(Constants::SPAWNSTER_OPTION_DEFAULT_LANGUAGE, 'English');
        
        if ($default_language === 'English') {
            return '';
        }
        
        return " Please write all content in {$default_language}.";
    }

    /**
     * Check if logging is enabled.
     *
     * @return bool Whether logging is enabled.
     */
    public static function is_logging_enabled(): bool {
        return get_option(Constants::SPAWNSTER_OPTION_LOGGING_ENABLED, true);
    }

    /**
     * Log a message if logging is enabled.
     *
     * @param string $message The message to log.
     */
    public static function log(string $message): void {
        if (self::is_logging_enabled()) {
            error_log('Spawnster: ' . $message);
        }
    }
}