<?php

declare(strict_types=1);

namespace AIPT\Utils;

/**
 * Provider Name Mapper
 *
 * Single source of truth for mapping between internal AIPT provider IDs
 * and WordPress 7.0 Connectors IDs. This class bridges the naming conventions:
 *
 * - AIPT uses: 'openai', 'claude', 'gemini', 'openrouter'
 * - WP 7.0 Connectors uses: 'openai', 'anthropic', 'google', 'openrouter'
 *
 * The first three (openai, anthropic/google) are built-in WP 7.0 Connectors.
 * OpenRouter mapping is retained as defensive code only — the plugin no
 * longer registers OpenRouter as a Connector (see Init.php). OpenRouter
 * credentials are sourced exclusively from the plugin's local AES-256-GCM
 * storage (`aipt_openrouter_api_key`).
 *
 * @since 2.6.0
 */
final class ProviderNameMapper {

	/**
	 * Get the list of supported AIPT provider IDs.
	 *
	 * @since 2.6.0
	 *
	 * @return array<int, string> Frozen list of AIPT provider IDs: ['openai', 'gemini', 'claude', 'openrouter']
	 */
	public static function aiptProviders(): array {
		return array( 'openai', 'gemini', 'claude', 'openrouter' );
	}

	/**
	 * Convert AIPT provider ID to WordPress Connectors ID.
	 *
	 * Maps internal AIPT naming to WP 7.0 Connectors naming:
	 * - 'openai' → 'openai'
	 * - 'claude' → 'anthropic'
	 * - 'gemini' → 'google'
	 * - 'openrouter' → 'openrouter'
	 *
	 * @since 2.6.0
	 *
	 * @param string $aipt_provider AIPT provider ID (e.g., 'claude', 'gemini').
	 *
	 * @return string WordPress Connectors ID.
	 *
	 * @throws \InvalidArgumentException If provider is unknown.
	 */
	public static function toConnectorId( string $aipt_provider ): string {
		$mapping = self::getProviderMapping();

		if ( ! isset( $mapping[ $aipt_provider ] ) ) {
			throw new \InvalidArgumentException(

				"Unknown AIPT provider: {$aipt_provider}"
			);
		}

		return $mapping[ $aipt_provider ];
	}

	/**
	 * Single source of truth for AIPT provider → WP 7.0 Connectors ID mapping.
	 *
	 * Adding a new provider requires only one edit here. The reverse mapping
	 * (toAiptProvider) is derived via array_flip so it stays in sync automatically.
	 *
	 * @since 2.6.0
	 *
	 * @return array<string, string> AIPT provider id → Connectors id.
	 */
	private static function getProviderMapping(): array {
		return array(
			'openai'     => 'openai',
			'claude'     => 'anthropic',
			'gemini'     => 'google',
			'openrouter' => 'openrouter',
		);
	}

	/**
	 * Convert WordPress Connectors ID to AIPT provider ID (reverse mapping).
	 *
	 * Maps WP 7.0 Connectors naming back to internal AIPT naming:
	 * - 'openai' → 'openai'
	 * - 'anthropic' → 'claude'
	 * - 'google' → 'gemini'
	 * - 'openrouter' → 'openrouter'
	 *
	 * @since 2.6.0
	 *
	 * @param string $connector_id WordPress Connectors ID (e.g., 'anthropic', 'google').
	 *
	 * @return string AIPT provider ID.
	 *
	 * @throws \InvalidArgumentException If connector ID is unknown.
	 */
	public static function toAiptProvider( string $connector_id ): string {
		$reverse_mapping = array_flip( self::getProviderMapping() );

		if ( ! isset( $reverse_mapping[ $connector_id ] ) ) {
			throw new \InvalidArgumentException(

				"Unknown connector ID: {$connector_id}"
			);
		}

		return $reverse_mapping[ $connector_id ];
	}

	/**
	 * Check if an AIPT provider is supported by WordPress 7.0 built-in Connectors.
	 *
	 * Built-in providers: 'openai', 'claude' (anthropic), 'gemini' (google).
	 * Self-registered: 'openrouter'.
	 *
	 * @since 2.6.0
	 *
	 * @param string $aipt_provider AIPT provider ID.
	 *
	 * @return bool True if provider is built-in to WP 7.0 Connectors, false if self-registered.
	 *
	 * @throws \InvalidArgumentException If provider is unknown.
	 */
	public static function isSupportedByCoreConnectors( string $aipt_provider ): bool {
		$core_providers = array( 'openai', 'claude', 'gemini' );

		if ( ! in_array( $aipt_provider, self::aiptProviders(), true ) ) {
			throw new \InvalidArgumentException(

				"Unknown AIPT provider: {$aipt_provider}"
			);
		}

		return in_array( $aipt_provider, $core_providers, true );
	}

	/**
	 * Get human-readable display name for an AIPT provider.
	 *
	 * Returns i18n-aware display names:
	 * - 'openai' → 'OpenAI'
	 * - 'claude' → 'Anthropic Claude'
	 * - 'gemini' → 'Google Gemini'
	 * - 'openrouter' → 'OpenRouter'
	 *
	 * @since 2.6.0
	 *
	 * @param string $aipt_provider AIPT provider ID.
	 *
	 * @return string Human-readable display name (i18n-wrapped).
	 *
	 * @throws \InvalidArgumentException If provider is unknown.
	 */
	public static function displayName( string $aipt_provider ): string {
		$names = array(
			'openai'    => _x( 'OpenAI', 'AI provider display name', 'ai-product-tools' ),
			'claude'    => _x( 'Anthropic Claude', 'AI provider display name', 'ai-product-tools' ),
			'gemini'    => _x( 'Google Gemini', 'AI provider display name', 'ai-product-tools' ),
			'openrouter' => _x( 'OpenRouter', 'AI provider display name', 'ai-product-tools' ),
		);

		if ( ! isset( $names[ $aipt_provider ] ) ) {
			throw new \InvalidArgumentException(

				"Unknown AIPT provider: {$aipt_provider}"
			);
		}

		return $names[ $aipt_provider ];
	}
}
