<?php
/**
 * PaymentsApi
 * PHP version 8.1
 *
 * @category Class
 * @package  Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */

/**
 * Simply.in API
 *
 * Swagger documentation for SIMPLY.IN
 *
 * The version of the OpenAPI document: 1.99.21 (preprod)
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.14.0
 */

/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

namespace Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\ApiException;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Configuration;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\FormDataProcessor;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\HeaderSelector;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\ObjectSerializer;

/**
 * PaymentsApi Class Doc Comment
 *
 * @category Class
 * @package  Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */
class PaymentsApi {

	/**
	 * @var ClientInterface
	 */
	protected $client;

	/**
	 * @var Configuration
	 */
	protected $config;

	/**
	 * @var HeaderSelector
	 */
	protected $headerSelector;

	/**
	 * @var int Host index
	 */
	protected $hostIndex;

	/** @var string[] $contentTypes * */
	public const contentTypes = [
		'paymentsGetAvailablePaymentMethods' => [
			'application/json',
		],
		'paymentsGetPaymentStatus'           => [
			'application/json',
		],
		'paymentsPay'                        => [
			'application/json',
		],
	];

	/**
	 * @param ClientInterface $client
	 * @param Configuration $config
	 * @param HeaderSelector $selector
	 * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec
	 */
	public function __construct(
		?ClientInterface $client = null,
		?Configuration $config = null,
		?HeaderSelector $selector = null,
		int $hostIndex = 0
	) {
		$this->client         = $client ?: new Client();
		$this->config         = $config ?: Configuration::getDefaultConfiguration();
		$this->headerSelector = $selector ?: new HeaderSelector();
		$this->hostIndex      = $hostIndex;
	}

	/**
	 * Set the host index
	 *
	 * @param int $hostIndex Host index (required)
	 */
	public function setHostIndex( $hostIndex ): void {
		$this->hostIndex = $hostIndex;
	}

	/**
	 * Get the host index
	 *
	 * @return int Host index
	 */
	public function getHostIndex() {
		return $this->hostIndex;
	}

	/**
	 * @return Configuration
	 */
	public function getConfig() {
		return $this->config;
	}

	/**
	 * Operation paymentsGetAvailablePaymentMethods
	 *
	 * Get available payment methods for merchant &amp; user using Sin.Token service
	 *
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetAvailablePaymentMethods'] to see the possible values for this operation
	 *
	 * @return \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethods200ResponseInner[]|\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\InlineObject
	 * @throws \InvalidArgumentException
	 * @throws \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\ApiException on non-2xx response or if the response body is not in the expected format
	 */
	public function paymentsGetAvailablePaymentMethods(
		string $contentType = self::contentTypes['paymentsGetAvailablePaymentMethods'][0]
	) {
		[ $response ] = $this->paymentsGetAvailablePaymentMethodsWithHttpInfo( $contentType );

		return $response;
	}

	/**
	 * Operation paymentsGetAvailablePaymentMethodsWithHttpInfo
	 *
	 * Get available payment methods for merchant &amp; user using Sin.Token service
	 *
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetAvailablePaymentMethods'] to see the possible values for this operation
	 *
	 * @return array of \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethods200ResponseInner[]|\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\InlineObject, HTTP status code, HTTP response headers (array of strings)
	 * @throws \InvalidArgumentException
	 * @throws \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\ApiException on non-2xx response or if the response body is not in the expected format
	 */
	public function paymentsGetAvailablePaymentMethodsWithHttpInfo(
		string $contentType = self::contentTypes['paymentsGetAvailablePaymentMethods'][0]
	) {
		$request = $this->paymentsGetAvailablePaymentMethodsRequest( $contentType );

		if ( $this->config->getDebug() ) {
			ob_start();
		}
		try {
			$options = $this->createHttpClientOption();
			try {
				$response = $this->client->send( $request, $options );
			} catch ( RequestException $e ) {
				throw new ApiException(
					"[{$e->getCode()}] {$e->getMessage()}",
					(int) $e->getCode(),
					$e->getResponse() ? $e->getResponse()->getHeaders() : null,
					$e->getResponse() ? (string) $e->getResponse()
					                               ->getBody() : null
				);
			} catch ( ConnectException $e ) {
				throw new ApiException(
					"[{$e->getCode()}] {$e->getMessage()}",
					(int) $e->getCode(),
					null,
					null
				);
			}

			$statusCode = $response->getStatusCode();


			switch ( $statusCode ) {
				case 200:
					return $this->handleResponseWithDataType(
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethods200ResponseInner[]',
						$request,
						$response,
					);
				default:
					return $this->handleResponseWithDataType(
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\InlineObject',
						$request,
						$response,
					);
			}


			if ( $statusCode < 200 || $statusCode > 299 ) {
				throw new ApiException(
					sprintf(
						'[%d] Error connecting to the API (%s)',
						$statusCode,
						(string) $request->getUri()
					),
					$statusCode,
					$response->getHeaders(),
					(string) $response->getBody()
				);
			}

			return $this->handleResponseWithDataType(
				'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethods200ResponseInner[]',
				$request,
				$response,
			);
		} catch ( ApiException $e ) {
			switch ( $e->getCode() ) {
				case 200:
					$data = ObjectSerializer::deserialize(
						$e->getResponseBody(),
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethods200ResponseInner[]',
						$e->getResponseHeaders()
					);
					$e->setResponseObject( $data );
					throw $e;
				default:
					$data = ObjectSerializer::deserialize(
						$e->getResponseBody(),
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\InlineObject',
						$e->getResponseHeaders()
					);
					$e->setResponseObject( $data );
					throw $e;
			}


			throw $e;
		} finally {
			if ( $this->config->getDebug() ) {
				$this->logDebugOutput( ob_get_clean() );
			}
		}
	}

	/**
	 * Operation paymentsGetAvailablePaymentMethodsAsync
	 *
	 * Get available payment methods for merchant &amp; user using Sin.Token service
	 *
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetAvailablePaymentMethods'] to see the possible values for this operation
	 *
	 * @return \GuzzleHttp\Promise\PromiseInterface
	 * @throws \InvalidArgumentException
	 */
	public function paymentsGetAvailablePaymentMethodsAsync(
		string $contentType = self::contentTypes['paymentsGetAvailablePaymentMethods'][0]
	) {
		return $this->paymentsGetAvailablePaymentMethodsAsyncWithHttpInfo( $contentType )
		            ->then(
			            function ( $response ) {
				            return $response[0];
			            }
		            );
	}

	/**
	 * Operation paymentsGetAvailablePaymentMethodsAsyncWithHttpInfo
	 *
	 * Get available payment methods for merchant &amp; user using Sin.Token service
	 *
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetAvailablePaymentMethods'] to see the possible values for this operation
	 *
	 * @return \GuzzleHttp\Promise\PromiseInterface
	 * @throws \InvalidArgumentException
	 */
	public function paymentsGetAvailablePaymentMethodsAsyncWithHttpInfo(
		string $contentType = self::contentTypes['paymentsGetAvailablePaymentMethods'][0]
	) {
		$returnType = '\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethods200ResponseInner[]';
		$request    = $this->paymentsGetAvailablePaymentMethodsRequest( $contentType );

		return $this->client
			->sendAsync( $request, $this->createHttpClientOption() )
			->then(
				function ( $response ) use ( $returnType ) {
					if ( $returnType === '\SplFileObject' ) {
						$content = $response->getBody(); //stream goes to serializer
					} else {
						$content = (string) $response->getBody();
						if ( $returnType !== 'string' ) {
							$content = json_decode( $content );
						}
					}

					return [
						ObjectSerializer::deserialize( $content,
							$returnType,
							[] ),
						$response->getStatusCode(),
						$response->getHeaders(),
					];
				},
				function ( $exception ) {
					$response   = $exception->getResponse();
					$statusCode = $response->getStatusCode();
					throw new ApiException(
						esc_html( sprintf(
							'[%d] Error connecting to the API (%s)',
							$statusCode,
							$exception->getRequest()->getUri()
						) ),
						esc_html( $statusCode ),
						esc_html( $response->getHeaders() ),
						esc_html( (string) $response->getBody() )
					);
				}
			);
	}

	/**
	 * Create request for operation 'paymentsGetAvailablePaymentMethods'
	 *
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetAvailablePaymentMethods'] to see the possible values for this operation
	 *
	 * @return \GuzzleHttp\Psr7\Request
	 * @throws \InvalidArgumentException
	 */
	public function paymentsGetAvailablePaymentMethodsRequest(
		string $contentType = self::contentTypes['paymentsGetAvailablePaymentMethods'][0]
	) {


		$resourcePath = '/payments/getAvailablePaymentMethods';
		$formParams   = [];
		$queryParams  = [];
		$headerParams = [];
		$httpBody     = '';
		$multipart    = false;


		$headers = $this->headerSelector->selectHeaders(
			[ 'application/json', ],
			$contentType,
			$multipart
		);

		// for model (json/xml)
		if ( count( $formParams ) > 0 ) {
			if ( $multipart ) {
				$multipartContents = [];
				foreach ( $formParams as $formParamName => $formParamValue ) {
					$formParamValueItems = is_array( $formParamValue ) ? $formParamValue : [ $formParamValue ];
					foreach ( $formParamValueItems as $formParamValueItem ) {
						$multipartContents[] = [
							'name'     => $formParamName,
							'contents' => $formParamValueItem,
						];
					}
				}
				// for HTTP post (form)
				$httpBody = new MultipartStream( $multipartContents );

			} elseif ( stripos( $headers['Content-Type'],
					'application/json' ) !== false ) {
				# if Content-Type contains "application/json", json_encode the form parameters
				$httpBody = \GuzzleHttp\Utils::jsonEncode( $formParams );
			} else {
				// for HTTP post (form)
				$httpBody = ObjectSerializer::buildQuery( $formParams );
			}
		}

		// this endpoint requires API key authentication
		$apiKey = $this->config->getApiKeyWithPrefix( 'api_token' );
		if ( $apiKey !== null ) {
			$queryParams['api_token'] = $apiKey;
		}

		// language header per docs: lng: 'PL' | 'EN'
		$wpLocale            = function_exists( 'get_locale' ) ? get_locale() : 'en_US';
		$headerParams['lng'] = ( stripos( $wpLocale,
				'pl' ) === 0 ) ? 'PL' : 'EN';


		// this endpoint requires API key authentication
		$apiKey = $this->config->getApiKeyWithPrefix( 'X-Auth-Merchant-Api-Key' );
		if ( $apiKey !== null ) {
			$headers['X-Auth-Merchant-Api-Key'] = $apiKey;
		}

		$defaultHeaders = [];
		if ( $this->config->getUserAgent() ) {
			$defaultHeaders['User-Agent'] = $this->config->getUserAgent();
			$defaultHeaders['Origin']     = home_url();
		}

		$headers = array_merge(
			$defaultHeaders,
			$headerParams,
			$headers
		);

		$operationHost = $this->config->getHost();
		$query         = ObjectSerializer::buildQuery( $queryParams );

		return new Request(
			'GET',
			$operationHost . $resourcePath . ( $query ? "?{$query}" : '' ),
			$headers,
			$httpBody
		);
	}

	/**
	 * Operation paymentsPay
	 *
	 * Initiate a payment using Sin.Token service
	 *
	 * @param \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPayRequest $payments_pay_request payments_pay_request (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsPay'] to see the possible values for this operation
	 *
	 * @return \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPay200Response|\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\InlineObject
	 * @throws \InvalidArgumentException
	 * @throws \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\ApiException on non-2xx response or if the response body is not in the expected format
	 */
	public function paymentsPay(
		$payments_pay_request,
		string $contentType = self::contentTypes['paymentsPay'][0]
	) {
		[ $response ] = $this->paymentsPayWithHttpInfo( $payments_pay_request,
			$contentType );

		return $response;
	}

	/**
	 * Operation paymentsPayWithHttpInfo
	 *
	 * Initiate a payment using Sin.Token service
	 *
	 * @param \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPayRequest $payments_pay_request (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsPay'] to see the possible values for this operation
	 *
	 * @return array of \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPay200Response|\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\InlineObject, HTTP status code, HTTP response headers (array of strings)
	 * @throws \InvalidArgumentException
	 * @throws \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\ApiException on non-2xx response or if the response body is not in the expected format
	 */
	public function paymentsPayWithHttpInfo(
		$payments_pay_request,
		string $contentType = self::contentTypes['paymentsPay'][0]
	) {
		$request = $this->paymentsPayRequest( $payments_pay_request,
			$contentType );

		if ( $this->config->getDebug() ) {
			ob_start();
		}
		try {
			$options = $this->createHttpClientOption();
			try {
				$response = $this->client->send( $request, $options );
			} catch ( RequestException $e ) {
				throw new ApiException(
					"[{$e->getCode()}] {$e->getMessage()}",
					(int) $e->getCode(),
					$e->getResponse() ? $e->getResponse()->getHeaders() : null,
					$e->getResponse() ? (string) $e->getResponse()
					                               ->getBody() : null
				);
			} catch ( ConnectException $e ) {
				throw new ApiException(
					"[{$e->getCode()}] {$e->getMessage()}",
					(int) $e->getCode(),
					null,
					null
				);
			}

			$statusCode = $response->getStatusCode();


			switch ( $statusCode ) {
				case 200:
					return $this->handleResponseWithDataType(
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPay200Response',
						$request,
						$response,
					);
				default:
					return $this->handleResponseWithDataType(
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\InlineObject',
						$request,
						$response,
					);
			}


			if ( $statusCode < 200 || $statusCode > 299 ) {
				throw new ApiException(
					sprintf(
						'[%d] Error connecting to the API (%s)',
						$statusCode,
						(string) $request->getUri()
					),
					$statusCode,
					$response->getHeaders(),
					(string) $response->getBody()
				);
			}

			return $this->handleResponseWithDataType(
				'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPay200Response',
				$request,
				$response,
			);
		} catch ( ApiException $e ) {
			switch ( $e->getCode() ) {
				case 200:
					$data = ObjectSerializer::deserialize(
						$e->getResponseBody(),
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPay200Response',
						$e->getResponseHeaders()
					);
					$e->setResponseObject( $data );
					throw $e;
				default:
					$data = ObjectSerializer::deserialize(
						$e->getResponseBody(),
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\InlineObject',
						$e->getResponseHeaders()
					);
					$e->setResponseObject( $data );
					throw $e;
			}


			throw $e;
		} finally {
			if ( $this->config->getDebug() ) {
				$this->logDebugOutput( ob_get_clean() );
			}
		}
	}

	/**
	 * Operation paymentsPayAsync
	 *
	 * Initiate a payment using Sin.Token service
	 *
	 * @param \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPayRequest $payments_pay_request (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsPay'] to see the possible values for this operation
	 *
	 * @return \GuzzleHttp\Promise\PromiseInterface
	 * @throws \InvalidArgumentException
	 */
	public function paymentsPayAsync(
		$payments_pay_request,
		string $contentType = self::contentTypes['paymentsPay'][0]
	) {
		return $this->paymentsPayAsyncWithHttpInfo( $payments_pay_request,
			$contentType )
		            ->then(
			            function ( $response ) {
				            return $response[0];
			            }
		            );
	}

	/**
	 * Operation paymentsPayAsyncWithHttpInfo
	 *
	 * Initiate a payment using Sin.Token service
	 *
	 * @param \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPayRequest $payments_pay_request (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsPay'] to see the possible values for this operation
	 *
	 * @return \GuzzleHttp\Promise\PromiseInterface
	 * @throws \InvalidArgumentException
	 */
	public function paymentsPayAsyncWithHttpInfo(
		$payments_pay_request,
		string $contentType = self::contentTypes['paymentsPay'][0]
	) {
		$returnType = '\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPay200Response';
		$request    = $this->paymentsPayRequest( $payments_pay_request,
			$contentType );

		return $this->client
			->sendAsync( $request, $this->createHttpClientOption() )
			->then(
				function ( $response ) use ( $returnType ) {
					if ( $returnType === '\SplFileObject' ) {
						$content = $response->getBody(); //stream goes to serializer
					} else {
						$content = (string) $response->getBody();
						if ( $returnType !== 'string' ) {
							$content = json_decode( $content );
						}
					}

					return [
						ObjectSerializer::deserialize( $content,
							$returnType,
							[] ),
						$response->getStatusCode(),
						$response->getHeaders(),
					];
				},
				function ( $exception ) {
					$response   = $exception->getResponse();
					$statusCode = $response->getStatusCode();
					throw new ApiException(
						esc_html( sprintf(
							'[%d] Error connecting to the API (%s)',
							$statusCode,
							$exception->getRequest()->getUri()
						) ),
						esc_html( $statusCode ),
						esc_html( $response->getHeaders() ),
						esc_html( (string) $response->getBody() )
					);
				}
			);
	}

	/**
	 * Create request for operation 'paymentsPay'
	 *
	 * @param \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPayRequest $payments_pay_request (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsPay'] to see the possible values for this operation
	 *
	 * @return \GuzzleHttp\Psr7\Request
	 * @throws \InvalidArgumentException
	 */
	public function paymentsPayRequest(
		$payments_pay_request,
		string $contentType = self::contentTypes['paymentsPay'][0]
	) {

		// verify the required parameter 'payments_pay_request' is set
		if ( $payments_pay_request === null || ( is_array( $payments_pay_request ) && count( $payments_pay_request ) === 0 ) ) {
			throw new \InvalidArgumentException(
				'Missing the required parameter $payments_pay_request when calling paymentsPay'
			);
		}


		$resourcePath = '/payments/pay';
		$formParams   = [];
		$queryParams  = [];
		$headerParams = [];
		$httpBody     = '';
		$multipart    = false;


		$headers = $this->headerSelector->selectHeaders(
			[ 'application/json', ],
			$contentType,
			$multipart
		);

		// for model (json/xml)
		if ( isset( $payments_pay_request ) ) {
			if ( stripos( $headers['Content-Type'],
					'application/json' ) !== false ) {
				# if Content-Type contains "application/json", json_encode the body
				$httpBody = \GuzzleHttp\Utils::jsonEncode( ObjectSerializer::sanitizeForSerialization( $payments_pay_request ) );
			} else {
				$httpBody = $payments_pay_request;
			}
		} elseif ( count( $formParams ) > 0 ) {
			if ( $multipart ) {
				$multipartContents = [];
				foreach ( $formParams as $formParamName => $formParamValue ) {
					$formParamValueItems = is_array( $formParamValue ) ? $formParamValue : [ $formParamValue ];
					foreach ( $formParamValueItems as $formParamValueItem ) {
						$multipartContents[] = [
							'name'     => $formParamName,
							'contents' => $formParamValueItem,
						];
					}
				}
				// for HTTP post (form)
				$httpBody = new MultipartStream( $multipartContents );

			} elseif ( stripos( $headers['Content-Type'],
					'application/json' ) !== false ) {
				# if Content-Type contains "application/json", json_encode the form parameters
				$httpBody = \GuzzleHttp\Utils::jsonEncode( $formParams );
			} else {
				// for HTTP post (form)
				$httpBody = ObjectSerializer::buildQuery( $formParams );
			}
		}

		// this endpoint requires API key authentication
		$apiKey = $this->config->getApiKeyWithPrefix( 'api_token' );
		if ( $apiKey !== null && $apiKey !== '' ) {
			$queryParams['api_token'] = $apiKey;
		}


		//simplyin_use_session_api_token_for_pay -------------Can we remove it?

		/*$simplyin_auth_token = ( new Simplyin_Session() )->get( 'simplyin_auth_token' );

		$useSessionToken = filter_var(get_option('simplyin_use_session_api_token_for_pay', 'yes'), FILTER_VALIDATE_BOOLEAN);
		if ($useSessionToken && !empty($simplyin_auth_token)){
			$queryParams['api_token'] = $simplyin_auth_token;
		}*/

		// language header per docs: lng: 'PL' | 'EN'
		$wpLocale            = function_exists( 'get_locale' ) ? get_locale() : 'en_US';
		$headerParams['lng'] = ( stripos( $wpLocale,
				'pl' ) === 0 ) ? 'PL' : 'EN';

		// this endpoint requires API key authentication
		$apiKey = $this->config->getApiKeyWithPrefix( 'X-Auth-Merchant-Api-Key' );
		if ( $apiKey !== null ) {
			$headers['X-Auth-Merchant-Api-Key'] = $apiKey;
		}

		$defaultHeaders = [];
		if ( $this->config->getUserAgent() ) {
			$defaultHeaders['User-Agent'] = $this->config->getUserAgent();
		}


		$defaultHeaders['Origin'] = home_url();


		$headers = array_merge(
			$defaultHeaders,
			$headerParams,
			$headers
		);

		$operationHost = $this->config->getHost();
		$query         = ObjectSerializer::buildQuery( $queryParams );

		return new Request(
			'POST',
			$operationHost . $resourcePath . ( $query ? "?{$query}" : '' ),
			$headers,
			$httpBody
		);
	}


	/**
	 * Operation paymentsGetPaymentStatus
	 *
	 * Get payment status from Sin.Token service
	 *
	 * @param string $payment_id payment_id (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetPaymentStatus'] to see the possible values for this operation
	 *
	 * @return \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetPaymentStatus200Response|\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethodsDefaultResponse
	 * @throws \InvalidArgumentException
	 * @throws \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\ApiException on non-2xx response or if the response body is not in the expected format
	 */
	public function paymentsGetPaymentStatus(
		$payment_id,
		string $contentType = self::contentTypes['paymentsGetPaymentStatus'][0]
	) {
		[ $response ] = $this->paymentsGetPaymentStatusWithHttpInfo( $payment_id,
			$contentType );

		return $response;
	}

	/**
	 * Operation paymentsGetPaymentStatusWithHttpInfo
	 *
	 * Get payment status from Sin.Token service
	 *
	 * @param string $payment_id (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetPaymentStatus'] to see the possible values for this operation
	 *
	 * @return array of \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetPaymentStatus200Response|\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethodsDefaultResponse, HTTP status code, HTTP response headers (array of strings)
	 * @throws \InvalidArgumentException
	 * @throws \Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\ApiException on non-2xx response or if the response body is not in the expected format
	 */
	public function paymentsGetPaymentStatusWithHttpInfo(
		$payment_id,
		string $contentType = self::contentTypes['paymentsGetPaymentStatus'][0]
	) {
		$request = $this->paymentsGetPaymentStatusRequest( $payment_id,
			$contentType );

		try {
			$options = $this->createHttpClientOption();
			try {
				$response = $this->client->send( $request, $options );
			} catch ( RequestException $e ) {
				throw new ApiException(
					"[{$e->getCode()}] {$e->getMessage()}",
					(int) $e->getCode(),
					$e->getResponse() ? $e->getResponse()->getHeaders() : null,
					$e->getResponse() ? (string) $e->getResponse()
					                               ->getBody() : null
				);
			} catch ( ConnectException $e ) {
				throw new ApiException(
					"[{$e->getCode()}] {$e->getMessage()}",
					(int) $e->getCode(),
					null,
					null
				);
			}

			$statusCode = $response->getStatusCode();


			switch ( $statusCode ) {
				case 200:
					return $this->handleResponseWithDataType(
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetPaymentStatus200Response',
						$request,
						$response,
					);
				default:
					return $this->handleResponseWithDataType(
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethodsDefaultResponse',
						$request,
						$response,
					);
			}


			if ( $statusCode < 200 || $statusCode > 299 ) {
				throw new ApiException(
					sprintf(
						'[%d] Error connecting to the API (%s)',
						$statusCode,
						(string) $request->getUri()
					),
					$statusCode,
					$response->getHeaders(),
					(string) $response->getBody()
				);
			}

			return $this->handleResponseWithDataType(
				'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetPaymentStatus200Response',
				$request,
				$response,
			);
		} catch ( ApiException $e ) {
			switch ( $e->getCode() ) {
				case 200:
					$data = ObjectSerializer::deserialize(
						$e->getResponseBody(),
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetPaymentStatus200Response',
						$e->getResponseHeaders()
					);
					$e->setResponseObject( $data );
					throw $e;
				default:
					$data = ObjectSerializer::deserialize(
						$e->getResponseBody(),
						'\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetAvailablePaymentMethodsDefaultResponse',
						$e->getResponseHeaders()
					);
					$e->setResponseObject( $data );
					throw $e;
			}


			throw $e;
		}
	}

	/**
	 * Operation paymentsGetPaymentStatusAsync
	 *
	 * Get payment status from Sin.Token service
	 *
	 * @param string $payment_id (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetPaymentStatus'] to see the possible values for this operation
	 *
	 * @return \GuzzleHttp\Promise\PromiseInterface
	 * @throws \InvalidArgumentException
	 */
	public function paymentsGetPaymentStatusAsync(
		$payment_id,
		string $contentType = self::contentTypes['paymentsGetPaymentStatus'][0]
	) {
		return $this->paymentsGetPaymentStatusAsyncWithHttpInfo( $payment_id,
			$contentType )
		            ->then(
			            function ( $response ) {
				            return $response[0];
			            }
		            );
	}

	/**
	 * Operation paymentsGetPaymentStatusAsyncWithHttpInfo
	 *
	 * Get payment status from Sin.Token service
	 *
	 * @param string $payment_id (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetPaymentStatus'] to see the possible values for this operation
	 *
	 * @return \GuzzleHttp\Promise\PromiseInterface
	 * @throws \InvalidArgumentException
	 */
	public function paymentsGetPaymentStatusAsyncWithHttpInfo(
		$payment_id,
		string $contentType = self::contentTypes['paymentsGetPaymentStatus'][0]
	) {
		$returnType = '\Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsGetPaymentStatus200Response';
		$request    = $this->paymentsGetPaymentStatusRequest( $payment_id,
			$contentType );

		return $this->client
			->sendAsync( $request, $this->createHttpClientOption() )
			->then(
				function ( $response ) use ( $returnType ) {
					if ( $returnType === '\SplFileObject' ) {
						$content = $response->getBody(); //stream goes to serializer
					} else {
						$content = (string) $response->getBody();
						if ( $returnType !== 'string' ) {
							$content = json_decode( $content );
						}
					}

					return [
						ObjectSerializer::deserialize( $content,
							$returnType,
							[] ),
						$response->getStatusCode(),
						$response->getHeaders(),
					];
				},
				function ( $exception ) {
					$response   = $exception->getResponse();
					$statusCode = $response->getStatusCode();
					throw new ApiException(
						sprintf(
							'[%d] Error connecting to the API (%s)',
							esc_html( $statusCode ),
							esc_url( $exception->getRequest()->getUri() )
						),
						esc_html( $statusCode ),
						[],
						esc_html( $response->getBody() )
					);
				}
			);
	}

	/**
	 * Create request for operation 'paymentsGetPaymentStatus'
	 *
	 * @param string $payment_id (required)
	 * @param string $contentType The value for the Content-Type header. Check self::contentTypes['paymentsGetPaymentStatus'] to see the possible values for this operation
	 *
	 * @return \GuzzleHttp\Psr7\Request
	 * @throws \InvalidArgumentException
	 */
	public function paymentsGetPaymentStatusRequest(
		$payment_id,
		string $contentType = self::contentTypes['paymentsGetPaymentStatus'][0]
	) {

		// verify the required parameter 'payment_id' is set
		if ( $payment_id === null || ( is_array( $payment_id ) && count( $payment_id ) === 0 ) ) {
			throw new \InvalidArgumentException(
				'Missing the required parameter $payment_id when calling paymentsGetPaymentStatus'
			);
		}


		$resourcePath = '/payments/getPaymentStatus';
		$formParams   = [];
		$queryParams  = [];
		$headerParams = [];
		$httpBody     = '';
		$multipart    = false;

		// query params
		$queryParams = array_merge( $queryParams,
			ObjectSerializer::toQueryValue(
				$payment_id,
				'paymentId', // param base name
				'string', // openApiType
				'form', // style
				true, // explode
				true // required
			) ?? [] );


		$headers = $this->headerSelector->selectHeaders(
			[ 'application/json', ],
			$contentType,
			$multipart
		);

		// for model (json/xml)
		if ( count( $formParams ) > 0 ) {
			if ( $multipart ) {
				$multipartContents = [];
				foreach ( $formParams as $formParamName => $formParamValue ) {
					$formParamValueItems = is_array( $formParamValue ) ? $formParamValue : [ $formParamValue ];
					foreach ( $formParamValueItems as $formParamValueItem ) {
						$multipartContents[] = [
							'name'     => $formParamName,
							'contents' => $formParamValueItem,
						];
					}
				}
				// for HTTP post (form)
				$httpBody = new MultipartStream( $multipartContents );

			} elseif ( stripos( $headers['Content-Type'],
					'application/json' ) !== false ) {
				# if Content-Type contains "application/json", json_encode the form parameters
				$httpBody = \GuzzleHttp\Utils::jsonEncode( $formParams );
			} else {
				// for HTTP post (form)
				$httpBody = ObjectSerializer::buildQuery( $formParams );
			}
		}

		// this endpoint requires API key authentication
		$apiKey = $this->config->getApiKeyWithPrefix( 'api_token' );
		if ( $apiKey !== null ) {
			$queryParams['api_token'] = $apiKey;
		}
		// this endpoint requires API key authentication
		$apiKey = $this->config->getApiKeyWithPrefix( 'X-Auth-Merchant-Api-Key' );
		if ( $apiKey !== null ) {
			$headers['X-Auth-Merchant-Api-Key'] = $apiKey;
		}

		$defaultHeaders = [];

		if ( $this->config->getUserAgent() ) {
			$defaultHeaders['User-Agent'] = $this->config->getUserAgent();
			$defaultHeaders['Origin']     = home_url();
		}

		if ( $this->config->getUserAgent() ) {
			$defaultHeaders['User-Agent'] = $this->config->getUserAgent();
		}

		$headers = array_merge(
			$defaultHeaders,
			$headerParams,
			$headers
		);

		$operationHost = $this->config->getHost();
		$query         = ObjectSerializer::buildQuery( $queryParams );

		return new Request(
			'GET',
			$operationHost . $resourcePath . ( $query ? "?{$query}" : '' ),
			$headers,
			$httpBody
		);
	}

	/**
	 * Create http client option
	 *
	 * @return array of http client options
	 */
	protected function createHttpClientOption() {
		$options = [
			RequestOptions::TIMEOUT         => 15,
			RequestOptions::CONNECT_TIMEOUT => 5,
		];
		if ( $this->config->getDebug() ) {
			$options[ RequestOptions::DEBUG ] = true;
		}

		return $options;
	}

	private function handleResponseWithDataType(
		string $dataType,
		RequestInterface $request,
		ResponseInterface $response
	): array {
		if ( $dataType === '\SplFileObject' ) {
			$content = $response->getBody(); //stream goes to serializer
		} else {
			$content = (string) $response->getBody();
			if ( $dataType !== 'string' ) {
				try {
					$content = json_decode( $content,
						false,
						512,
						JSON_THROW_ON_ERROR );
				} catch ( \JsonException $exception ) {
					throw new ApiException(
						esc_html( sprintf(
							'Error JSON decoding server response (%s)',
							$request->getUri()
						) ),
						esc_html( $response->getStatusCode() ),
						esc_html( $response->getHeaders() ),
						esc_html( $content )
					);
				}
			}
		}

		return [
			ObjectSerializer::deserialize( $content, $dataType, [] ),
			$response->getStatusCode(),
			$response->getHeaders(),
		];
	}

	private function responseWithinRangeCode(
		string $rangeCode,
		int $statusCode
	): bool {
		$left  = (int) ( $rangeCode[0] . '00' );
		$right = (int) ( $rangeCode[0] . '99' );

		return $statusCode >= $left && $statusCode <= $right;
	}

	private function logDebugOutput( string $output ): void {
		if ( ! $output ) {
			return;
		}
	}
}
