<?php

declare(strict_types=1);

namespace ComerciaGlobalPayments\AddonPayments\SDK\Api;

use ComerciaGlobalPayments\AddonPayments\SDK\Encryption\Cypher\Aes256Cbc;
use ComerciaGlobalPayments\AddonPayments\SDK\Request\RequestInterface;
use Symfony\Component\Validator\ConstraintViolationListInterface;

/**
 * Interface ApiClientInterface.
 *
 * Defines an interface for API clients.
 *
 * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
 */
interface ApiClientInterface
{
    public const DEFAULT_ENCRYPTION = Aes256Cbc::NAME;

    public const DEFAULT_LIVE_MODE = false;

    public const BACKOFFICE_LIVE = 'https://backoffice.easypaymentgateway.com/';

    public const BACKOFFICE_STAGING = 'https://backoffice-stg.easypaymentgateway.com/';

    /**
     * Sends an HTTP request to the API.
     *
     * @param string            $method  The HTTP method
     * @param string            $url     Endpoint
     * @param string[]          $headers An array of headers
     * @param array|string|null $payload The payload for the request
     * @param array             $options Extra options to pass to the HTTP client
     *
     * @return \GuzzleHttp\Message\ResponseInterface|\Psr\Http\Message\ResponseInterface The received response
     *
     * @throws \GuzzleHttp\Exception\TransferException
     */
    public function sendRequest(
        string $method,
        string $url,
        array $headers = [],
        $payload = null,
        array $options = []
    );

    /**
     * Generate validity token for transaction-related requests.
     *
     * @param string[] $transactionsIds An array of transactions IDs
     *
     * @throws \InvalidArgumentException Thrown if the transaction IDs are empty
     */
    public function generateTransactionToken(array $transactionsIds): string;

    /**
     * Get encryption method instance.
     *
     * @return \ComerciaGlobalPayments\AddonPayments\SDK\Encryption\Cypher\WithInitializationVectorInterface|\ComerciaGlobalPayments\AddonPayments\SDK\Encryption\Cypher\WithoutInitializationVectorInterface
     */
    public function getEncryption();

    /**
     * Check whereas the client is being used against live API endpoints.
     */
    public function isLive(): bool;

    /**
     * Get allowed encryption methods.
     *
     * @return string[] An array of encryption classes keyed by name
     */
    public static function getAllowedEncryptionMethods(): array;

    /**
     * Get API endpoints.
     *
     * @param bool $live Whereas return live or staging endpoints
     *
     * @return string[] Endpoints keyed by operation
     */
    public static function getEndpoints(bool $live = false): array;

    /**
     * Get endpoint for a given operation.
     *
     * @throws \InvalidArgumentException If the operation does not exists
     */
    public function getEndpoint(string $operation): string;

    /**
     * Validate a given request before sending it.
     */
    public function validate(RequestInterface $request): ConstraintViolationListInterface;

    /**
     * Get configuration default values.
     *
     * @return mixed[]
     */
    public function getDefaultConfiguration(): array;
}
