<?php
/**
 * Provider-Agnostic Embedding Service.
 *
 * @package Replyan_AI
 */

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

class Replyan_AI_Embedding_Service {

	private string $provider;
	private string $model;
	private array  $settings;

	public function __construct( ?array $settings = null ) {
		$this->settings = $settings ?? Replyan_AI_Settings::get();
		$this->provider = $this->settings['embedding_provider'] ?? '';
		$this->model    = $this->settings['embedding_model'] ?? '';

		// Auto-detect embedding provider and model if not explicitly set
		if ( empty( $this->provider ) ) {
			if ( ! empty( $this->settings['api_key'] ) ) {
				$this->provider = 'openai';
				if ( empty( $this->model ) ) {
					$this->model = 'text-embedding-3-small';
				}
			} elseif ( ! empty( $this->settings['openrouter_api_key'] ) ) {
				$this->provider = 'openrouter';
				if ( empty( $this->model ) ) {
					$this->model = 'openai/text-embedding-3-small';
				}
			} elseif ( ! empty( $this->settings['gemini_api_key'] ) ) {
				$this->provider = 'gemini';
				if ( empty( $this->model ) ) {
					$this->model = 'text-embedding-004';
				}
			}
		}
	}

	/**
	 * Generates an embedding for the given text.
	 *
	 * @param string $text The text to embed.
	 * @return array Array of floats.
	 * @throws Exception If generation fails.
	 */
	public function generate( string $text ): array {
		if ( empty( trim( $text ) ) ) {
			return array();
		}

		switch ( $this->provider ) {
			case 'openai':
				return $this->generateOpenAI( $text );
			case 'openrouter':
				return $this->generateOpenRouter( $text );
			case 'gemini':
				return $this->generateGemini( $text );
			case 'anthropic':
				return $this->generateAnthropic( $text ); // e.g. Voyage AI
			default:
				return array();
		}
	}

	/**
	 * Generate Batch Embeddings (For Future Support)
	 * 
	 * @param array $texts Array of strings.
	 * @return array Array of embedding arrays.
	 */
	public function generateBatch( array $texts ): array {
		// Future implementation
		throw new Exception( 'Batch embeddings not yet implemented.' );
	}

	private function generateOpenAI( string $text ): array {
		$api_key = $this->settings['api_key'] ?? '';
		if ( empty( $api_key ) ) {
			throw new Exception( 'OpenAI API key is missing.' );
		}

		$response = wp_remote_post( 'https://api.openai.com/v1/embeddings', array(
			'timeout' => 30,
			'headers' => array(
				'Authorization' => 'Bearer ' . $api_key,
				'Content-Type'  => 'application/json',
			),
			'body'    => wp_json_encode( array(
				'model' => $this->model,
				'input' => $text,
			) ),
		) );

		if ( is_wp_error( $response ) ) {
			throw new Exception( esc_html( 'Network error: ' . $response->get_error_message() ) );
		}

		$body = wp_remote_retrieve_body( $response );
		$data = json_decode( $body, true );

		if ( isset( $data['error'] ) ) {
			throw new Exception( esc_html( 'OpenAI API Error: ' . ( $data['error']['message'] ?? 'Unknown error' ) ) );
		}

		if ( isset( $data['data'][0]['embedding'] ) ) {
			return $data['data'][0]['embedding'];
		}

		throw new Exception( 'Unexpected response format from OpenAI.' );
	}

	private function generateOpenRouter( string $text ): array {
		$api_key = $this->settings['openrouter_api_key'] ?? '';
		if ( empty( $api_key ) ) {
			throw new Exception( 'OpenRouter API key is missing.' );
		}

		$response = wp_remote_post( 'https://openrouter.ai/api/v1/embeddings', array(
			'timeout' => 30,
			'headers' => array(
				'Authorization' => 'Bearer ' . $api_key,
				'Content-Type'  => 'application/json',
			),
			'body'    => wp_json_encode( array(
				'model' => $this->model,
				'input' => $text,
			) ),
		) );

		if ( is_wp_error( $response ) ) {
			throw new Exception( esc_html( 'Network error: ' . $response->get_error_message() ) );
		}

		$body = wp_remote_retrieve_body( $response );
		$data = json_decode( $body, true );

		if ( isset( $data['error'] ) ) {
			throw new Exception( esc_html( 'OpenRouter API Error: ' . ( $data['error']['message'] ?? 'Unknown error' ) ) );
		}

		if ( isset( $data['data'][0]['embedding'] ) ) {
			return $data['data'][0]['embedding'];
		}

		throw new Exception( 'Unexpected response format from OpenRouter.' );
	}

	private function generateGemini( string $text ): array {
		$api_key = $this->settings['gemini_api_key'] ?? '';
		if ( empty( $api_key ) ) {
			throw new Exception( 'Gemini API key is missing.' );
		}

		$model = $this->model ?: 'text-embedding-004';
		$url   = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:embedContent?key={$api_key}";

		$response = wp_remote_post( $url, array(
			'timeout' => 30,
			'headers' => array(
				'Content-Type' => 'application/json',
			),
			'body'    => wp_json_encode( array(
				'model'   => "models/{$model}",
				'content' => array(
					'parts' => array(
						array( 'text' => $text ),
					),
				),
			) ),
		) );

		if ( is_wp_error( $response ) ) {
			throw new Exception( esc_html( 'Network error: ' . $response->get_error_message() ) );
		}

		$body = wp_remote_retrieve_body( $response );
		$data = json_decode( $body, true );

		if ( isset( $data['error'] ) ) {
			throw new Exception( esc_html( 'Gemini API Error: ' . ( $data['error']['message'] ?? 'Unknown error' ) ) );
		}

		if ( isset( $data['embedding']['values'] ) ) {
			return $data['embedding']['values'];
		}

		throw new Exception( 'Unexpected response format from Gemini.' );
	}

	private function generateAnthropic( string $text ): array {
		throw new Exception( 'Anthropic embedding not yet implemented.' );
	}
}
