<?php
/**
 * Vision model registry for all AI providers.
 *
 * @package AIAltTextGenerator
 * @since 1.7.0
 */

namespace AIAltTextGenerator;

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

/**
 * @since 1.7.0
 */
class ProviderModels {

	/**
	 * Retired model IDs mapped to the closest current replacement.
	 *
	 * @var array<string, string>
	 */
	private const RETIRED_MAP = [
		'gemini-2.0-flash'         => 'gemini-2.5-flash',
		'gemini-2.0-flash-lite'    => 'gemini-2.5-flash-lite',
		'gemini-1.5-pro'           => 'gemini-2.5-pro',
		'gemini-1.5-flash'         => 'gemini-2.5-flash',
		'claude-3-5-haiku-latest'  => 'claude-haiku-4-5-20251001',
		'claude-3-5-sonnet-latest' => 'claude-sonnet-4-6',
		'claude-3-haiku-20240307'   => 'claude-haiku-4-5-20251001',
	];

	/**
	 * @param array<string, mixed> $settings
	 * @return array<string, array{label: string, models: array<string, string>}>
	 */
	public static function getGroups( string $provider, array $settings = [] ): array {
		$provider = Settings::sanitizeProvider( $provider );

		$groups = match ( $provider ) {
			'gemini' => self::geminiGroups(),
			'claude' => self::claudeGroups(),
			default  => Models::getGroups( $settings ),
		};

		/**
		 * Filter grouped vision models for a provider.
		 *
		 * @param array<string, array{label: string, models: array<string, string>}> $groups   Model groups.
		 * @param string                                                            $provider Provider ID.
		 * @param array<string, mixed>                                              $settings Module settings.
		 */
		return apply_filters( 'wpps_ai_alt_text_provider_model_groups', $groups, $provider, $settings );
	}

	/**
	 * @param array<string, mixed> $settings
	 * @return array<string, string>
	 */
	public static function getList( string $provider, array $settings = [] ): array {
		$list = [];
		foreach ( self::getGroups( $provider, $settings ) as $group ) {
			if ( ! isset( $group['models'] ) || ! is_array( $group['models'] ) ) {
				continue;
			}
			foreach ( $group['models'] as $id => $label ) {
				$list[ (string) $id ] = (string) $label;
			}
		}

		return $list;
	}

	public static function getDefault( string $provider ): string {
		return match ( Settings::sanitizeProvider( $provider ) ) {
			'gemini' => 'gemini-2.5-flash',
			'claude' => 'claude-haiku-4-5-20251001',
			default  => Models::DEFAULT,
		};
	}

	/**
	 * @param array<string, mixed> $settings
	 */
	public static function sanitize( string $model, string $provider, array $settings = [] ): string {
		$provider = Settings::sanitizeProvider( $provider );
		$model    = trim( sanitize_text_field( $model ) );

		if ( $provider === 'openai' ) {
			return Models::sanitize( $model, $settings );
		}

		if ( $model === '' ) {
			return self::getDefault( $provider );
		}

		if ( isset( self::RETIRED_MAP[ $model ] ) ) {
			$model = self::RETIRED_MAP[ $model ];
		}

		$allowed = array_keys( self::getList( $provider, $settings ) );
		if ( in_array( $model, $allowed, true ) ) {
			return $model;
		}

		return self::getDefault( $provider );
	}

	/**
	 * @param array<string, mixed> $settings
	 */
	public static function getSettingsHint( string $provider, array $settings ): string {
		$provider = Settings::sanitizeProvider( $provider );

		if ( $provider === 'gemini' ) {
			return __( 'Gemini 2.5 Flash is the recommended default. Use Flash Lite for bulk libraries or 2.5 Pro for complex scenes.', 'wp-powersuite' );
		}

		if ( $provider === 'claude' ) {
			return __( 'Claude Haiku 4.5 is fast and cost-effective. Use Sonnet 4.6 when you need richer, more specific descriptions.', 'wp-powersuite' );
		}

		return Models::getSettingsHint( $settings );
	}

	/**
	 * @return array<string, array{label: string, models: array<string, string>}>
	 */
	private static function geminiGroups(): array {
		return [
			'budget' => [
				'label'  => __( 'Budget (bulk uploads)', 'wp-powersuite' ),
				'models' => [
					'gemini-2.5-flash'      => __( 'Gemini 2.5 Flash — recommended default', 'wp-powersuite' ),
					'gemini-2.5-flash-lite' => __( 'Gemini 2.5 Flash Lite — lowest cost', 'wp-powersuite' ),
				],
			],
			'premium' => [
				'label'  => __( 'Premium (complex images)', 'wp-powersuite' ),
				'models' => [
					'gemini-2.5-pro'   => __( 'Gemini 2.5 Pro — detailed or SEO-focused alt text', 'wp-powersuite' ),
					'gemini-3.5-flash' => __( 'Gemini 3.5 Flash — latest generation', 'wp-powersuite' ),
				],
			],
		];
	}

	/**
	 * @return array<string, array{label: string, models: array<string, string>}>
	 */
	private static function claudeGroups(): array {
		return [
			'budget' => [
				'label'  => __( 'Budget (bulk uploads)', 'wp-powersuite' ),
				'models' => [
					'claude-haiku-4-5-20251001' => __( 'Claude Haiku 4.5 — recommended default', 'wp-powersuite' ),
				],
			],
			'premium' => [
				'label'  => __( 'Premium (complex images)', 'wp-powersuite' ),
				'models' => [
					'claude-sonnet-4-6' => __( 'Claude Sonnet 4.6 — richer descriptions', 'wp-powersuite' ),
					'claude-opus-4-8'   => __( 'Claude Opus 4.8 — highest quality', 'wp-powersuite' ),
				],
			],
		];
	}
}
