<?php

namespace WPDesk\FakturyKSEF\Api\Exceptions;

use Exception;
use WPDeskKSEFVendor\GuzzleHttp\Exception\RequestException;

/**
 * Exception thrown when client response return an error.
 */
class ResponseException extends \RuntimeException implements ResponseExceptionInterface {

	/**
	 * Details exception.
	 *
	 * @var RequestException
	 */
	protected $details;

	/**
	 * @param string           $message  Message.
	 * @param int              $code     Code.
	 * @param RequestException $details  Details.
	 * @param Exception|null   $previous Previous.
	 */
	public function __construct( $message, $code, RequestException $details, ?Exception $previous = null ) {
		parent::__construct( $message, $code, $previous );
		$this->details = $details;
	}

	public function get_message() {
		return $this->getMessage();
	}

	public function get_translated_error(): string {
		// translators: $1 - error code.
		$response = sprintf( esc_html__( 'An unknown error occurred while trying to decode response. Response error code: %1$s', 'ksef-for-flexible-invoices' ), $this->code );
		switch ( $this->code ) {
			case 400:
				$response = esc_html__( 'An error occurred while trying to establish a connection. Verify that the VAT number is completed and that the stored token is compatible with the selected environment.', 'ksef-for-flexible-invoices' );
				break;
			case 429:
				$response = esc_html__( 'Too many requests. Wait a while and try again.', 'ksef-for-flexible-invoices' );
				break;
		}

		return $response;
	}

	/**
	 * @return string[][]
	 */
	public function get_headers() {
		return $this->details->getResponse()->getHeaders();
	}

	/**
	 * @return int
	 */
	public function get_response_code() {
		return $this->details->getResponse()->getStatusCode();
	}

	/**
	 * @return false|object
	 */
	public function get_body_contents() {
		if ( $this->details->getResponse() && $this->details->getResponse()->getBody() ) {
			$contents = $this->details->getResponse()->getBody()->getContents();
			$result   = json_decode( $contents );
			if ( json_last_error() === JSON_ERROR_NONE ) {
				return $result;
			}
		}

		return false;
	}

	/**
	 * @param false|object $result
	 *
	 * @return bool
	 */
	public function is_error( $result ) {
		return $result && isset( $result->error );
	}

	/**
	 * @return false|array
	 */
	public function get_error_message() {
		$result = $this->get_body_contents();
		if ( isset( $result->error ) && $this->is_error( $result ) ) {
			return (array) $result->error;
		}

		return false;
	}
}
