<?php
/**
 * OpenRouter model catalog helpers (free tier discovery).
 *
 * @package WP_PowerSuite\AI
 */

namespace WP_PowerSuite\AI;

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

/**
 * Fetches and caches OpenRouter models suitable for zero-cost inference.
 */
final class OpenRouterModels {

	private const MODELS_URL  = 'https://openrouter.ai/api/v1/models';
	private const CACHE_KEY   = 'wpps_openrouter_free_models';
	private const CACHE_TTL   = 6 * HOUR_IN_SECONDS;

	/**
	 * @return array<string, string> Model ID => display label.
	 */
	public static function getFreeModels(): array {
		$cached = get_transient( self::CACHE_KEY );
		if ( is_array( $cached ) ) {
			return $cached;
		}

		$models = self::fetchFreeModels();
		set_transient( self::CACHE_KEY, $models, self::CACHE_TTL );

		return $models;
	}

	public static function flushCache(): void {
		delete_transient( self::CACHE_KEY );
	}

	/**
	 * @return array<string, string>
	 */
	private static function fetchFreeModels(): array {
		$response = wp_remote_get(
			self::MODELS_URL,
			[
				'timeout' => 20,
				'headers' => self::requestHeaders(),
			]
		);

		if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
			return self::fallbackFreeModels();
		}

		$body = json_decode( (string) wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $body ) || ! isset( $body['data'] ) || ! is_array( $body['data'] ) ) {
			return self::fallbackFreeModels();
		}

		$models = [];
		foreach ( $body['data'] as $model ) {
			if ( ! is_array( $model ) || ! self::isFreeTextModel( $model ) ) {
				continue;
			}

			$id = trim( (string) ( $model['id'] ?? '' ) );
			if ( $id === '' ) {
				continue;
			}

			$name = trim( (string) ( $model['name'] ?? $id ) );
			$models[ $id ] = $name !== '' ? $name : $id;
		}

		if ( $models === [] ) {
			return self::fallbackFreeModels();
		}

		uasort(
			$models,
			static function ( string $a, string $b ): int {
				return strcasecmp( $a, $b );
			}
		);

		return self::prioritizeRouter( $models );
	}

	/**
	 * @param array<string, mixed> $model
	 */
	private static function isFreeTextModel( array $model ): bool {
		$id = (string) ( $model['id'] ?? '' );
		if ( $id === '' ) {
			return false;
		}

		if ( str_contains( strtolower( $id ), 'rerank' ) || str_contains( strtolower( $id ), 'embed' ) ) {
			return false;
		}

		$architecture = is_array( $model['architecture'] ?? null ) ? $model['architecture'] : [];
		$modality     = strtolower( (string) ( $architecture['modality'] ?? '' ) );
		$inputs       = is_array( $architecture['input_modalities'] ?? null ) ? $architecture['input_modalities'] : [];
		$outputs      = is_array( $architecture['output_modalities'] ?? null ) ? $architecture['output_modalities'] : [];

		if ( ! in_array( 'text', $outputs, true ) || ! in_array( 'text', $inputs, true ) ) {
			return false;
		}

		if ( $modality !== '' && ! str_contains( $modality, 'text' ) ) {
			return false;
		}

		$pricing = is_array( $model['pricing'] ?? null ) ? $model['pricing'] : [];

		return self::pricingIsFree( (string) ( $pricing['prompt'] ?? '' ) )
			&& self::pricingIsFree( (string) ( $pricing['completion'] ?? '' ) );
	}

	private static function pricingIsFree( string $value ): bool {
		if ( $value === '' ) {
			return false;
		}

		return (float) $value === 0.0;
	}

	/**
	 * @param array<string, string> $models
	 * @return array<string, string>
	 */
	private static function prioritizeRouter( array $models ): array {
		if ( ! isset( $models['openrouter/free'] ) ) {
			return $models;
		}

		$router = [ 'openrouter/free' => $models['openrouter/free'] ];
		unset( $models['openrouter/free'] );

		return $router + $models;
	}

	/**
	 * @return array<string, string>
	 */
	private static function fallbackFreeModels(): array {
		return [
			'openrouter/free'                          => __( 'Free Models Router — auto-selects a free model', 'wppowersuite-lite' ),
			'openai/gpt-oss-20b:free'                  => __( 'OpenAI: gpt-oss-20b (free)', 'wppowersuite-lite' ),
			'google/gemma-4-26b-a4b-it:free'           => __( 'Google: Gemma 4 26B (free)', 'wppowersuite-lite' ),
			'meta-llama/llama-3.3-70b-instruct:free'   => __( 'Meta: Llama 3.3 70B Instruct (free)', 'wppowersuite-lite' ),
			'qwen/qwen-2.5-72b-instruct:free'          => __( 'Qwen: Qwen 2.5 72B Instruct (free)', 'wppowersuite-lite' ),
			'deepseek/deepseek-r1:free'                => __( 'DeepSeek: R1 (free)', 'wppowersuite-lite' ),
		];
	}

	/**
	 * @return array<string, string>
	 */
	private static function requestHeaders(): array {
		$headers = [
			'Accept' => 'application/json',
		];

		$api_key = ConnectionSettings::getApiKey( null, 'openrouter' );
		if ( $api_key !== '' ) {
			$headers['Authorization'] = 'Bearer ' . $api_key;
		}

		return array_merge( $headers, OpenAiCompatibleClient::openRouterHeaders() );
	}
}
