<?php
/**
 * Handles connection to the BNPL API.
 *
 * @package flo-checkout
 */

namespace Flo_Checkout\Gateways\BNPL;

use Flo_Checkout\Gateways\BNPL\Models\BNPL_Transaction;
use Flo_Checkout\Shared;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Abstracts\Hub_API\Abstract_API_Base;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Helpers\General_Helpers;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Loggers\Log_Level_Enum;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Traits\Singleton_Trait;

/**
 * Class BNPL_API
 */
class BNPL_API extends Abstract_API_Base {
	use Singleton_Trait;

	/**
	 * BNPL_API constructor.
	 */
	protected function __construct() {
		parent::__construct(
			General_Helpers::ensure_trailing_slash( BNPL_Settings::get( 'api_url' ) ),
			BNPL_Settings::get( 'api_user' ),
			BNPL_Settings::get( 'api_pass' ),
		);
	}

	/**
	 * Create a new transaction.
	 *
	 * @param float  $order_total The total sum for the order for which the transaction is created.
	 * @param string $note       A note to be added to the transaction.
	 *
	 * @return BNPL_Transaction|false Returns the transaction or false on failure.
	 */
	public function create_transaction( float $order_total, string $note = '' ): false|BNPL_Transaction {
		$body = wp_json_encode(
			array(
				'amountWithTax' => $order_total,
				'note'          => $note,
			)
		);

		if ( ! $body ) {
			BNPL_Settings::log( 'Could not build transaction request body', array( 'order_total' => $order_total ), Log_Level_Enum::ERROR );
			return false;
		}

		$response = $this->request_array( 'POST', 'create', $body );

		return $response ? new BNPL_Transaction( $response ) : false;
	}

	/**
	 * Get transaction details.
	 *
	 * @param string $transaction_id The ID of the transaction.
	 *
	 * @return BNPL_Transaction|false The transaction object if successful, false otherwise.
	 */
	public function get_transaction( string $transaction_id ): false|BNPL_Transaction {
		$response = $this->request_array( 'GET', $transaction_id );

		return $response ? new BNPL_Transaction( $response ) : false;
	}

	/**
	 * Cancel a transaction.
	 *
	 * @param string $transaction_id The ID of the transaction to be cancelled.
	 *
	 * @return bool Returns true if the transaction is successfully cancelled, false otherwise.
	 */
	public function cancel_transaction( string $transaction_id ): bool {
		return (bool) $this->request( 'POST', $transaction_id . '/cancel' );
	}

	/**
	 * Refund a transaction.
	 *
	 * @param string $transaction_id The ID of the transaction to refund.
	 *
	 * @return bool True if the refund request was successful, false otherwise.
	 */
	public function refund_transaction( string $transaction_id ): bool {
		return (bool) $this->request( 'POST', $transaction_id . '/refund' );
	}

	/**
	 * Get the default API version.
	 *
	 * @return string The default API version.
	 */
	protected function get_default_api_version(): string {
		return 'v1';
	}

	/**
	 * Build the request URL.
	 *
	 * @param string $version  The API version to use.
	 * @param string $endpoint The specific endpoint of the API to be accessed.
	 *
	 * @return string The full URL constructed for the API request.
	 */
	protected function build_request_url( string $version, string $endpoint ): string {
		return sprintf( '%sapi/%scheckout/bnpl/%s', $this->url, $version, $endpoint );
	}
}
