<?php

declare( strict_types=1 );

namespace Brightfern\Transmission;

use Brightfern\Support\Http\HttpClient;
use Brightfern\Support\Http\WpHttpClient;

/**
 * Builds the configured {@see AccessPointProvider} from settings. The registry
 * pattern is the swap point: new providers register here — the rest of the
 * plugin only ever talks to the interface.
 *
 * Two ways to reach KSeF exist side by side, deliberately: `storecove`
 * routes KSeF through Storecove's paid "V-flow" (same account/credentials as
 * Peppol, just a different OutboundDocument::CHANNEL_* — see
 * StorecoveProvider::buildKsefBody()); `ksef-direct` talks to the Ministry
 * of Finance's own REST API with no intermediary or platform fee, at the
 * cost of the plugin owning real client-side cryptography (see
 * KsefProvider). Neither replaces the other — a merchant picks whichever
 * fits them.
 *
 * Adding a provider:
 *   1. Implement AccessPointProvider.
 *   2. Add a case in build() and an option in the settings dropdown.
 * No other code changes.
 */
final class ProviderFactory {

	/**
	 * @param array<string,mixed> $settings Plugin settings (provider id + creds).
	 */
	public static function fromSettings( array $settings, ?HttpClient $http = null ): AccessPointProvider {
		$http     = $http ?? new WpHttpClient();
		$provider = (string) ( $settings['provider'] ?? 'mock' );

		switch ( $provider ) {
			case 'storecove':
				return new StorecoveProvider(
					$http,
					(string) ( $settings['storecove_api_key'] ?? '' ),
					(string) ( $settings['storecove_legal_entity_id'] ?? '' ),
					(string) ( $settings['storecove_base_url'] ?? 'https://api.storecove.com/api/v2' )
				);

			case 'ksef-direct':
				return new KsefProvider(
					$http,
					(string) ( $settings['ksef_token'] ?? '' ),
					(string) ( $settings['seller_nip'] ?? '' ),
					(string) ( $settings['ksef_base_url'] ?? 'https://api-test.ksef.mf.gov.pl/api/v2' )
				);

			case 'mock':
			default:
				return new MockProvider();
		}
	}

	/**
	 * Provider choices for the settings dropdown.
	 *
	 * @return array<string,string>
	 */
	public static function choices(): array {
		return array(
			'mock'        => 'Mock (sandbox, no network)',
			'storecove'   => 'Storecove',
			'ksef-direct' => 'Poland KSeF (direct, no intermediary)',
		);
	}
}
