<?php
/**
 * Response result model.
 *
 * @package flo-checkout
 */

namespace Flo_Checkout\Gateways\Shift4_APM\Responses\Models\Payment;

use Exception;
use Flo_Checkout\Gateways\Apple_Pay\Settings;
use Flo_Checkout\Gateways\Shift4_APM\Responses\Models\Result_Model;
use Flo_Checkout\Gateways\Shift4_Apple_Pay;
use JsonSerializable;

defined( 'ABSPATH' ) || exit;

/**
 * Class Response_Result_Model
 */
class Result_Model_Gateway_Payment extends Result_Model implements JsonSerializable {

	/**
	 * Response code.
	 *
	 * @var ?string
	 */
	protected ?string $response_code;

	/**
	 * The transaction result code description
	 *
	 * @var string
	 */
	protected string $response_description;

	/**
	 * Additional, human readable error description.
	 *
	 * @var string
	 */
	protected string $response_details;

	/**
	 * Processor response code.
	 *
	 * @var string
	 */
	public string $processor_response_code;

	/**
	 * Response_Result_Model constructor.
	 *
	 * @param array $response_body The response data array.
	 */
	public function __construct(
		array $response_body
	) {
		parent::__construct( $response_body );

		// The response code is 3 digits in length, and the first digit can be changed.
		// This is done for Shift4 internal purposes.
		$this->response_code = ! empty( $response_body['result']['response_code'] ) ?
			substr( $response_body['result']['response_code'], -2 ) :
			null;

		$this->response_description    = $response_body['result']['response_description'] ?? '';
		$this->response_details        = $response_body['result']['response_details'] ?? '';
		$this->processor_response_code = $response_body['result']['processor_response_code'] ?? '';
	}

	/**
	 * Get the response code.
	 *
	 * @return string|null
	 */
	public function get_response_code(): ?string {
		return $this->response_code ?? null;
	}

	/**
	 * Whether the response is successful, according to the response code.
	 *
	 * @return bool
	 */
	public function is_success(): bool {
		return '00' === $this->get_response_code();
	}

	/**
	 * Validate the response.
	 *
	 * @throws Exception If the response code is not successful.
	 */
	public function validate(): void {
		if ( ! $this->is_success() ) {
			$error = $this->response_description;
			if ( ! empty( $this->response_details ) ) {
				$error .= ' - ' . $this->response_details;
			}
			throw new Exception( esc_html( $error ) );
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public function jsonSerialize(): array {
		return array(
			'response_code'           => $this->response_code,
			'response_description'    => $this->response_description,
			'response_details'        => $this->response_details,
			'processor_response_code' => $this->processor_response_code,
		);
	}
}
