<?php
/**
 * OpenAI-compatible text providers (Mistral, DeepSeek, Grok, Groq, OpenRouter, Perplexity).
 *
 * Any provider that speaks OpenAI's /v1/chat/completions schema can extend this base.
 *
 * @package CatalogPilot\AiStudio
 */

namespace CatalogPilot\AiStudio\Providers;

defined( 'ABSPATH' ) || exit;

abstract class OpenAI_Compat_Provider extends Provider {

	/** OpenAI-style base URL including /v1 prefix (no trailing slash). */
	protected $api_base = '';

	/** Whether the provider honours `response_format: { type: "json_object" }`. */
	protected $supports_json_mode = true;

	/** Extra headers added to every request (e.g. referer for OpenRouter). */
	protected function extra_headers() {
		return array();
	}

	public function complete( $system, $user ) {
		if ( '' === $this->api_key ) {
			return new \WP_Error( 'cpais_missing_key', __( 'API key is not configured.', 'catalogpilot-ai-studio-for-woocommerce' ) );
		}

		$body = array(
			'model'    => $this->model,
			'messages' => array(
				array( 'role' => 'system', 'content' => $system ),
				array( 'role' => 'user',   'content' => $user ),
			),
			'temperature' => 0.7,
		);
		if ( $this->supports_json_mode ) {
			$body['response_format'] = array( 'type' => 'json_object' );
		}

		$headers = array_merge(
			array(
				'Authorization' => 'Bearer ' . $this->api_key,
				'Content-Type'  => 'application/json',
			),
			$this->extra_headers()
		);

		$data = $this->request(
			$this->api_base . '/chat/completions',
			array(
				'headers' => $headers,
				'body'    => wp_json_encode( $body ),
			)
		);

		if ( is_wp_error( $data ) ) {
			return $data;
		}

		$text = $data['choices'][0]['message']['content'] ?? '';
		return array(
			'text'  => $text,
			'usage' => array(
				'input_tokens'  => $data['usage']['prompt_tokens']     ?? 0,
				'output_tokens' => $data['usage']['completion_tokens'] ?? 0,
			),
		);
	}

	public function test_connection() {
		if ( '' === $this->api_key ) {
			return new \WP_Error( 'cpais_missing_key', __( 'API key is required.', 'catalogpilot-ai-studio-for-woocommerce' ) );
		}
		$response = wp_remote_get(
			$this->api_base . '/models',
			array(
				'timeout' => 15,
				'headers' => array_merge(
					array( 'Authorization' => 'Bearer ' . $this->api_key ),
					$this->extra_headers()
				),
			)
		);
		if ( is_wp_error( $response ) ) {
			return $response;
		}
		$code = wp_remote_retrieve_response_code( $response );
		if ( 200 !== $code ) {
			return new \WP_Error( 'cpais_auth_failed', __( 'Authentication failed.', 'catalogpilot-ai-studio-for-woocommerce' ), array( 'status' => $code ) );
		}
		return true;
	}
}

final class Mistral_Provider extends OpenAI_Compat_Provider {
	protected $api_base = 'https://api.mistral.ai/v1';
	public function id() { return 'mistral'; }
}

final class DeepSeek_Provider extends OpenAI_Compat_Provider {
	protected $api_base = 'https://api.deepseek.com';
	public function id() { return 'deepseek'; }
}

final class Grok_Provider extends OpenAI_Compat_Provider {
	protected $api_base = 'https://api.x.ai/v1';
	public function id() { return 'grok'; }
}

final class Groq_Provider extends OpenAI_Compat_Provider {
	protected $api_base = 'https://api.groq.com/openai/v1';
	public function id() { return 'groq'; }
}

final class OpenRouter_Provider extends OpenAI_Compat_Provider {
	protected $api_base = 'https://openrouter.ai/api/v1';
	public function id() { return 'openrouter'; }

	protected function extra_headers() {
		return array(
			'HTTP-Referer' => esc_url_raw( home_url() ),
			'X-Title'      => 'CatalogPilot AI Studio for WooCommerce',
		);
	}
}

final class Perplexity_Provider extends OpenAI_Compat_Provider {
	protected $api_base = 'https://api.perplexity.ai';
	/** Perplexity ignores response_format for many models — skip json mode. */
	protected $supports_json_mode = false;
	public function id() { return 'perplexity'; }

	public function test_connection() {
		if ( '' === $this->api_key ) {
			return new \WP_Error( 'cpais_missing_key', __( 'API key is required.', 'catalogpilot-ai-studio-for-woocommerce' ) );
		}
		// Perplexity has no public /models endpoint — do a minimal chat call.
		$response = wp_remote_post(
			$this->api_base . '/chat/completions',
			array(
				'timeout' => 15,
				'headers' => array(
					'Authorization' => 'Bearer ' . $this->api_key,
					'Content-Type'  => 'application/json',
				),
				'body'    => wp_json_encode(
					array(
						'model'      => $this->model ?: 'sonar',
						'messages'   => array( array( 'role' => 'user', 'content' => 'ping' ) ),
						'max_tokens' => 1,
					)
				),
			)
		);
		if ( is_wp_error( $response ) ) {
			return $response;
		}
		$code = wp_remote_retrieve_response_code( $response );
		if ( $code < 200 || $code >= 300 ) {
			$body = json_decode( wp_remote_retrieve_body( $response ), true );
			$msg  = $body['error']['message'] ?? sprintf( 'HTTP %d', $code );
			return new \WP_Error( 'cpais_auth_failed', $msg, array( 'status' => $code ) );
		}
		return true;
	}
}
