<?php
/**
 * Credorax Payments For WooCommerce
 * https://www.credorax.com/
 *
 * @category Credorax
 * @package  WC_Credorax
 * @author   Girit-Interactive (https://www.girit-tech.com/)
 */

  if (! defined('ABSPATH')) {
      exit; // Exit if accessed directly.
  }

/**
 * Credorax Credorax abstract gateway response model.
 */
abstract class WC_Credorax_Model_Response_AbstractGateway extends WC_Credorax_Model_AbstractResponse
{
    /**
     * Response handlers.
     */
    const GATEWAY_CAPTURE_HANDLER = 'gateway_capture';
    const GATEWAY_VOID_HANDLER = 'gateway_void';
    const GATEWAY_REFUND_HANDLER = 'gateway_refund';

    /**
     * @var WC_Order
     */
    protected $_order;

    /**
     * @var string
     */
    protected $_transactionId;

    /**
     * @var string
     */
    protected $_cipher;

    /**
     * @var string|null
     */
    protected $_operationCode;

    /**
     * @var string
     */
    protected $_responseId;

    /**
     * @var int
     */
    protected $_responseCode;

    /**
     * @var string
     */
    protected $_responseDescription;

    /**
     * @var string
     */
    protected $_authCode;

    /**
     * @method __construct
     * @param  array       $curlResponse
     * @param  WC_Order    $order
     */
    public function __construct(
        array $curlResponse,
        WC_Order $order
        ) {
        parent::__construct($curlResponse);
        $this->_order = $order;
    }

    /**
     * @return string
     */
    public function getResponseType()
    {
        return AbstractResponse::RESPONSE_TYPE_GATEWAY;
    }

    /**
     * @return Dynamic3D
     */
    protected function processResponseData()
    {
        $body = $this->getBody();

        $this->_transactionId = $body['z13'];
        $this->_cipher = $body['K'];
        $this->_operationCode = (int)$body['O'];
        $this->_responseId = isset($body['z1']) ? $body['z1'] : null;
        $this->_responseCode = isset($body['z2']) ? (int)$body['z2'] : 0;
        $this->_responseDescription = isset($body['z3']) ? $body['z3'] : null;
        $this->_authCode = isset($body['z4']) ? $body['z4'] : null;

        return $this;
    }

    /**
     * @return AbstractResponse
     * @throws \Exception
     */
    public function process()
    {
        parent::process();

        $this
            ->processResponseData()
            ->updateTransaction();

        return $this;
    }

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    protected function getRequestStatus()
    {
        if (parent::getRequestStatus() === false) {
            return false;
        }

        $body = $this->getBody();
        if (isset($body['z2']) && $body['z2']) {
            return false;
        }

        return true;
    }

    /**
     * @return AbstractGateway
     * @throws \Exception
     */
    protected function updateTransaction()
    {
        $body = $this->getBody();
        ksort($body);

        $this->_order->add_meta_data(
            WC_Credorax_Gateway::KEY_RAW_TRANSACTION_DETAILS,
            array_merge(
                (array) $this->_order->get_meta(WC_Credorax_Gateway::KEY_RAW_TRANSACTION_DETAILS),
                $body
            ),
            true
        );

        $this->_order->add_meta_data(
            WC_Credorax_Gateway::KEY_CREDORAX_LAST_OPERATION_CODE,
            $this->getOperationCode(),
            true
        );

        if (($transactionId = $this->getTransactionId())) {
            $this->_order->add_meta_data(
                WC_Credorax_Gateway::KEY_CREDORAX_TRANSACTION_ID,
                $transactionId,
                true
            );
        }

        if (!$this->_order->get_meta(WC_Credorax_Gateway::KEY_CREDORAX_RESPONSE_ID) && ($responseId = $this->getResponseId())) {
            $this->_order->add_meta_data(
                WC_Credorax_Gateway::KEY_CREDORAX_RESPONSE_ID,
                $responseId,
                true
            );
        }

        return $this;
    }

    /**
     * @return string
     */
    public function getTransactionId()
    {
        return $this->_transactionId;
    }

    /**
     * @return string
     */
    public function getOperationCode()
    {
        return $this->_operationCode;
    }

    /**
     * @return string
     */
    public function getResponseId()
    {
        return $this->_responseId;
    }

    /**
     * @return int
     */
    public function getResponseCode()
    {
        return $this->_responseCode;
    }

    /**
     * @return string
     */
    public function getResponseDescription()
    {
        return $this->_responseDescription;
    }

    /**
     * @return string
     */
    public function getAuthCode()
    {
        return $this->_authCode;
    }

    /**
     * @return WC_Order
     */
    public function getOrder()
    {
        return $this->_order;
    }
}
