<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

declare(strict_types=1);

namespace SimplyIn\Api;

use Configuration;
use Context;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Psr7\HttpFactory;
use Simplyin;
use SimplyIn\Auth\RsaRegistrar;
use SimplyIn\Auth\RsaSigner;

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

final class SimplyInApiClientFactory
{
    public static function create(
        string $baseUrl,
        string $merchantApiKey,
        string $origin,
        ?ApiRequestContext $defaultContext = null,
        float $timeoutSeconds = 30.0,
        float $connectTimeoutSeconds = 10.0,
        ?RsaSigner $rsaSigner = null,
        ?RsaRegistrar $rsaRegistrar = null,
    ): SimplyInApiClient {
        $guzzle = new GuzzleClient([
            'timeout' => $timeoutSeconds,
            'connect_timeout' => $connectTimeoutSeconds,
            'verify' => true,
            'http_errors' => false,
        ]);

        $psr17 = new HttpFactory();

        return new SimplyInApiClient(
            httpClient: $guzzle,
            requestFactory: $psr17,
            streamFactory: $psr17,
            baseUrl: $baseUrl,
            merchantApiKey: $merchantApiKey,
            origin: $origin,
            defaultContext: $defaultContext,
            rsaSigner: $rsaSigner,
            rsaRegistrar: $rsaRegistrar,
        );
    }

    public static function fromPrestaShop(
        Simplyin $module,
        Context $context,
        ?string $merchantApiKeyOverride = null,
        ?RsaSigner $rsaSigner = null,
        ?RsaRegistrar $rsaRegistrar = null,
    ): SimplyInApiClient {
        // Both the base URL and the API key now come from state ModuleBootstrap resolves (selected
        // environment -> backend URL, and that environment's own key slot). A module instance that
        // has not bootstrapped yet would otherwise silently yield a client pointed at "/" with no
        // key, so resolve it properly instead of shipping a broken client. This cannot recurse:
        // bootstrap() applies the environment before it builds any client.
        if ($module->environment === null) {
            $module->loadObjects();
        }

        $apiKey = $merchantApiKeyOverride ?? $module->merchantApiKey;
        $origin = (string) $context->shop->getBaseURL(true);

        // Default to the module's shared signer/registrar so EVERY call site (not just the ones that
        // pass them explicitly) uses RSA once registered. Skipped when an override API key is given:
        // testing a new key must authenticate with THAT key, not a stale RSA credential.
        $hasOverride = $merchantApiKeyOverride !== null && $merchantApiKeyOverride !== '';
        if (!$hasOverride) {
            $rsaSigner ??= $module->rsaSigner;
            $rsaRegistrar ??= $module->rsaRegistrar;
        }

        $defaultContext = new ApiRequestContext(
            pluginVersion: (string) $module->version,
            shopName: (string) Configuration::get('PS_SHOP_NAME'),
            shopVersion: (string) Configuration::get('PS_VERSION_DB'),
            languageIsoCode: (string) $context->language->iso_code,
        );

        return self::create(
            baseUrl: rtrim((string) $module->backend_url, '/') . '/',
            merchantApiKey: $apiKey,
            origin: $origin,
            defaultContext: $defaultContext,
            rsaSigner: $rsaSigner,
            rsaRegistrar: $rsaRegistrar,
        );
    }
}
