<?php
/**
 * Abstract response class.
 *
 * @package flo-checkout
 */

namespace Flo_Checkout\Gateways\Shift4_APM\Responses;

use Exception;
use Flo_Checkout\Gateways\Shift4_APM\Requests\Models\Request_Response_Model;
use Flo_Checkout\Gateways\Shift4_APM\Responses\Models\Result_Model;
use Flo_Checkout\Gateways\Shift4_APM\Traits\Request_And_Response_Logger_Trait;

defined( 'ABSPATH' ) || exit;

/**
 * Abstract response class.
 */
abstract class Abstract_Response {
	use Request_And_Response_Logger_Trait;

	/**
	 * Response result object.
	 *
	 * @var Result_Model
	 */
	protected Result_Model $result;

	/**
	 * Constructor.
	 *
	 * @param Request_Response_Model $request_response_model The response from the request.
	 */
	public function __construct(
		protected Request_Response_Model $request_response_model,
	) {}

	/**
	 * Process the response.
	 *
	 * @throws Exception If the response is not successful.
	 */
	public function process(): self {
		$this->validate();
		return $this;
	}

	/**
	 * Check if response is considered successful.
	 *
	 * @throws Exception If the response is not successful.
	 */
	protected function validate(): void {
		$this->request_response_model->validate();
		$this->create_result();
		$this->result->validate();
		$this->validate_response_data();
	}

	/**
	 * Create result object.
	 *
	 * @return void
	 * @throws Exception If the response is not successful.
	 */
	protected function create_result(): void {
		$this->result = new Result_Model( $this->request_response_model->get_body() );
	}

	/**
	 * Validate all required response data fields are set.
	 *
	 * @throws Exception If any required fields are missing.
	 */
	protected function validate_response_data(): void {
		$required_keys = $this->get_required_response_data_keys();
		$body_keys     = array_keys( $this->request_response_model->get_body() );

		$diff = array_diff( $required_keys, $body_keys );
		if ( ! empty( $diff ) ) {
			$this->log_and_throw_error(
				__( 'Response data validation failed.', 'flo-checkout-plugin' ),
				array(
					'required_keys' => $required_keys,
					'body_keys'     => $body_keys,
				),
				'Required response data fields are missing.'
			);
		}
	}

	/**
	 * Get required response data keys.
	 *
	 * @return array
	 */
	protected function get_required_response_data_keys(): array {
		return array();
	}
}
