<?php

namespace Limb_Chatbot\Includes\AI_Providers\Open_Router;

use Limb_Chatbot\Includes\AI_Providers\AI_Provider;
use Limb_Chatbot\Includes\AI_Providers\Open_Router\Endpoints\Key_Endpoint;
use Limb_Chatbot\Includes\Config_Dependent_Interface;
use Limb_Chatbot\Includes\Data_Objects\AI_Model;
use Limb_Chatbot\Includes\Data_Objects\Config;
use Limb_Chatbot\Includes\Exceptions\Error_Codes;
use Limb_Chatbot\Includes\Exceptions\Exception;

/**
 * OpenRouter provider implementation class.
 *
 * Implements AI_Provider and Config_Dependent_Interface for OpenRouter-specific functionality.
 * OpenRouter provides unified access to various AI models from multiple providers.
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Open_Router
 * @since 1.0.14
 */
class Open_Router extends AI_Provider implements Config_Dependent_Interface {

	/**
	 * Base URL for OpenRouter API.
	 *
	 * @since 1.0.14
	 * @var string
	 */
	const API_BASE_URL = 'https://openrouter.ai/api/v1';

	/**
	 * Unique identifier for the OpenRouter provider.
	 *
	 * @since 1.0.14
	 * @var string
	 */
	public static string $id = 'open-router';

	/**
	 * Default timeout for OpenRouter API requests, in seconds.
	 *
	 * @since 1.0.14
	 * @var int
	 */
	public static int $timeout = 60;

	/**
	 * Display name of the OpenRouter provider.
	 *
	 * Note: Uses underscore to match namespace pattern for seeder class resolution.
	 *
	 * @since 1.0.14
	 * @var string
	 */
	public static string $name = 'Open_Router';

	/**
	 * Validates whether the given configuration contains valid API credentials for OpenRouter.
	 *
	 * Uses the /key endpoint which requires authentication, unlike /models which is public.
	 * Returns key information including usage, limits, and tier status.
	 *
	 * Handles OpenRouter-specific error codes:
	 * - 401: Unauthorized - Wrong API key
	 * - 402: Payment Required - Insufficient credits
	 * - 429: Too Many Requests - Rate limit exceeded
	 * - 500/502/503: Server errors
	 *
	 * @param Config $config Configuration object to validate.
	 *
	 * @return bool True if valid API credentials; false otherwise.
	 * @throws Exception If authentication fails or other API errors occur.
	 * @since 1.0.14
	 */
	public function is_valid_config( Config $config ): bool {
		try {
			$key_endpoint = new Key_Endpoint( $config );
			$key_info     = $key_endpoint->get();

			return ! empty( $key_info );
		} catch ( Exception $e ) {
			$error_code = $e->get_error_code();

			switch ( $error_code ) {
				case Error_Codes::AUTHENTICATION_UNAUTHORIZED:
				case Error_Codes::AUTHENTICATION_API_KEY_MISSING:
					throw new Exception(
						Error_Codes::AUTHENTICATION_UNAUTHORIZED,
						__( 'OpenRouter API authentication failed. Please check your API key.', 'limb-chatbot' ),
						$e->get_error_data()
					);

				case Error_Codes::QUOTA_EXCEED:
					throw new Exception(
						Error_Codes::QUOTA_EXCEED,
						__( 'OpenRouter API quota exceeded. Please check your credits.', 'limb-chatbot' ),
						$e->get_error_data()
					);

				case Error_Codes::TECHNICAL_ERROR:
					throw new Exception(
						Error_Codes::TECHNICAL_ERROR,
						__( 'OpenRouter API server error. Please retry after a brief wait.', 'limb-chatbot' ),
						$e->get_error_data()
					);

				default:
					throw $e;
			}
		}
	}

	/**
	 * Returns the default embedding model for this provider.
	 *
	 * @return AI_Model|null The default embedding model or null if not found.
	 * @since 1.0.14
	 */
	public function get_default_embedding_model() {
		return AI_Model::find_by_name( 'openai/text-embedding-3-small' );
	}
}
