<?php

namespace Sibs2;

class sibsPaymentGateway extends \WC_Payment_Gateway
{
    protected $payment_id;

    protected $payment_type;

    protected $payment_brand;

    protected $language;

    protected $payment_group;

    protected $payment_display           = 'form';

    private static $added_meta_boxes     = false;

    private static $added_payment_method = false;

    private static $updated_meta_boxes   = false;

    protected $wc_order;

    public function __construct()
    {
        $this->payment_id         = $this->id;

        $payment_title            = sibsPaymentSettings::sibs_backend_payment_title($this->payment_id);
        $payment_desc             = sibsPaymentSettings::sibs_backend_payment_desc($this->payment_id);
        $payment_gateway          = sibsGeneralFunctions::sibs_get_payment_gateway_variable($this->payment_id);

        $this->plugins_url        = sibsFunctions::sibs_get_plugin_url();
        $this->form_fields        = sibsPaymentSettings::sibs_create_backend_payment_settings($this->payment_id);
        $this->method_title       = $payment_title;
        $this->method_description = $payment_desc;
        $this->payment_type       = $payment_gateway['payment_type'];
        $this->payment_brand      = $payment_gateway['payment_brand'];
        $this->payment_group      = $payment_gateway['payment_group'];
        $this->language           = $payment_gateway['language'];

        // Enable woocommerce refund for {payment gateway}.
        $this->supports = ['refunds'];

        $this->init_settings();

    // Save admin configuration from woocomerce checkout tab.
        add_action("woocommerce_update_options_payment_gateways_{$this->payment_id}", [&$this, 'process_admin_options']); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_update_options_payment_gateways_(gateway_id)

    // Frontend hook.
        add_action("woocommerce_receipt_{$this->payment_id}", [&$this, 'sibs_receipt_page']); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_receipt_(orderpayment_method)
        add_action("woocommerce_thankyou_{$this->payment_id}", [&$this, 'sibs_thankyou_page']); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_thankyou_(orderpayment_method)

    // Backend hook.
        add_action('woocommerce_admin_order_data_after_order_details', [&$this, 'sibs_update_order_status']); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_admin_order_data_after_order_details
        add_action('woocommerce_admin_order_data_after_billing_address', [&$this, 'sibs_add_payment_method']); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_admin_order_data_after_billing_address
        add_action('woocommerce_admin_order_data_after_shipping_address', [&$this, 'sibs_add_additional_information']); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_admin_order_data_after_shipping_address

    //WebHook
        add_action('rest_api_init', [&$this, 'sibs_rest_api_init']); // https://developer.wordpress.org/reference/hooks/rest_api_init/
        add_action('rest_api_init', [&$this, 'sibs_rest_api_log']); // https://developer.wordpress.org/reference/hooks/rest_api_init/

        WC()->session->__unset('sibs_thankyou_page');
        WC()->session->__unset('sibs_receipt_page');
        WC()->session->__unset('sibs_confirmation_page');
    }

    /**
     * Get Payment Logo(s)
     * ( extended at Sibs payment gateways class ).
     *
     * @return bool
     */
    protected function sibs_get_payment_logo()
    {
        return false;
    }

    public function is_available()
    {
        $is_available = parent::is_available();

        if ($is_available) {
            $recurring = 0;

            switch ($this->payment_id) {
                case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD:
                case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_DIRECT_DEBIT:
                case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAYPAL:
                    if ($recurring && get_current_user_id() > 0) {
                        $is_available = false;
                    }

                    break;
                case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD_SAVED:
                case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_DIRECT_DEBIT_SAVED:
                case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAYPAL_SAVED:
                    if (! $recurring || get_current_user_id() === 0) {
                        $is_available = false;
                    }

                    break;
                default:
                    $is_available = true;

                    break;
            }
        }

        return $is_available;
    }

    public function sibs_get_title()
    {
        return sibsGeneralFunctions::sibs_translate_backend_payment($this->payment_id);
    }

    public function sibs_get_multi_icon()
    {
        $icons_html = '';

        $payment_setting = get_option("woocommerce_{$this->payment_id}_settings");
        $cards           = $payment_setting['card_types'];

        if (! empty($cards)) {
            foreach ($cards as $card) {
                $title = strtolower($card);
                $icon  = "{$this->plugins_url}/assets/images/$title.png";
                $icons_html .= "<img 
                    src=\"$icon\"
                    alt=\"$title\"
                    title=\"$title\"
                    style=\"height:40px; max-height:40px; margin:5px 10px 5px 0; float: none; vertical-align: middle; display: inline;\"
                />";
            }
            $icons_html   = "<p>$icons_html</p>";
            $payment_desc = $payment_setting['payment_desc'];
            $icons_html .= "<p>$payment_desc</p>";
        }

        return $icons_html;
    }

    public function get_icon()
    {
        $paymentID = $this->payment_id;

        $title     = sibsGeneralFunctions::sibs_translate_frontend_payment($paymentID);
        $icon      = $this->sibs_get_payment_logo();
        $icon_html = "<img
            src=\"$icon\"
            alt=\"$title\"
            title=\"$title\"
            style=\"height:40px; max-height:40px; margin:5px 10px 5px 0; float: none; vertical-align: middle; display: inline;\"
        />";
        $icon_html = "<p>$icon_html</p>";

        switch($paymentID) {
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_BLIK:
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAY_BY_LINK:
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAY_BY_LINK_KEVIN:
                $payment_setting = get_option("woocommerce_{$paymentID}_settings");
                $payment_desc    = $payment_setting['payment_desc'];
                $icon_html .= "<p>$payment_desc</p>";

                break;
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_EASYCREDIT:
                $error_message = $this->easyCreditGetErrorMessage();

                if ($error_message) {
                    $icon_html .= $error_message;
                    $icon_html .=
                    "<script>
                        document.getElementById('payment_method_{$paymentID}').disabled = true;
                        document.getElementById('payment_method_{$paymentID}').checked = false;
                        var payment_method_easycredit_class = document.getElementsByClassName('payment_method_{$paymentID}')[0];
                        if (payment_method_easycredit_class.style.opacity !== undefined) {
                            payment_method_easycredit_class.style.opacity = '0.7';
                        } else {
                            payment_method_easycredit_class.style.filter = 'alpha(opacity=70)';
                        }
                    </script>";
                }

                break;
        }

        return apply_filters('woocommerce_gateway_icon', $icon_html, $this->id);
    }

    public function process_payment($order_id)
    {
        $wc_order = new \WC_Order($order_id);

        return [
            'result'   => 'success',
            'redirect' => $wc_order->get_checkout_payment_url(true),
        ];
    }

    public function sibs_receipt_page($order_id)
    {
        wc_get_logger()->debug("sibs_receipt_page(order_id): $order_id", sibsConstants::SIBS_LOG);

        $id                = sibsGeneralFunctions::sibs_get_request_value('id');
        $key               = sibsGeneralFunctions::sibs_get_request_value('key');
        $accept_payment    = sibsGeneralFunctions::sibs_get_request_value('accept_payment');
        $confirmation_page = sibsGeneralFunctions::sibs_get_request_value('confirmation_page');

        wc_get_logger()->debug("sibs_get_request_value(id) = $id", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("sibs_get_request_value(key) = $key", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("sibs_get_request_value(accept_payment) = $accept_payment", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("sibs_get_request_value(confirmation_page) = $confirmation_page", sibsConstants::SIBS_LOG);

        if (! empty($id) && empty($accept_payment) && empty($confirmation_page)) {
            wc_get_logger()->debug('sibs_response_page', sibsConstants::SIBS_LOG);
            $this->sibs_response_page($id, $order_id);
        } elseif (! empty($accept_payment)) {
            $this->sibs_accept_payment($id, $order_id);
        }

        if (! empty($confirmation_page) && ! WC()->session->__isset('sibs_confirmation_page')) {
            $this->sibs_confirmation_page($id, $order_id);
            WC()->session->set('sibs_confirmation_page', true);
        } elseif (empty($confirmation_page) && ! WC()->session->__isset('sibs_receipt_page')) {
            $this->sibs_set_payment_form($order_id);
            WC()->session->set('sibs_receipt_page', true);
        }
    }

    private function sibs_set_payment_form($order_id)
    {
        wc_get_logger()->debug("sibs_set_payment_form(order_id): $order_id", sibsConstants::SIBS_LOG);

        $payment_parameters = $this->sibs_set_payment_parameters($order_id);
        $server_mode        = get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_general_environment');
        $checkout_result    = \SibsPaymentCore::sibs_get_checkout_result($payment_parameters, $server_mode);

        wc_get_logger()->info('checkout_result: ' . wc_print_r($checkout_result, true), sibsConstants::SIBS_LOG);

        if (! $checkout_result['is_valid']) {
            $this->sibs_do_error_payment($order_id, sibsConstants::WOOCOMMERCE_ORDER_STATUS_CANCELLED, $checkout_result['response']);
        } elseif (! isset($checkout_result['response']['transactionID'])) {
            $this->sibs_do_error_payment($order_id, sibsConstants::WOOCOMMERCE_ORDER_STATUS_CANCELLED, $checkout_result['response'], 'ERROR_GENERAL_REDIRECT');
        }

        // TODO: Return this code when resolve the issue with it
        //$checkoutData = $this->checkout_result_to_data($checkout_result['response']);
        //$this->sibs_save_or_update_transactions($order_id, $checkoutData);

        $url_config = self::get_url_config(
            $server_mode,
            $checkout_result['response']['transactionID'],
            wc_get_checkout_url(),
            $this->plugins_url
        );

        $payment_widget_content = \SibsPaymentCore::sibs_get_payment_widget_content($url_config['payment_widget'], $server_mode);
        wc_get_logger()->debug('payment_widget_content: ' . wc_print_r($payment_widget_content, true), sibsConstants::SIBS_LOG);

        if (! $payment_widget_content['is_valid'] || str_contains($payment_widget_content['response'], 'errorDetail')) {
            $this->sibs_do_error_payment($order_id, sibsConstants::WOOCOMMERCE_ORDER_STATUS_CANCELLED, 'ERROR_GENERAL_REDIRECT');
        }

        wp_enqueue_script('sibs_formpayment_script', $url_config['payment_widget'], [], null);
        wp_enqueue_style('sibs_formpayment_style', "{$this->plugins_url}/assets/css/formpayment.css", [], null);

        $args         = self::get_form_args($this->payment_id, $payment_parameters, $url_config, $checkout_result);
        $payment_form = sibsGeneralFunctions::sibs_get_payment_form($this->payment_id);

        sibsGeneralFunctions::sibs_include_template($this->sibs_get_template_form($payment_form), $args);
    }

    private function sibs_get_template_form($payment_form)
    {
        switch ($payment_form) {
            case 'redirect':
                wc_get_logger()->debug('redirect template', sibsConstants::SIBS_LOG);
                $template = '/../templates/checkout/template-redirect-payment.php';

                break;
            case 'servertoserver':
                wc_get_logger()->debug('server to server template', sibsConstants::SIBS_LOG);
                $template = '/../templates/checkout/template-servertoserver-payment.php';

                break;
            default:
                $template = '/../templates/checkout/template-payment-form.php';
        }

        return __DIR__ . $template;
    }

    private static function get_form_args($payment_id, $payment_parameters, $url_config, $checkout_result)
    {
        wc_get_logger()->debug("payment_id: $payment_id", sibsConstants::SIBS_LOG);

        $formConfig    = self::get_form_config($payment_id, $payment_parameters, $url_config, $checkout_result);
        $formContext   = $checkout_result['response']['formContext'];
        $formSignature = $checkout_result['response']['transactionSignature'];
        $formStyle     = self::get_form_style();

        wc_get_logger()->debug("formConfig: $formConfig", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("formContext: $formContext", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("formSignature: $formSignature", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("formStyle: $formStyle", sibsConstants::SIBS_LOG);

        $args = [
            'formConfig'  => $formConfig,
            'formContext' => $formContext,
            'signature'   => $formSignature,
            'spg_style'   => $formStyle,
        ];

        return $args;
    }

    private static function get_url_config($server_mode, $transaction_id, $cancel_url, $plugins_url)
    {
        $environment_file = sibsFunctions::get_environment();
        $widget_endpoints = $environment_file['widget_endpoints'];

        $payment_widget = \SibsPaymentCore::sibs_get_payment_widget_url(
            $server_mode,
            $transaction_id,
            $widget_endpoints
        );

        $return_url = self::get_plugin_return_url();

        wc_get_logger()->debug("url_config[return_url]: {$return_url}", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("transaction_id: $transaction_id", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("url_config[payment_widget]: {$payment_widget}", sibsConstants::SIBS_LOG);

        return [
            'cancel_url'     => $cancel_url,
            'plugins_url'    => $plugins_url,
            'return_url'     => $return_url,
            'payment_widget' => $payment_widget,
        ];
    }

    private static function get_plugin_return_url()
    {
        global $wp;

        $key = sibsGeneralFunctions::sibs_get_request_value('key');

        if (isset($wp->request)) {
            $url = home_url($wp->request);

            return "$url/?key=$key";
        } else {
            $url       = get_page_link();
            $order_pay = sibsGeneralFunctions::sibs_get_request_value('order-pay');

            return "$url&order-pay=$order_pay&key=$key";
        }
    }

    private static function get_form_style()
    {
        $layout = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout') : 'default';
        $theme = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme') : 'default';

        $layout_primary = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout_primary')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout_primary') : '';
        $layout_surface = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout_surface')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout_surface') : '';
        $layout_text_color = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout_text_color')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout_text_color') : '';
        $layout_header_color = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout_header_color')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_layout_header_color') : '';

        $theme_secondary =  ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme_secondary_color')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme_secondary_color') : '';
        $theme_background = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme_background_color')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme_background_color') : '';
        $theme_border = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme_border_color')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme_border_color') : '';
        $theme_header = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme_header_text')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_theme_header_text') : '';

        $font = ! empty(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_font')) ?
          get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_style_font') : '';

        $style           = [
            'layout' => $layout,
            'theme'  => $theme,
            'color'  => [
                'primary'   => $layout_primary,
                'secondary' => $theme_secondary,
                'border'    => $theme_border,
                'surface'   => $layout_surface,
                'header'    => [
                    'text'       => $theme_header,
                    'background' => $layout_header_color,
                ],
                'body' => [
                    'text'       => $layout_text_color,
                    'background' => $theme_background,
                ],
                'font' => $font,
            ],
        ];

        return json_encode($style);
    }

    private static function get_form_config($payment_id, $payment_parameters, $url_config, $checkout_result)
    {
        $form_customer_name   = $payment_parameters['customer']['customerInfo']['customerName'];
        $form_customer_email  = $payment_parameters['customer']['customerInfo']['customerEmail'];
        $form_amount          = $payment_parameters['transaction']['amount']['value'];
        $form_currency        = $payment_parameters['transaction']['amount']['currency'];
        $form_payment_methods = $payment_id;
        $form_language        = sibsFunctions::get_language();

        $formConfig = [
            'paymentMethodList' => [
                $form_payment_methods,
            ],
            'amount' => [
                'amount'   => $form_amount,
                'currency' => $form_currency,
            ],
            'language'     => $form_language,
            'redirectUrl'  => $url_config['return_url'] . '&id=' . $checkout_result['response']['transactionID'],
            'customerData' => [
                'customerName'  => $form_customer_name,
                'customerEmail' => $form_customer_email,
            ],
        ];

        return json_encode($formConfig);
    }

    private function sibs_response_page($id, $order_id)
    {
        wc_get_logger()->debug("sibs_response_page(order_id): $order_id", sibsConstants::SIBS_LOG);

        $is_testmode_available = false;
        $status_parameters     = sibsGeneralFunctions::sibs_get_credentials($this->payment_id, $is_testmode_available);
        wc_get_logger()->info('status_parameters: ' . wc_print_r($status_parameters, true), sibsConstants::SIBS_LOG);

        $payment_result = self::get_payment_result($id, $status_parameters);

        if (! $payment_result) {
            $this->sibs_do_error_payment($order_id, sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED, 'ERROR_GENERAL_NORESPONSE');

            return;
        }
        wc_get_logger()->debug('payment_result: ' . print_r($payment_result, true), sibsConstants::SIBS_LOG);

        $result_status  = \SibsPaymentCore::sibs_get_transaction_result($payment_result['returnStatus']['statusCode']);
        $payment_status = sibsGeneralFunctions::convertTransactionStatus(
            $payment_result['paymentStatus'],
            $payment_result['paymentType']
        );
        $payment_result['payment_status'] = $payment_status;

        wc_get_logger()->info("payment_status: $payment_status", sibsConstants::SIBS_LOG);

        if ($result_status !== sibsConstants::SIBS_ACK || $payment_status === sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED) {
            $this->sibs_failed_response($order_id, $payment_result, $result_status);

            return;
        }

        $this->sibs_do_success_payment($order_id, $payment_result);
    }

    private static function get_payment_result($id, $status_parameters)
    {
        $payment_result = \SibsPaymentCore::sibs_get_payment_status($id, $status_parameters);
        wc_get_logger()->info('payment_result: ' . wc_print_r($payment_result, true), sibsConstants::SIBS_LOG);

        return $payment_result;
    }

    /**
     * SIBS: Confirmation Page.
     *
     * @param string $order
     */
    private function sibs_confirmation_page($id, $order_id)
    {
        wc_get_logger()->debug("sibs_confirmation_page(order_id): $order_id", sibsConstants::SIBS_LOG);

        $is_testmode_available = false;
        $status_parameters     = sibsGeneralFunctions::sibs_get_credentials($this->payment_id, $is_testmode_available);

        $payment_result = \SibsPaymentCore::sibs_get_payment_server_to_server_status($id, $status_parameters);
        $wc_order       = new \WC_Order($order_id);

        if (! $payment_result) {
            $this->sibs_do_error_payment($order_id, sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED, 'ERROR_GENERAL_NORESPONSE');

            return;
        }

        $result_status = \SibsPaymentCore::sibs_get_transaction_result($payment_result['result']['code']);

        $payment_status = sibsGeneralFunctions::convertTransactionStatus(
            $payment_result['paymentStatus'],
            $payment_result['paymentType']
        );
        $payment_result['payment_status'] = $payment_status;

        wc_get_logger()->debug("payment_status: $payment_status", sibsConstants::SIBS_LOG);

        if ($result_status !== sibsConstants::SIBS_ACK) {
            $this->sibs_failed_response($order_id, $payment_result, $result_status);

            return;
        }

        WC()->session->set('easycredit_result', [$id => $payment_result]);
        WC()->session->set('sum_of_interest', $payment_result['resultDetails']['ratenplan.zinsen.anfallendeZinsen']);
        WC()->session->set('order_total', $payment_result['resultDetails']['ratenplan.gesamtsumme']);
        WC()->session->set('tilgungsplan_text', $payment_result['resultDetails']['tilgungsplanText']);
        WC()->session->set('vorvertragliche_link', $payment_result['resultDetails']['vorvertraglicheInformationen']);

        add_action('woocommerce_thankyou_' . $this->payment_id, [$this, 'sibs_get_woocommerce_thankyou_text']);
        add_filter('woocommerce_get_order_item_totals', [$this, 'sibs_add_sumofinterest_ordertotal']);
        add_filter('woocommerce_thankyou_order_received_text', [$this, 'sibs_get_woocommerce_thankyou_order_received_text']);
        add_action('woocommerce_thankyou', [$this, 'sibs_get_woocommerce_thankyou']);
        add_filter('woocommerce_pay_order_button_text', [$this, 'change_thankyou_to_confirmation']);

        try {
            $wc_order->update_status(sibsConstants::WOOCOMMERCE_ORDER_STATUS_ON_HOLD);
        } catch (\Throwable $t) {
            wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
        }

        wc_get_template('checkout/thankyou.php', ['order' => $order_id]);
    }

    public function sibs_get_woocommerce_thankyou_text()
    {
        $tilgungsplan_text        = esc_attr(WC()->session->get('tilgungsplan_text'));
        $vorvertragliche_link     = esc_attr(WC()->session->get('vorvertragliche_link'));
        $frontend_easycredit_link = esc_attr(__('FRONTEND_EASYCREDIT_LINK', sibsConstants::SIBS_TRANSLATE));

        echo"<p>$tilgungsplan_text</p>
    <p>
      <a href=\"$vorvertragliche_link\" target='_blank'>$frontend_easycredit_link</a>
    </p>";
    }

    public function sibs_get_woocommerce_thankyou_order_received_text()
    {
        return __('GENERAL_TEXT_ORDER_REVIEW', sibsConstants::SIBS_TRANSLATE);
    }

    /**
     * Get woocommerce thankyou.
     */
    public function sibs_get_woocommerce_thankyou()
    {
        wc_get_logger()->debug('sibs_get_woocommerce_thankyou()', sibsConstants::SIBS_LOG);

        $key = sibsGeneralFunctions::sibs_get_request_value('key');
        $id  = sibsGeneralFunctions::sibs_get_request_value('id');

        if (isset(WC()->request)) {
            $url                 = home_url(WC()->request);
            $accept_payment_link = esc_attr(
                "$url/?key=$key&accept_payment=1&id=$id"
            );
        } else {
            $url                 = home_url(WC()->request);
            $order_pay           = sibsGeneralFunctions::sibs_get_request_value('order-pay');
            $accept_payment_link = esc_attr(
                "$url&order-pay=$order_pay&key=$key&accept_payment=1&id=$id"
            );
        }

        $wc_checkout_url = esc_attr(wc_get_checkout_url());
        $cancel          = esc_attr(__('Cancel', sibsConstants::SIBS_TRANSLATE));
        $place_order     = esc_attr(__('Place order', sibsConstants::SIBS_TRANSLATE));

        // Input hidden is for make the input have the shame padding according to css style.
        echo "<div id=\"payment\" style=\"padding-top: 10px; border-top: 1px solid #aaaaaa\">
            <input type=\"hidden\"/>
            <input type=\"button\" class=\"button alt\" onclick=\"window.location = \\$wc_checkout_url\\\" value=\"$cancel\"/>
            <input type=\"submit\" class=\"button alt\"  id=\"place_order\" onclick=\"window.location = \\$accept_payment_link\\\" value=\"$place_order\" />
        </div>";

        echo '<script>
            var title = document.getElementsByClassName("woocommerce-thankyou-order-received")[0].innerHTML;
            document.getElementsByClassName("entry-title")[0].innerHTML = title;
            var element = document.getElementsByClassName("order_details")[0];
            element.parentNode.removeChild(element);
        </script>';
    }

    private function sibs_accept_payment($reference_id, $order_id)
    {
        wc_get_logger()->debug("sibs_accept_payment(order_id): $order_id", sibsConstants::SIBS_LOG);

        if (! WC()->session->__isset('easycredit_result') && ! isset(WC()->session->get('easycredit_result')[$reference_id])) {
            $this->sibs_do_error_payment($order_id, sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED, 'ERROR_GENERAL_CAPTURE_PAYMENT');

            return;
        }

        $payment_result = WC()->session->get('easycredit_result')[$reference_id];
        WC()->session->__unset('easycredit_result');
        $is_testmode_available     = true;
        $is_multichannel_available = true;

        $capture_parameter                 = sibsGeneralFunctions::sibs_get_credentials($this->payment_id, $is_testmode_available, $is_multichannel_available);
        $capture_parameter['amount']       = $payment_result['amount'];
        $capture_parameter['currency']     = $payment_result['currency'];
        $capture_parameter['payment_type'] = sibsConstants::SPG_PAYMENT_TYPE_CAPT;

        $capture_result = \SibsPaymentCore::sibs_back_office_operation($reference_id, $capture_parameter, $order_id);

        if (! $capture_result) {
            $this->sibs_do_error_payment($order_id, sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED, 'ERROR_GENERAL_CAPTURE_PAYMENT');

            return;
        }

        $capture_status = \SibsPaymentCore::sibs_get_transaction_result($capture_result['returnStatus']['statusCode']);

        $payment_status = sibsGeneralFunctions::convertTransactionStatus(
            $payment_result['paymentStatus'],
            $payment_result['paymentType']
        );
        $payment_result['payment_status'] = $payment_status;

        wc_get_logger()->debug("payment_status: $payment_status", sibsConstants::SIBS_LOG);

        if ($capture_status === sibsConstants::SIBS_ACK) {
            $this->sibs_do_success_payment($order_id, $payment_result);
        } else {
            $this->sibs_failed_response($order_id, $payment_result, $capture_status);
        }
    }

    private function sibs_do_success_payment($order_id, $payment_result)
    {
        $wc_order = new \WC_Order($order_id);
        wc_get_logger()->info('success order_id: ' . wc_print_r($order_id, true), sibsConstants::SIBS_LOG);

        try {
            $wc_order->update_status($payment_result['payment_status']);
        } catch (\Throwable $t) {
            wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
        }

        $order_awaiting_payment_session = WC()->session->get('order_awaiting_payment');
        // Empty awaiting payment session.
        if (! empty($order_awaiting_payment_session)) {
            WC()->session->__unset('order_awaiting_payment');
        }

        $this->sibs_save_or_update_transactions($order_id, $payment_result, true);

        WC()->cart->empty_cart();
        wp_safe_redirect($this->get_return_url($wc_order));

        exit();
    }

    private function sibs_failed_response($order_id, $payment_result, $result_status)
    {
        $error_identifier = ($result_status === sibsConstants::SIBS_NOK) ?
          \SibsErrorHandler::sibs_get_error_identifier($payment_result['returnStatus']['statusCode']) :
          'ERROR_UNKNOWN';

        wc_get_logger()->error("error_identifier: $error_identifier", sibsConstants::SIBS_LOG);

        $this->sibs_save_or_update_transactions($order_id, $payment_result);
        $this->sibs_do_error_payment($order_id, $payment_result['payment_status'], $error_identifier);
    }

    private function sibs_do_error_payment($order_id, $payment_status, $error_identifier)
    {
        $wc_order = new \WC_Order($order_id);

        $error_translated = sibsGeneralFunctions::sibs_translate_error_identifier($error_identifier);
        wc_get_logger()->error('error_translated: ' . wc_print_r($error_translated, true), sibsConstants::SIBS_LOG);
        wc_get_logger()->error("payment_status: $payment_status", sibsConstants::SIBS_LOG);

        // Cancel the order.
        try {
            $wc_order->update_status($payment_status);
        } catch (\Throwable $t) {
            wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
        }

        // To display failure messages from woocommerce session.
        wc_add_notice($error_translated, 'error');

        wp_safe_redirect(wc_get_checkout_url());

        exit();
    }

    public function sibs_thankyou_page($order_id)
    {
        if (! WC()->session->__isset('sibs_thankyou_page')) {
            WC()->session->set('sibs_thankyou_page', true);
        }
    }

    public static function sibs_is_sibs_by_order($order_id)
    {
        $transaction_log = sibsGeneralModels::sibs_get_db_transaction_log($order_id);

        return isset($transaction_log['payment_id']) ? self::sibs_is_sibs_by_payment_id($transaction_log['payment_id']) : false;
    }

    private static function sibs_is_sibs_by_payment_id($payment_method)
    {
        if (str_contains($payment_method, 'sibs')) {
            return true;
        }

        return false;
    }

    private function sibs_update_payment_status($order_id, $original_post_status = false, $order_post_status = false)
    {
        $transaction_log = sibsGeneralModels::sibs_get_db_transaction_log($order_id);

        if (! $original_post_status) {
            $original_post_status = $transaction_log['payment_status'];
        }

        $backoffice_parameter = sibsGeneralFunctions::sibs_get_credentials($transaction_log['payment_id']);

        $backoffice_result = \SibsPaymentCore::sibs_update_status($transaction_log['reference_id'], $backoffice_parameter);
        $backoffice_status = \SibsPaymentCore::sibs_get_transaction_result($backoffice_result['result']['code']);
        $payment_status    = sibsGeneralFunctions::convertTransactionStatus(
            $backoffice_result['paymentStatus'],
            $backoffice_result['paymentType']
        );

        if ($backoffice_status === sibsConstants::SIBS_ACK && $payment_status !== sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED) {
            sibsGeneralModels::sibs_update_db_transaction_log_status($order_id, $payment_status);
            sibsGeneralModels::sibs_update_db_posts_status($order_id, $payment_status);

            if ($original_post_status !== $payment_status) {
                $unsuccess_Status = [
                    sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED,
                    sibsConstants::WOOCOMMERCE_ORDER_STATUS_CANCELLED,
                ];

                if ($order_post_status && (in_array($order_post_status, $unsuccess_Status))) {
                    wc_increase_stock_levels($order_id);
                }

                $wc_order_status         = wc_get_order_statuses();
                $status_name['original'] = $wc_order_status[$original_post_status];
                $status_name['new']      = $wc_order_status[$payment_status];
                $this->sibs_add_order_notes($order_id, $status_name);
            }

            return true;
        }

        return false;
    }

    /**
     * SIBS: Check Status.
     *
     * @param int $order_id
     * @return array $back_data
     */
    public static function check_status($order_id)
    {
        wc_get_logger()->debug("[check_status] order_id: $order_id", sibsConstants::SIBS_LOG);

        try {
            $is_sibs_payment = self::sibs_is_sibs_by_order($order_id);

            if (! $is_sibs_payment) {
                throw new sibsException(
                    __('Order is not a SIBS payment', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $sibs_payment              = sibsGeneralModels::sibs_get_db_transaction_log($order_id);
            $is_testmode_available     = false;
            $is_multichannel_available = true;
            $credentials               = sibsGeneralFunctions::sibs_get_credentials($sibs_payment['payment_id'], $is_testmode_available, $is_multichannel_available);

            wc_get_logger()->debug('[check_status] sibs_payment: ' . print_r($sibs_payment, true), sibsConstants::SIBS_LOG);
            wc_get_logger()->debug('[check_status] credentials: ' . print_r($credentials, true), sibsConstants::SIBS_LOG);

            $payment_result = self::get_payment_result($sibs_payment['reference_id'], $credentials);
            wc_get_logger()->debug('[check_status] payment_result: ' . print_r($payment_result, true), sibsConstants::SIBS_LOG);

            $result_status = \SibsPaymentCore::sibs_get_transaction_result($payment_result['returnStatus']['statusCode'], $payment_result['paymentStatus']);
            wc_get_logger()->debug("[check_status] result_status: $result_status", sibsConstants::SIBS_LOG);

            if ($result_status === sibsConstants::SIBS_ACK) {
                $back_data = self::deal_ACK_status($order_id, $payment_result);
            } else {
                $error_message = sprintf(
                    __('Error on Status Inquiry for order #%s', sibsConstants::SIBS_TRANSLATE),
                    esc_attr($order_id)
                );

                throw new sibsException($error_message);
            }
        } catch(sibsException $e) {
            $back_data['msg']   = $e->getErrorMessage();
            $back_data['error'] = 1;
        } catch(Exception $e) {
            $back_data['msg']   = $e->getMessage();
            $back_data['error'] = 1;
        }

        return $back_data;
    }

    /**
     * SIBS: Deal with acknologment status.
     *
     * @param int $order_id
     * @param array $payment_result
     * @return array $back_data
     */
    public function deal_ACK_status($order_id, $payment_result)
    {
        $payment_type   = $payment_result['paymentType'];
        $payment_method = $payment_result['paymentMethod'];

        wc_get_logger()->debug('[dealACKStatus] payment_type: ' . esc_attr($payment_type), sibsConstants::SIBS_LOG);
        wc_get_logger()->debug('[dealACKStatus] payment_method: ' . esc_attr($payment_method), sibsConstants::SIBS_LOG);

        $payment_status = sibsGeneralFunctions::convertTransactionStatus(
            $payment_result['paymentStatus'],
            $payment_type
        );

        $back_data['msg'] = sprintf(
            __('SIBS status payment is %s for order #%s', sibsConstants::SIBS_TRANSLATE),
            esc_attr($payment_status),
            esc_attr($order_id)
        );
        $back_data['error'] = 0;

        return $back_data;
    }

    /**
     * SIBS: Get Message when ACK.
     *
     * @param int $order_id
     * @param array $payment_result
     * @param string $payment_type
     * @return array ($payment_status, $back_data)
     */
    public function get_ACK_message($order_id, $payment_result, $payment_type)
    {
        $payment_status = sibsGeneralFunctions::convertTransactionStatus(
            $payment_result['paymentStatus'],
            $payment_type
        );

        switch ($payment_status) {
            case sibsConstants::WOOCOMMERCE_ORDER_STATUS_PENDING:
            case sibsConstants::WOOCOMMERCE_ORDER_STATUS_ON_HOLD:
                wc_get_logger()->debug('[getACKMessage] Status payment pending for order #' . esc_attr($order_id), sibsConstants::SIBS_LOG);
                $back_data['msg'] = sprintf(
                    __('Status payment pending for order #%s', sibsConstants::SIBS_TRANSLATE),
                    esc_attr($order_id)
                );

                break;
            case sibsConstants::SIBS_ORDER_STATUS_AUTHORIZED:
                wc_get_logger()->debug('[getACKMessage] Status payment authorized for order #' . esc_attr($order_id), sibsConstants::SIBS_LOG);
                $back_data['msg'] = sprintf(
                    __('Status payment authorized for order #%s', sibsConstants::SIBS_TRANSLATE),
                    esc_attr($order_id)
                );

                break;
            case sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_CAPTURED:
                wc_get_logger()->debug('[getACKMessage] Status payment partially captured for order #' . esc_attr($order_id), sibsConstants::SIBS_LOG);
                $back_data['msg'] = sprintf(
                    __('Status payment partially captured for order #%s', sibsConstants::SIBS_TRANSLATE),
                    esc_attr($order_id)
                );

                break;
            case sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_REFUNDED:
                wc_get_logger()->debug('[getACKMessage] Status payment partially refunded for order #' . esc_attr($order_id), sibsConstants::SIBS_LOG);
                $back_data['msg'] = sprintf(
                    __('Status payment partially refunded for order #%s', sibsConstants::SIBS_TRANSLATE),
                    esc_attr($order_id)
                );

                break;
            case sibsConstants::SIBS_ORDER_STATUS_PENDING_REFUND:
                wc_get_logger()->debug('[getACKMessage] Status payment pending refund for order #' . esc_attr($order_id), sibsConstants::SIBS_LOG);
                $back_data['msg'] = sprintf(
                    __('Status payment is pending for refund for order #%s', sibsConstants::SIBS_TRANSLATE),
                    esc_attr($order_id)
                );

                break;
            case sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING:
            case sibsConstants::WOOCOMMERCE_ORDER_STATUS_COMPLETED:
                wc_get_logger()->debug('[getACKMessage] Status payment complete (ACK) for order #' . esc_attr($order_id), sibsConstants::SIBS_LOG);
                $back_data['msg'] = sprintf(
                    __('Status complete (ACK) for order #%s', sibsConstants::SIBS_TRANSLATE),
                    esc_attr($order_id)
                );

                break;
            case sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED:
            default:
                wc_get_logger()->debug('[getACKMessage] Status payment declined (NOK) for order #' . esc_attr($order_id), sibsConstants::SIBS_LOG);
                $back_data['msg'] = sprintf(
                    __('Status declined (NOK) for order #%s', sibsConstants::SIBS_TRANSLATE),
                    esc_attr($order_id)
                );
        }

        return [$payment_status, $back_data];
    }

    /**
     * SIBS: Process Capture Amount.
     *
     * @param int $order_id
     * @return array $back_data
     */
    public static function process_capture($order_id)
    {
        $wc_order = new \WC_Order($order_id);
        wc_get_logger()->debug("[process_capture] order_id: $order_id", sibsConstants::SIBS_LOG);

        try {
            $is_sibs_payment = self::sibs_is_sibs_by_order($order_id);

            if (! $is_sibs_payment) {
                throw new sibsException(
                    __('Order is not a SIBS payment', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $payment_status    = 'wc-' . $wc_order->get_status();
            $status_to_capture = [
                sibsConstants::SIBS_ORDER_STATUS_AUTHORIZED,
            ];

            if (! in_array($payment_status, $status_to_capture)) {
                throw new sibsException(
                    __('Order is cannot be captured in this status', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $sibs_payment  = sibsGeneralModels::sibs_get_db_transaction_log($order_id);
            $payment_type  = sibsConstants::SPG_PAYMENT_TYPE_CAPT;
            $error_message = __('ERROR_GENERAL_CAPTURE_PAYMENT', sibsConstants::SIBS_TRANSLATE);
            $amount        = $wc_order->get_total();

            wc_get_logger()->debug('[process_capture] sibs_payment: ' . wc_print_r($sibs_payment, true), sibsConstants::SIBS_LOG);
            wc_get_logger()->debug("[process_capture] payment_type: $payment_type", sibsConstants::SIBS_LOG);
            wc_get_logger()->debug("[process_capture] amount: $amount", sibsConstants::SIBS_LOG);

            $backoffice_config = self::get_backoffice_config(
                $sibs_payment,
                $payment_type,
                $amount,
                $error_message
            );

            $backoffice_result = self::sibs_do_back_office_payment($backoffice_config);

            sibsGeneralModels::sibs_update_db_transaction($order_id, [
                'captured_id'    => $backoffice_result['response']['transactionID'],
                'capture_status' => $backoffice_result['response']['paymentStatus'],
            ]);

            if (! $backoffice_result['is_valid']) {
                throw new sibsException(
                    __('Capture request has an ERROR', sibsConstants::SIBS_TRANSLATE)
                );
            }

            switch($backoffice_result['response']['paymentStatus']) {
                case sibsConstants::SIBS_RESULT_SUCCESS:
                    $capture_status = $backoffice_config['order_status'];
                    wc_get_logger()->debug('[process_capture] SUCCESS', sibsConstants::SIBS_LOG);

                    break;
                default:
                    throw new sibsException(
                        __('Capture request denied by SIBS.', sibsConstants::SIBS_TRANSLATE)
                    );
            }

            $amountMSG = "$amount {$wc_order->get_currency()}";

            $note_message = sprintf(
                __('Order was Captured for %s', sibsConstants::SIBS_TRANSLATE),
                $amountMSG
            );

            try {
                $wc_order->update_status($capture_status);
            } catch (\Throwable $t) {
                wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
            }

            sibsGeneralModels::sibs_update_db_transaction($order_id, [
                'payment_status'      => $capture_status,
                'captured_amount'     => $backoffice_result['response']['amount']['value'] + $sibs_payment['captured_amount'],
                'capture_information' => $note_message . (! empty($sibs_payment['capture_information']) ? ', ' . $sibs_payment['capture_information'] : ''),
            ]);

            // Add cpture note
            $wc_order->add_order_note($note_message);

            // Capture Success
            $back_data['error'] = 0;
            $back_data['msg']   = sprintf(
                __('Capture success for order #%s with %s', sibsConstants::SIBS_TRANSLATE),
                $wc_order->get_id(),
                $amountMSG
            );
        } catch(sibsException $e) {
            $back_data['error'] = 1;
            $back_data['msg']   = $e->getErrorMessage();
        } catch(Exception $e) {
            $back_data['error'] = 1;
            $back_data['msg']   = $e->getMessage();
        }

        return $back_data;
    }

    /**
     * SIBS: Process Refund.
     *
     * @param string $order_id
     * @param string|null $amount
     * @param string $reason
     */
    public function process_refund($order_id, $amount = null, $reason = '')
    {
        $wc_order = new \WC_Order($order_id);

        wc_get_logger()->debug("[process_refund] order_id: $order_id", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("[process_refund] amount: $amount", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("[process_refund] reason: $reason", sibsConstants::SIBS_LOG);

        try {
            $is_sibs_payment = self::sibs_is_sibs_by_order($order_id);

            if (! $is_sibs_payment) {
                throw new sibsException(
                    __('Order is not a SIBS payment', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $payment_status   = 'wc-' . $wc_order->get_status();
            $status_to_refund = [
                sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING,
                sibsConstants::WOOCOMMERCE_ORDER_STATUS_COMPLETED,
                sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_CAPTURED,
                sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_REFUNDED,
            ];

            if (! in_array($payment_status, $status_to_refund)) {
                throw new sibsException(
                    sprintf(
                        __('Order is cannot be refunded in status %s', sibsConstants::SIBS_TRANSLATE),
                        esc_attr($payment_status)
                    )
                );
            }

            $sibs_payment  = sibsGeneralModels::sibs_get_db_transaction_log($order_id);
            $payment_type  = sibsConstants::SPG_PAYMENT_TYPE_RFND;
            $error_message = __('ERROR_GENERAL_REFUND_PAYMENT', sibsConstants::SIBS_TRANSLATE);

            wc_get_logger()->debug('[process_refund] sibs_payment: ' . wc_print_r($sibs_payment, true), sibsConstants::SIBS_LOG);
            wc_get_logger()->debug("[process_refund] payment_type: $payment_type", sibsConstants::SIBS_LOG);

            $backoffice_config = self::get_backoffice_config(
                $sibs_payment,
                $payment_type,
                $amount,
                $error_message
            );

            $backoffice_result = self::sibs_do_back_office_payment($backoffice_config);
            sibsGeneralModels::sibs_update_db_transaction($order_id, [
                'refunded_id'   => $backoffice_result['response']['transactionID'],
                'refund_status' => $backoffice_result['response']['paymentStatus'],
            ]);

            if (! $backoffice_result['is_valid']) {
                throw new sibsException(
                    __('Refund request has an ERROR', sibsConstants::SIBS_TRANSLATE)
                );
            }

            switch($backoffice_result['response']['paymentStatus']) {
                case sibsConstants::SIBS_RESULT_SUCCESS:
                    $refund_status = $backoffice_config['order_status'];
                    wc_get_logger()->debug('[process_refund] SUCCESS', sibsConstants::SIBS_LOG);

                    break;
                case sibsConstants::SIBS_RESULT_PENDING:
                    $refund_status = sibsConstants::SIBS_ORDER_STATUS_PENDING_REFUND;
                    wc_get_logger()->debug('[process_refund] PENDING', sibsConstants::SIBS_LOG);

                    break;
                default:
                    throw new sibsException(
                        __('Refund request denied by SIBS', sibsConstants::SIBS_TRANSLATE)
                    );
            }

            $amountMSG = "$amount {$wc_order->get_currency()}";

            $note_message = sprintf(
                __('Order was Refunded for %s', sibsConstants::SIBS_TRANSLATE),
                $amountMSG
            );

            try {
                $wc_order->update_status($refund_status);
            } catch (\Throwable $t) {
                wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
            }

            sibsGeneralModels::sibs_update_db_transaction($order_id, [
                'payment_status'     => $refund_status,
                'refunded_amount'    => $backoffice_result['response']['amount']['value'] + $sibs_payment['refunded_amount'],
                'refund_information' => $note_message . (! empty($sibs_payment['refund_information']) ? ', ' . $sibs_payment['refund_information'] : ''),
            ]);

            if ($backoffice_result['response']['paymentStatus'] === sibsConstants::SIBS_RESULT_PENDING) {
                return new \WP_Error(
                    'refund_pending',
                    __('BLIK Refund is asyncronous, you have to make a refund inquiry to get the real refund status', sibsConstants::SIBS_TRANSLATE),
                    ['status' => 200]
                );
            }

            return true;
        } catch(sibsException $e) {
            return new \WP_Error(
                'not_refunded_error',
                $e->getErrorMessage(),
                ['status' => 400]
            );
        } catch(Exception $e) {
            return new \WP_Error(
                'not_refunded_error',
                $e->getMessage(),
                ['status' => 500]
            );
        }
    }

    public static function get_order_refunded_status($order_id, $payment_method)
    {
        $async_refund = [
            sibsConstants::SIBS_PAYMENT_METHOD_ORDER_BLIK,
        ];

        if (in_array($payment_method, $async_refund)) {
            wc_get_logger()->debug('[process_refund] Order Fully Refunded (Async)', sibsConstants::SIBS_LOG);

            return sibsConstants::WOOCOMMERCE_ORDER_STATUS_REFUNDED;
        }

        if (self::is_fully_refunded($order_id)) {
            wc_get_logger()->debug('[process_refund] Order Fully Refunded', sibsConstants::SIBS_LOG);

            return sibsConstants::WOOCOMMERCE_ORDER_STATUS_REFUNDED;
        } elseif (self::is_partially_refunded($order_id)) {
            wc_get_logger()->debug('[process_refund] Order Partially Refunded', sibsConstants::SIBS_LOG);

            return sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_REFUNDED;
        }

        throw new sibsException(
            __('Order is not fully or partially refunded. Amount Value must be wrong.', sibsConstants::SIBS_TRANSLATE)
        );
    }

    public static function is_fully_refunded($order_id)
    {
        $wc_order = new \WC_Order($order_id);

        wc_get_logger()->debug('[is_fully_refunded] get_remaining_refund_items: ' . $wc_order->get_remaining_refund_items(), sibsConstants::SIBS_LOG);
        wc_get_logger()->debug('[is_fully_refunded] get_remaining_refund_amount: ' . $wc_order->get_remaining_refund_amount(), sibsConstants::SIBS_LOG);

        return
            $wc_order->get_remaining_refund_items() === 0 ||
            $wc_order->get_remaining_refund_amount() == 0;
    }

    public static function is_partially_refunded($order_id)
    {
        $wc_order = new \WC_Order($order_id);

        wc_get_logger()->debug('[is_partially_refunded] get_item_count_refunded: ' . $wc_order->get_item_count_refunded(), sibsConstants::SIBS_LOG);
        wc_get_logger()->debug('[is_partially_refunded] get_total_refunded: ' . $wc_order->get_total_refunded(), sibsConstants::SIBS_LOG);

        $not_fully_refunded = ! self::is_fully_refunded($order_id);
        $refunded_something = (
            $wc_order->get_item_count_refunded() > 0 ||
            $wc_order->get_total_refunded() > 0
        );

        return $not_fully_refunded && $refunded_something;
    }

    /**
     * SIBS: Refund Inquiry.
     *
     * @param int $order_id
     * @return array $back_data
     */
    public static function refund_inquiry($order_id)
    {
        $wc_order = new \WC_Order($order_id);
        wc_get_logger()->debug("[refund_inquiry] order_id: $order_id", sibsConstants::SIBS_LOG);

        try {
            $is_sibs_payment = self::sibs_is_sibs_by_order($order_id);

            if (! $is_sibs_payment) {
                throw new sibsException(
                    __('Order is not a SIBS payment', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $payment_status           = 'wc-' . $wc_order->get_status();
            $status_to_refund_inquiry = [
                sibsConstants::SIBS_ORDER_STATUS_PENDING_REFUND,
            ];

            if (! in_array($payment_status, $status_to_refund_inquiry)) {
                throw new sibsException(
                    __('Order is not on a status to refund inquiry', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $sibs_payment              = sibsGeneralModels::sibs_get_db_transaction_log($order_id);
            $is_testmode_available     = false;
            $is_multichannel_available = true;
            $credentials               = sibsGeneralFunctions::sibs_get_credentials($sibs_payment['payment_id'], $is_testmode_available, $is_multichannel_available);

            wc_get_logger()->debug('[refund_inquiry] sibs_payment: ' . print_r($sibs_payment, true), sibsConstants::SIBS_LOG);
            wc_get_logger()->debug('[refund_inquiry] credentials: ' . print_r($credentials, true), sibsConstants::SIBS_LOG);

            $refund_result = self::get_payment_result($sibs_payment['refunded_id'], $credentials);
            wc_get_logger()->debug('[refund_inquiry] payment_result: ' . print_r($refund_result, true), sibsConstants::SIBS_LOG);

            if ($refund_result['paymentStatus'] === sibsConstants::SIBS_RESULT_SUCCESS) {
                $refund_inquiry_status = sibsConstants::WOOCOMMERCE_ORDER_STATUS_REFUNDED;

                try {
                    $wc_order->update_status($refund_inquiry_status);
                } catch (\Throwable $t) {
                    wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
                }

                $amount    = $sibs_payment['refunded_amount'];
                $amountMSG = "$amount {$wc_order->get_currency()}";

                // Add refund Inquiry note
                $note_message = sprintf(
                    __('Order was Refunded for %s', sibsConstants::SIBS_TRANSLATE),
                    $amountMSG
                );
                $wc_order->add_order_note($note_message);

                sibsGeneralModels::sibs_update_db_transaction($order_id, [
                    'payment_status'     => $refund_inquiry_status,
                    'refunded_amount'    => $sibs_payment['refunded_amount'],
                    'refund_information' => $note_message . (! empty($sibs_payment['refund_information']) ? ', ' . $sibs_payment['refund_information'] : ''),
                ]);
                wc_get_logger()->debug('[refund_inquiry] SUCCESS', sibsConstants::SIBS_LOG);
            } else {
                if ($refund_result['paymentStatus'] === sibsConstants::SIBS_RESULT_PENDING) {
                    $refund_inquiry_status = sibsConstants::SIBS_ORDER_STATUS_PENDING_REFUND;
                    $errorMessage          = __('Order refund still pending', sibsConstants::SIBS_TRANSLATE);
                    wc_get_logger()->debug('[refund_inquiry] PENDING', sibsConstants::SIBS_LOG);
                } else {
                    $refund_inquiry_status = sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING;
                    $errorMessage          = __('Order refund failed for #%s', sibsConstants::SIBS_TRANSLATE);
                    wc_get_logger()->debug('[refund_inquiry] FAILED', sibsConstants::SIBS_LOG);
                }

                try {
                    $wc_order->update_status($refund_inquiry_status);
                } catch (\Throwable $t) {
                    wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
                }

                sibsGeneralModels::sibs_update_db_transaction($order_id, [
                    'payment_status'     => $refund_inquiry_status,
                    'refunded_amount'    => $sibs_payment['refunded_amount'],
                    'refund_information' => $errorMessage . (! empty($sibs_payment['refund_information']) ? ', ' . $sibs_payment['refund_information'] : ''),
                ]);

                throw new sibsException($errorMessage);
            }

            // Refund Inquiry Success
            $back_data['error'] = 0;
            $back_data['msg']   = sprintf(
                __('Refund success for order #%s with %s', sibsConstants::SIBS_TRANSLATE),
                $wc_order->get_id(),
                $amountMSG
            );

            wc_get_logger()->debug('[refund_inquiry] SUCCESS', sibsConstants::SIBS_LOG);
        } catch(sibsException $e) {
            $back_data['error'] = 1;
            $back_data['msg']   = $e->getErrorMessage();
        }

        return $back_data;
    }

    /**
     * SIBS: Cancel Authorization.
     *
     * @param int $order_id
     * @return array $back_data
     */
    public static function cancel_authorization($order_id)
    {
        $wc_order = new \WC_Order($order_id);
        wc_get_logger()->debug("[cancel_authorization] order_id: $order_id", sibsConstants::SIBS_LOG);

        try {
            $is_sibs_payment = self::sibs_is_sibs_by_order($order_id);

            if (! $is_sibs_payment) {
                throw new sibsException(
                    __('Order is not a SIBS payment', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $payment_status                 = 'wc-' . $wc_order->get_status();
            $status_to_cancel_authorization = [
                sibsConstants::SIBS_ORDER_STATUS_AUTHORIZED,
            ];

            if (! in_array($payment_status, $status_to_cancel_authorization)) {
                throw new sibsException(
                    __('Order is not on a status to cancel authorization', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $sibs_payment  = sibsGeneralModels::sibs_get_db_transaction_log($order_id);
            $payment_type  = sibsConstants::SPG_PAYMENT_TYPE_CAUT;
            $error_message = __('ERROR_GENERAL_CANCEL_AUTH_PAYMENT', sibsConstants::SIBS_TRANSLATE);
            $amount        = $wc_order->get_total();

            wc_get_logger()->debug('[cancel_authorization] sibs_payment: ' . wc_print_r($sibs_payment, true), sibsConstants::SIBS_LOG);
            wc_get_logger()->debug("[cancel_authorization] payment_type: $payment_type", sibsConstants::SIBS_LOG);

            $backoffice_config = self::get_backoffice_config(
                $sibs_payment,
                $payment_type,
                $amount,
                $error_message
            );

            $backoffice_result = self::sibs_do_back_office_payment($backoffice_config);

            if (! $backoffice_result['is_valid']) {
                throw new sibsException(
                    __('Cancel Authorization request has an ERROR', sibsConstants::SIBS_TRANSLATE)
                );
            }

            if ($backoffice_result['response']['paymentStatus'] !== sibsConstants::SIBS_RESULT_SUCCESS) {
                throw new sibsException(
                    __('Cancel Authorization request denied by SIBS', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $cancel_auth_status = $backoffice_config['order_status'];
            wc_get_logger()->debug('[cancel_authorization] SUCCESS', sibsConstants::SIBS_LOG);

            $note_message = __('Order was Canceled', sibsConstants::SIBS_TRANSLATE);

            try {
                $wc_order->update_status($cancel_auth_status);
            } catch (\Throwable $t) {
                wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
            }

            sibsGeneralModels::sibs_update_db_transaction($order_id, [
                'payment_status' => $cancel_auth_status,
            ]);

            // Add authorization cancel note
            $wc_order->add_order_note($note_message);

            // Authorization Canecled with Success
            $back_data['error'] = 0;
            $back_data['msg']   = sprintf(
                __('Authorization Canceled with success for order #%s', sibsConstants::SIBS_TRANSLATE),
                $wc_order->get_id()
            );
        } catch(sibsException $e) {
            $back_data['error'] = 1;
            $back_data['msg']   = $e->getErrorMessage();
        }

        return $back_data;
    }

    /**
     * SIBS: Refund Async.
     *
     * @param int $order_id
     * @return array $back_data
     */
    public static function async_refund($order_id)
    {
        $wc_order = new \WC_Order($order_id);

        wc_get_logger()->debug("[async_refund] order_id: $order_id", sibsConstants::SIBS_LOG);

        try {
            $is_sibs_payment = self::sibs_is_sibs_by_order($order_id);

            if (! $is_sibs_payment) {
                throw new sibsException(
                    __('Order is not a SIBS payment', sibsConstants::SIBS_TRANSLATE)
                );
            }

            $payment_status   = 'wc-' . $wc_order->get_status();
            $status_to_refund = [
                sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING,
                sibsConstants::WOOCOMMERCE_ORDER_STATUS_COMPLETED,
                sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_CAPTURED,
                sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_REFUNDED,
            ];

            if (! in_array($payment_status, $status_to_refund)) {
                throw new sibsException(
                    sprintf(
                        __('Order is cannot be refunded in status %s', sibsConstants::SIBS_TRANSLATE),
                        esc_attr($payment_status)
                    )
                );
            }

            $sibs_payment  = sibsGeneralModels::sibs_get_db_transaction_log($order_id);
            $payment_type  = sibsConstants::SPG_PAYMENT_TYPE_RFND;
            $error_message = __('ERROR_GENERAL_REFUND_PAYMENT', sibsConstants::SIBS_TRANSLATE);
            $amount        = $wc_order->get_total();

            wc_get_logger()->debug('[async_refund] sibs_payment: ' . wc_print_r($sibs_payment, true), sibsConstants::SIBS_LOG);
            wc_get_logger()->debug("[async_refund] payment_type: $payment_type", sibsConstants::SIBS_LOG);

            $backoffice_config = self::get_backoffice_config(
                $sibs_payment,
                $payment_type,
                $amount,
                $error_message
            );

            $backoffice_result = self::sibs_do_back_office_payment($backoffice_config);
            sibsGeneralModels::sibs_update_db_transaction($order_id, [
                'refunded_id'   => $backoffice_result['response']['transactionID'],
                'refund_status' => $backoffice_result['response']['paymentStatus'],
            ]);

            if (! $backoffice_result['is_valid']) {
                throw new sibsException(
                    __('Refund request has an ERROR', sibsConstants::SIBS_TRANSLATE)
                );
            }

            switch($backoffice_result['response']['paymentStatus']) {
                case sibsConstants::SIBS_RESULT_SUCCESS:
                    $refund_status = $backoffice_config['order_status'];
                    wc_get_logger()->debug('[async_refund] SUCCESS', sibsConstants::SIBS_LOG);

                    break;
                case sibsConstants::SIBS_RESULT_PENDING:
                    $refund_status = sibsConstants::SIBS_ORDER_STATUS_PENDING_REFUND;
                    wc_get_logger()->debug('[async_refund] PENDING', sibsConstants::SIBS_LOG);

                    break;
                default:
                    throw new sibsException(
                        __('Refund request denied by SIBS', sibsConstants::SIBS_TRANSLATE)
                    );
            }

            $amountMSG = "$amount {$wc_order->get_currency()}";

            $note_message = sprintf(
                __('Order is Pending for Refund with %s', sibsConstants::SIBS_TRANSLATE),
                $amountMSG
            );

            try {
                $wc_order->update_status($refund_status);
            } catch (\Throwable $t) {
                wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
            }

            sibsGeneralModels::sibs_update_db_transaction($order_id, [
                'payment_status'     => $refund_status,
                'refunded_amount'    => $backoffice_result['response']['amount']['value'] + $sibs_payment['refunded_amount'],
                'refund_information' => $note_message . (! empty($sibs_payment['refund_information']) ? ', ' . $sibs_payment['refund_information'] : ''),
            ]);

            if ($backoffice_result['response']['paymentStatus'] === sibsConstants::SIBS_RESULT_PENDING) {
                $back_data['msg'] = sprintf(
                    __('BLIK Refund is asyncronous, you have to make a refund inquiry to get the real refund status', sibsConstants::SIBS_TRANSLATE),
                    $wc_order->get_id()
                );
            } else {
                $back_data['msg'] = sprintf(
                    __('Refund success for order #%s with %s', sibsConstants::SIBS_TRANSLATE),
                    $wc_order->get_id(),
                    $amountMSG
                );
            }
            $back_data['error'] = 0;
        } catch(sibsException $e) {
            $back_data['error'] = 1;
            $back_data['msg']   = $e->getErrorMessage();
        }

        return $back_data;
    }

    private static function get_backoffice_config($sibs_payment, $payment_type, $amount, $error_message = 'Sibs Error')
    {
        $reference_id = $sibs_payment['reference_id'];

        switch($payment_type) {
            case sibsConstants::SPG_PAYMENT_TYPE_RVSL:
            case sibsConstants::SPG_PAYMENT_TYPE_CAUT:
                $order_status = sibsConstants::WOOCOMMERCE_ORDER_STATUS_CANCELLED;

                break;
            case sibsConstants::SPG_PAYMENT_TYPE_RFND:
                $order_status = self::get_order_refunded_status($sibs_payment['order_no'], $sibs_payment['payment_id']);

                if ($sibs_payment['payment_type'] === sibsConstants::SPG_PAYMENT_TYPE_AUTH) {
                    $reference_id = $sibs_payment['captured_id'];
                }

                break;
            default:
                $order_status = sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING;

                break;
        }

        $backoffice_config = [
            'order_no'      => $sibs_payment['order_no'],
            'payment_id'    => $sibs_payment['payment_id'],
            'reference_id'  => $reference_id,
            'currency'      => $sibs_payment['currency'],
            'payment_type'  => $payment_type,
            'order_status'  => $order_status,
            'error_message' => $error_message,
            'amount'        => $amount,
        ];

        return $backoffice_config;
    }

    private static function sibs_do_back_office_payment($backoffice_config)
    {
        $is_testmode_available     = true;
        $is_multichannel_available = true;

        wc_get_logger()->debug('[sibs_do_back_office_payment] backoffice_config: ' . wc_print_r($backoffice_config, true), sibsConstants::SIBS_LOG);

        $backoffice_parameter = sibsGeneralFunctions::sibs_get_credentials(
            $backoffice_config['payment_id'],
            $is_testmode_available,
            $is_multichannel_available
        );

        $backoffice_parameter = array_merge_recursive($backoffice_parameter, [
            'currency'     => $backoffice_config['currency'],
            'payment_type' => $backoffice_config['payment_type'],
            'amount'       => $backoffice_config['amount'],
        ]);

        wc_get_logger()->debug('[sibs_do_back_office_payment] backoffice_parameter: ' . wc_print_r($backoffice_parameter, true), sibsConstants::SIBS_LOG);

        $backoffice_result = \SibsPaymentCore::sibs_back_office_operation(
            $backoffice_config['reference_id'],
            $backoffice_parameter,
            $backoffice_config['order_no']
        );

        wc_get_logger()->debug('[sibs_do_back_office_payment] backoffice_result: ' . wc_print_r($backoffice_result, true), sibsConstants::SIBS_LOG);

        return $backoffice_result;
    }

    public function sibs_add_additional_information($order)
    {
        if (self::$added_meta_boxes) {
            return;
        }

        $order_id        = $order->get_id();
        $is_sibs_payment = self::sibs_is_sibs_by_order($order_id);

        if (! $is_sibs_payment) {
            return;
        }

        $args = [
            'transaction_log'        => sibsGeneralModels::sibs_get_db_transaction_log($order_id),
            'additional_information' => '',
        ];

        sibsGeneralFunctions::sibs_include_template(__DIR__ . '/../templates/admin/meta-boxes/template-additional-information.php', $args);
        self::$added_meta_boxes = true;
    }

    public function sibs_update_order_status($order)
    {
        $post_type = false;

        if (isset($_GET['post_type'])) {
            $post_type = wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['post_type'])));
        }

        if (! self::$updated_meta_boxes && $post_type !== sibsConstants::WOOCOMMERCE_POST_TYPE_SHOP_ORDER) {
            $order_id        = $order->get_id();
            $is_sibs_payment = self::sibs_is_sibs_by_order($order_id);

            if (! $is_sibs_payment) {
                return;
            }

            if ($order->get_status() === sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING) {
                $request_section = sibsGeneralFunctions::sibs_get_request_value('section', false);

                if ($request_section === 'update-order') {
                    $this->sibs_update_payment_status($order_id, sibsConstants::WOOCOMMERCE_ORDER_STATUS_ON_HOLD);
                    $redirect = get_admin_url() . "post.php?post=$order_id&action=edit";
                    wp_safe_redirect($redirect);

                    exit;
                }

                $args = ['order_id' => $order_id];
                sibsGeneralFunctions::sibs_include_template(__DIR__ . '/../templates/admin/meta-boxes/template-update-order.php', $args);
            }
            self::$updated_meta_boxes = true;
        }
    }

    public function sibs_rest_api_init()
    {
        register_rest_route(
            'sibs-stg',
            '/webhook',
            [
                'permission_callback' => '__return_true',
                'methods'             => 'POST',
                'callback'            => [&$this, 'sibs_webhook'],
            ]
        );
    }

    public function sibs_rest_api_log()
    {
        register_rest_route(
            'sibs-stg',
            '/webhook/log',
            [
                'permission_callback' => '__return_true',
                'methods'             => 'POST',
                'callback'            => [&$this, 'sibs_webhook_log'],
            ]
        );
    }

    public function sibs_add_payment_method($order)
    {
        if (! self::$added_payment_method) {
            $action   = sibsGeneralFunctions::sibs_get_request_value('action', 'false');
            $order_id = $order->get_id();

            if (! empty($order_id)) {
                $args = ['action' => $action];
                sibsGeneralFunctions::sibs_include_template(__DIR__ . '/../templates/admin/meta-boxes/template-add-payment-method.php', $args);
            }

            self::$added_payment_method = true;
        }
    }

    public function sibs_webhook_log()
    {
        try {
            $strRequest = file_get_contents('php://input');
            $Request    = json_decode($strRequest, true);
            wc_get_logger()->debug('WEBHOOK LOG: ' . wc_print_r($strRequest, true), sibsConstants::SIBS_DATA_LOG);
        } catch (Exception $e) {
        }
    }

    public function sibs_webhook()
    {
        // DECRYPT MESSAGE
        try {
            $result = self::sodium_decrypt();

            //TRANSFORED MESSAGE DECODED -> JSON TYPE MESSAGE
            $webhook_body = json_decode($result, true);

            // TODO: Demand OriginalTransactionID from webhook

            wc_get_logger()->debug('WEBHOOK BODY DECODED: ' . wc_print_r($webhook_body, true), sibsConstants::SIBS_WEBHOOK_LOG);

            $order_id       = $webhook_body['merchant']['transactonId'] ?? '';
            $transactionId  = $webhook_body['transactionID'] ?? '';
            $payment_method = $webhook_body['paymentMethod'] ?? '';
            $payment_status = $webhook_body['paymentStatus'] ?? '';
            $payment_type   = $webhook_body['paymentType'] ?? '';
            $amount_value   = $webhook_body['amount']['value'] ?? '';
            $notificationID = $webhook_body['notificationID'] ?? '';

            wc_get_logger()->debug("WEBHOOK transactionId: $transactionId", sibsConstants::SIBS_WEBHOOK_LOG);
            wc_get_logger()->debug("WEBHOOK payment_status: $payment_status", sibsConstants::SIBS_WEBHOOK_LOG);
            wc_get_logger()->debug("WEBHOOK payment_type: $payment_type", sibsConstants::SIBS_WEBHOOK_LOG);
            wc_get_logger()->debug("WEBHOOK amount_value: $amount_value", sibsConstants::SIBS_WEBHOOK_LOG);
            wc_get_logger()->debug("WEBHOOK notificationID: $notificationID", sibsConstants::SIBS_WEBHOOK_LOG);

            if ($transactionId === sibsConstants::WEBHOOK_TEST) {
                return self::webhook_success_response($notificationID);
            }

            $sibs_transaction = sibsGeneralModels::sibs_get_db_reference_id($transactionId);

            if (empty($sibs_transaction)) {
                $sibs_transaction = sibsGeneralModels::sibs_get_db_transaction_log($order_id);

                if (empty($sibs_transaction)) {
                    throw new sibsException("WEBHOOK Unknown Order #$order_id for $transactionId", sibsConstants::SIBS_WEBHOOK_LOG);
                }
            }

            wc_get_logger()->debug('WEBHOOK order_no: ' . $sibs_transaction['order_no'], sibsConstants::SIBS_WEBHOOK_LOG);

            if ($payment_method != $sibs_transaction['payment_brand']) {
                throw new sibsException('Invalid payment method', sibsConstants::SIBS_WEBHOOK_LOG);
            }

            if (in_array($payment_status, [sibsConstants::SIBS_RESULT_IN_PROCESSING, sibsConstants::SIBS_RESULT_PENDING])) {
                return self::webhook_success_response($notificationID);
            }

            switch($payment_type) {
                case sibsConstants::SPG_PAYMENT_TYPE_AUTH:
                case sibsConstants::SPG_PAYMENT_TYPE_PURS:
                    return $this->webhook_payment($sibs_transaction, $payment_status, $payment_type, $notificationID);

                    break;
                case sibsConstants::SPG_PAYMENT_TYPE_CAPT:
                    return $this->webhook_capture($sibs_transaction, $payment_status, $amount_value, $notificationID);

                    break;
                case sibsConstants::SPG_PAYMENT_TYPE_RFND:
                    return $this->webhook_refund($sibs_transaction, $payment_status, $amount_value, $notificationID);

                    break;
                default:
                    throw new sibsException('Invalid payment type', sibsConstants::SIBS_WEBHOOK_LOG);
            }
        } catch (sibsException $e) {
            return self::webhook_error_response(400, $e->getErrorMessage());
        } catch (\Exception $e) {
            wc_get_logger()->error('Fatal Error: ' . $e->getMessage(), sibsConstants::SIBS_WEBHOOK_LOG);

            return self::webhook_error_response(500, $e->getMessage());
        }
    }

    private function webhook_payment($sibs_transaction, $payment_status, $payment_type, $notificationID)
    {
        $order        = wc_get_order($sibs_transaction['order_no']);
        $order_status = sibsGeneralFunctions::convertTransactionStatus($payment_status, $payment_type);

        sibsGeneralModels::sibs_update_db_transaction_by_reference_id($sibs_transaction['reference_id'], [
            'payment_status' => $order_status,
        ]);

        wc_get_logger()->debug("WEBHOOK order_status: $order_status", sibsConstants::SIBS_WEBHOOK_LOG);

        if (sibsGeneralFunctions::isAlreadyPaidOrAuthorized('wc-' . $order->get_status())) {
            // Don't need to change the status
            return self::webhook_success_response($notificationID);
        }

        switch($order_status) {
            case sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING:
            case sibsConstants::SIBS_ORDER_STATUS_AUTHORIZED:
                try {
                    $order->update_status($order_status);
                } catch (\Throwable $t) {
                    wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
                }

                wc_get_logger()->debug('Reduce Stock webhook', sibsConstants::SIBS_WEBHOOK_LOG);
                wc_reduce_stock_levels($order->get_id());

                break;
            case sibsConstants::WOOCOMMERCE_ORDER_STATUS_ON_HOLD:
                try {
                    $order->update_status($order_status);
                } catch (\Throwable $t) {
                    wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
                }

                wc_increase_stock_levels($order->get_id());

                break;
            default:
                $errorMessage = 'WEBHOOK operation failed.';
                $order->add_order_note($errorMessage);
        }

        wc_get_logger()->debug('WEBHOOK Payment operation with success.', sibsConstants::SIBS_WEBHOOK_LOG);

        return self::webhook_success_response($notificationID);
    }

    private function webhook_capture($sibs_transaction, $capture_status, $notificationID, $amount_value)
    {
        $order = wc_get_order($sibs_transaction['order_no']);

        if (sibsGeneralFunctions::isAlreadyCaptured('wc-' . $order->get_status())) {
            // Don't need to change the status
            return self::webhook_success_response($notificationID);
        }

        $note_message = ($capture_status === sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED) ?
            __('WEBHOOK Capture operation failed.', sibsConstants::SIBS_TRANSLATE) :
            sprintf(
                __('Order was Captured for %s', sibsConstants::SIBS_TRANSLATE),
                $amount_value . ' ' . $order->get_currency()
            );

        $orderRemainingCapture = $order->get_total() - $sibs_transaction['captured_amount'];
        wc_get_logger()->debug('WEBHOOK order remaining Capture: ' . $orderRemainingCapture, sibsConstants::SIBS_WEBHOOK_LOG);

        $order_status = ($amount_value >= $orderRemainingCapture) ?
            sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING :
            sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_CAPTURED;

        try {
            $order->update_status($order_status);
        } catch (\Throwable $t) {
            wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
        }

        $order->add_order_note($note_message);

        sibsGeneralModels::sibs_update_db_transaction($sibs_transaction['order_no'], [
            'payment_status'      => $order_status,
            'capture_status'      => sibsGeneralFunctions::convertTransactionStatusCaptRfnd($capture_status),
            'captured_amount'     => $amount_value + $sibs_transaction['captured_amount'],
            'capture_information' => $note_message .
                (! empty($sibs_transaction['capture_information']) ? ', ' . $sibs_transaction['capture_information'] : ''),
        ]);

        wc_get_logger()->debug('WEBHOOK Refund operation with success.', sibsConstants::SIBS_WEBHOOK_LOG);

        return self::webhook_success_response($notificationID);
    }

    private function webhook_refund($sibs_transaction, $refund_status, $amount_value, $notificationID)
    {
        $order = wc_get_order($sibs_transaction['order_no']);

        if (sibsGeneralFunctions::isAlreadyRefunded('wc-' . $order->get_status())) {
            // Don't need to change the status
            return self::webhook_success_response($notificationID);
        }

        $note_message = ($refund_status === sibsConstants::WOOCOMMERCE_ORDER_STATUS_FAILED) ?
            __('WEBHOOK Refund operation failed.', sibsConstants::SIBS_TRANSLATE) :
            sprintf(
                __('Order was Refunded for %s', sibsConstants::SIBS_TRANSLATE),
                $amount_value . ' ' . $order->get_currency()
            );

        $orderRemainingRefund = $order->get_total() - $order->get_total_refunded();
        wc_get_logger()->debug('WEBHOOK order remaining Refund: ' . $orderRemainingRefund, sibsConstants::SIBS_WEBHOOK_LOG);

        $order_status = ($amount_value >= $orderRemainingRefund) ?
            sibsConstants::WOOCOMMERCE_ORDER_STATUS_REFUNDED :
            sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_REFUNDED;

        try {
            $order->update_status($order_status);
        } catch (\Throwable $t) {
            wc_get_logger()->critical($t->getMessage(), sibsConstants::SIBS_LOG);
        }

        $order->add_order_note($note_message);

        sibsGeneralModels::sibs_update_db_transaction($sibs_transaction['order_no'], [
            'payment_status'     => $order_status,
            'refund_status'      => sibsGeneralFunctions::convertTransactionStatusCaptRfnd($refund_status),
            'refunded_amount'    => $amount_value + $sibs_transaction['refunded_amount'],
            'refund_information' => $note_message .
                (! empty($sibs_transaction['refund_information']) ? ', ' . $sibs_transaction['refund_information'] : ''),
        ]);

        wc_get_logger()->debug('WEBHOOK Refund operation with success.', sibsConstants::SIBS_WEBHOOK_LOG);

        return self::webhook_success_response($notificationID);
    }

    private function webhook_success_response($notificationId)
    {
        return [
            'statusCode'     => '200',
            'statusMsg'      => sibsConstants::SIBS_RESULT_SUCCESS,
            'notificationID' => $notificationId,
        ];
    }

    private function webhook_error_response($error_code = 400, $error_message)
    {
        return [
            'statusCode' => $error_code,
            'statusMsg'  => $error_message,
        ];
    }

    private function sodium_decrypt()
    {
        $webhookSecret = get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_general_webhook_secret');

        if (empty($webhookSecret)) {
            throw new sibsException('Webhook Secret not defined', sibsConstants::SIBS_WEBHOOK_LOG);
        }

        $iv_from_http_header       = $_SERVER['HTTP_X_INITIALIZATION_VECTOR'] ?? '';
        $auth_tag_from_http_header = $_SERVER['HTTP_X_AUTHENTICATION_TAG'] ?? '';

        if (empty($iv_from_http_header)) {
            throw new sibsException('X-Initialization-Vector not present in header', sibsConstants::SIBS_WEBHOOK_LOG);
        }

        if (empty($auth_tag_from_http_header)) {
            throw new sibsException('X-Authentication-Tag not present in header', sibsConstants::SIBS_WEBHOOK_LOG);
        }

        wc_get_logger()->debug('WEBHOOK BODY X-Authentication-Tag: ' . wc_print_r($auth_tag_from_http_header, true), sibsConstants::SIBS_WEBHOOK_LOG);
        wc_get_logger()->debug('WEBHOOK BODY X-Initialization-Vector: ' . wc_print_r($iv_from_http_header, true), sibsConstants::SIBS_WEBHOOK_LOG);

        $http_body = file_get_contents('php://input');

        if (empty($http_body)) {
            throw new sibsException('Body is empty', sibsConstants::SIBS_WEBHOOK_LOG);
        }

        wc_get_logger()->debug('WEBHOOK BODY ENCODED: ' . wc_print_r($http_body, true), sibsConstants::SIBS_WEBHOOK_LOG);

        $dir = plugin_dir_path(__DIR__) .
          DIRECTORY_SEPARATOR . 'external' .
          DIRECTORY_SEPARATOR . 'sodium_compat-1.7.0' .
          DIRECTORY_SEPARATOR . 'autoload.php';

        $result      = '';
        $key         = mb_convert_encoding($webhookSecret, 'UTF-8', 'BASE64');
        $iv          = mb_convert_encoding($iv_from_http_header, 'UTF-8', 'BASE64');
        $cipher_text = mb_convert_encoding($http_body, 'UTF-8', 'BASE64') . mb_convert_encoding($auth_tag_from_http_header, 'UTF-8', 'BASE64');

        if (file_exists(stream_resolve_include_path($dir))) {
            require_once $dir;
        } else {
            throw new sibsException('sodium lib not found in: ' . $dir, sibsConstants::SIBS_WEBHOOK_LOG);
        }

        if (function_exists('sodium_crypto_aead_aes256gcm_decrypt')) {
            $result = sodium_crypto_aead_aes256gcm_decrypt($cipher_text, '', $iv, $key);
        } else {
            throw new sibsException('sodium lib not available', sibsConstants::SIBS_WEBHOOK_LOG);
        }

        //ERROR WHEN DECRYPTION FAILS
        if ($result === false) {
            throw new sibsException('Bad ciphertext', sibsConstants::SIBS_WEBHOOK_LOG);
        }

        return $result;
    }

    private function sibs_add_customer_note($payment_id, $order_id)
    {
        $wc_order      = new \WC_Order($order_id);
        $customer_note = $wc_order->get_customer_note();

        $new_line         = "\n";
        $payment_comments = sibsGeneralFunctions::sibs_translate_frontend_payment($payment_id) . $new_line;

        if (! empty($wc_order->get_customer_note())) {
            $customer_note .= $new_line;
        }

        $customer_note .= html_entity_decode($payment_comments, ENT_QUOTES, 'UTF-8');
        $order_notes = [
            'ID'           => $wc_order->get_id(),
            'post_excerpt' => $customer_note,
        ];
        wp_update_post($order_notes);
    }

    private function sibs_set_customer_parameters($order_id)
    {
        $wc_order = new \WC_Order($order_id);

        $customer['first_name'] = $wc_order->get_billing_first_name();
        $customer['last_name']  = $wc_order->get_billing_last_name();
        $customer['email']      = $wc_order->get_billing_email();

        $phone_payments = [
            sibsConstants::SIBS_PAYMENT_METHOD_ORDER_KLARNAINS,
            sibsConstants::SIBS_PAYMENT_METHOD_ORDER_KLARNAINV,
            sibsConstants::SIBS_PAYMENT_METHOD_ORDER_EASYCREDIT,
            sibsConstants::SIBS_PAYMENT_METHOD_ORDER_BLIK,
            sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAY_BY_LINK,
            sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAY_BY_LINK_KEVIN,
        ];

        if (in_array($this->payment_id, $phone_payments)) {
            $customer['phone'] = $wc_order->get_billing_phone();
        }

        return $customer;
    }

    private function sibs_set_billing_parameters($order_id)
    {
        $wc_order = new \WC_Order($order_id);

        if (! $wc_order->has_billing_address()) {
            return [
                'country_code' => $wc_order->get_shipping_country(),
                'city'         => $wc_order->get_shipping_city(),
                'zip'          => $wc_order->get_shipping_postcode(),
                'street'       => $wc_order->get_formatted_shipping_address(),
            ];
        }

        return [
            'country_code' => $wc_order->get_billing_country(),
            'city'         => $wc_order->get_billing_city(),
            'zip'          => $wc_order->get_billing_postcode(),
            'street'       => $wc_order->get_formatted_billing_address(),
        ];
    }

    private function sibs_set_shipping_parameters($order_id)
    {
        $wc_order = new \WC_Order($order_id);

        if (! $wc_order->has_shipping_address()) {
            return [
                'country_code' => $wc_order->get_billing_country(),
                'city'         => $wc_order->get_billing_city(),
                'zip'          => $wc_order->get_billing_postcode(),
                'street'       => $wc_order->get_formatted_billing_address(),
            ];
        }

        return [
            'country_code' => $wc_order->get_shipping_country(),
            'city'         => $wc_order->get_shipping_city(),
            'zip'          => $wc_order->get_shipping_postcode(),
            'street'       => $wc_order->get_formatted_shipping_address(),
        ];
    }

    protected function sibs_set_payment_parameters($order_id)
    {
        $wc_order     = new \WC_Order($order_id);
        $order_number = $wc_order->get_order_number();

        $now = new \DateTime();

        $terminalId             = intval(get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_general_merchant_no'));
        $transactionDescription = "Transaction for order number $order_number terminalId $terminalId";
        $shopURL                = get_permalink(wc_get_page_id('shop'));

        $this->payment_type = sibsGeneralFunctions::sibs_get_payment_type($this->payment_id);

        $customer_data     = $this->sibs_set_customer_parameters($order_id);
        $costumer_language = sibsFunctions::get_language();
        wc_get_logger()->info('customer_data: ' . wc_print_r($customer_data, true), sibsConstants::SIBS_LOG);

        $costumer_info_shipping = $this->sibs_set_shipping_parameters($order_id);
        $costumer_info_billing  = $this->sibs_set_billing_parameters($order_id);

        $payment_parameters = [
            'merchant' => [
                'terminalId'             => $terminalId,
                'channel'                => 'web',
                'merchantTransactionId'  => $order_number,
                'transactionDescription' => $transactionDescription,
                'shopURL'                => $shopURL,
            ],
            'transaction' => [
                'transactionTimestamp' => $now->format(DATE_FORMAT),
                'description'          => $transactionDescription,
                'moto'                 => get_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_general_moto') == 0 ? false : true,
                'paymentType'          => $this->payment_type,
                'amount'               => [
                    'value'    => floatval(sibsFunctions::sibs_set_number_format($this->get_order_total())),
                    'currency' => get_woocommerce_currency(),
                ],
            ],
            'customer' => [
                'customerInfo' => [
                    'customerName'     => "{$customer_data['first_name']} {$customer_data['last_name']}",
                    'customerEmail'    => $customer_data['email'],
                    'customerLanguage' => $costumer_language,
                    'shippingAddress'  => [
                        'street1'  => $wc_order->get_shipping_address_1(),
                        'street2'  => $wc_order->get_shipping_address_2(),
                        'city'     => $costumer_info_shipping['city'],
                        'postcode' => $costumer_info_shipping['zip'],
                        'country'  => $costumer_info_shipping['country_code'],
                    ],
                    'billingAddress' => [
                        'street1'  => $wc_order->get_billing_address_1(),
                        'street2'  => $wc_order->get_billing_address_2(),
                        'city'     => $costumer_info_billing['city'],
                        'postcode' => $costumer_info_billing['zip'],
                        'country'  => $costumer_info_billing['country_code'],
                    ],
                ],
            ],
            'info' => [
                'deviceInfo' => [
                    'applicationName'    => 'woocommerce:' . WC()->version ?? 'N/A',
                    'applicationVersion' => constant('SIBS_VERSION'),
                ],
            ],
        ];

        $payment_parameters = array_merge_recursive($payment_parameters, $this->sibs_set_payment_parameters_by_payment_method($now));

        if (get_current_user_id()) {
            $payment_parameters = array_merge_recursive($payment_parameters, $this->get_checkout_parameter_oneclick());
        }

        wc_get_logger()->info('payment_parameters: ' . wc_print_r($payment_parameters, true), sibsConstants::SIBS_LOG);

        return $payment_parameters;
    }

    private function sibs_set_payment_parameters_by_payment_method($now)
    {
        $parameters = [];

        wc_get_logger()->info('sibs_set_payment_parameters_by_payment_method: ' . $this->payment_id, sibsConstants::SIBS_LOG);

        switch($this->payment_id) {
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAY_BY_LINK:
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAY_BY_LINK_KEVIN:
                $settings    = get_option("woocommerce_{$this->payment_id}_settings");
                $abs_number  = abs(intval(sibsConstants::SIBS_PAYMENT_DATE_VALUE));
                $date_offset = +$abs_number . ' ' . sibsConstants::SIBS_PAYMENT_DATE_UNIT;

                $now->modify($date_offset);

                $parameters = [
                    'transaction' => [
                        'paymentMethod' => [
                            sibsGeneralFunctions::sibs_spg_get_payment_method($this->payment_id),
                        ],
                        'payByLink' => [
                            'expirationDateTime'     => $now->format(DATE_FORMAT),
                            'linkExpirationDateTime' => $now->format(DATE_FORMAT),
                        ],
                    ],
                ];

                break;
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD:
                $credentials   = sibsGeneralFunctions::sibs_get_credentials($this->payment_id);
                $registrations = sibsGeneralModels::sibs_get_db_registered_payment($this->payment_group, $credentials);
                $parameters    = array_merge_recursive($parameters, $this->get_payment_registrations($registrations));
                // break;
            default:
                $parameters = array_merge_recursive($parameters, [
                    'transaction' => [
                        'paymentMethod' => [
                            sibsGeneralFunctions::sibs_spg_get_payment_method($this->payment_id),
                        ],
                    ],
                ]);

                break;
        }

        return $parameters;
    }

    private function get_payment_registrations($registrations)
    {
        $parameters = [];

        if (! empty($registrations)) {
            foreach ($registrations as $key => $value) {
                $parameters["registrations[$key].id"] = $value['reg_id'];
            }
        }

        return $parameters;
    }

    private function get_checkout_parameter_oneclick()
    {
        $oneclickParameters = [];
        $tokenMethods       = [
            sibsConstants::SIBS_PAYMENT_METHOD_CARD,
        ];

        if (in_array(sibsGeneralFunctions::sibs_spg_get_payment_method($this->payment_id), $tokenMethods)) {
            $settings = get_option('woocommerce_' . sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD . '_settings');
            $oneclick = $settings['tokenization'];

            switch($oneclick) {
                case sibsConstants::SIBS_TOKEN_TOKENIZATION:
                    $tokeniseCard       = true;
                    $customerAcceptance = false;
                    $paymentTokens      = sibsGeneralModels::sibs_get_current_user_card_tokens();

                    break;
                case sibsConstants::SIBS_TOKEN_ONECLICK:
                    if (WC()->session->__isset(sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_customer_acceptor')) {
                        $tokeniseCard       = WC()->session->get(sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_customer_acceptor');
                        $customerAcceptance = WC()->session->get(sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_customer_acceptor');
                        $paymentTokens      = WC()->session->get(sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_customer_acceptor') ?
                            sibsGeneralModels::sibs_get_current_user_card_tokens() :
                            [];

                        break;
                    }
                case sibsConstants::SIBS_TOKEN_NONE:
                default:
                    $tokeniseCard       = false;
                    $customerAcceptance = false;
                    $paymentTokens      = [];
            }

            $oneclickParameters = [
                'transaction' => [
                    'oneClick' => [
                        'customerAcceptance' => $customerAcceptance,
                    ],
                ],
                'tokenisation' => [
                    'tokenisationRequest' => [
                        'tokeniseCard' => $tokeniseCard,
                    ],
                    'paymentTokens' => $paymentTokens,
                ],
            ];
        }

        return $oneclickParameters;
    }

    protected function sibs_save_or_update_transactions($order_id, $payment_result, $is_confirm_page = false)
    {
        $local_payment_method = ! empty($payment_result['paymentMethod']) ?
                $payment_result['paymentMethod'] :
                $this->payment_brand;

        wc_get_logger()->debug('payment_result: ' . wc_print_r($payment_result, true), sibsConstants::SIBS_LOG);
        wc_get_logger()->debug('reference_id:' . $payment_result['transactionID'], sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("payment_id: {$this->payment_id}", sibsConstants::SIBS_LOG);
        wc_get_logger()->debug("payment_brand: {$local_payment_method}", sibsConstants::SIBS_LOG);

        $wc_order = new \WC_Order($order_id);
        $this->sibs_add_customer_note($this->payment_id, $order_id);

        $payment_status = sibsGeneralFunctions::convertTransactionStatus(
            $payment_result['paymentStatus'],
            $this->payment_type
        );

        $locale_info = localeconv();

        $transaction = [
            'order_no'               => $wc_order->get_order_number(),
            'customer_id'            => ($wc_order->get_user_id()) ? $wc_order->get_user_id() : get_current_user_id(),
            'reference_id'           => $payment_result['transactionID'],
            'payment_id'             => $this->payment_id,
            'payment_type'           => $this->payment_type,
            'payment_brand'          => $local_payment_method,
            'payment_status'         => $payment_status,
            'date'                   => date('Y-m-d H:i:s'),
            'currency'               => get_woocommerce_currency(),
            'amount'                 => number_format(str_replace($locale_info['decimal_point'], '.', $this->get_order_total()), 2, '.', ''),
            'additional_information' => '',
        ];
        wc_get_logger()->debug('transaction: ' . wc_print_r($transaction, true), sibsConstants::SIBS_LOG);

        $transaction_saved = sibsGeneralModels::sibs_create_or_update_db_transaction($transaction);
        wc_get_logger()->info('transaction_saved: ' . ($transaction_saved ? 'yes' : 'no'), sibsConstants::SIBS_LOG);

        if ($is_confirm_page) {
            // save credit card info (!This won't happen in SPG because card info is never sent!)
            $this->sibs_save_credit_card_info($payment_result, $local_payment_method);

            // save token info
            $this->sibs_token_info($payment_result, $local_payment_method);
        }
    }

    protected function sibs_save_credit_card_info($payment_result, $local_payment_method)
    {
        if (isset($payment_result['card']) && isset($payment_result['registrationId'])) {
            //get cards from user
            $credentials                         = sibsGeneralFunctions::sibs_get_credentials($this->payment_id);
            $payment_parameters['registrations'] = sibsGeneralModels::sibs_get_db_registered_payment($this->payment_group, $credentials);
            $cardExist                           = false;

            //if there is cards for the user
            if ($payment_parameters['registrations'] !== null) {
                foreach ($payment_parameters['registrations'] as $value) {
                    // if the card dont exist
                    if ($value['last4digits'] == $payment_result['card']['last4Digits'] &&
                      $value['brand'] == $local_payment_method &&
                      $value['expiry_month'] == $payment_result['card']['expiryMonth'] &&
                      $value['expiry_year'] == $payment_result['card']['expiryYear'] &&
                      $value['holder'] == $payment_result['card']['holder']
                    ) {
                        $cardExist = true;

                        break;
                    }
                }

                // if the card does not exist, add
                if ($cardExist == false) {
                    $recurring_saved = $this->sibs_save_recurring_card_payment($payment_result);
                    wc_get_logger()->info('recurring_saved (1): ' . ($recurring_saved ? 'yes' : 'no'), sibsConstants::SIBS_LOG);
                }
            } else {
                $recurring_saved = $this->sibs_save_recurring_card_payment($payment_result);
                wc_get_logger()->info('recurring_saved (2): ' . ($recurring_saved ? 'yes' : 'no'), sibsConstants::SIBS_LOG);
            }
        }
    }

    protected function sibs_save_recurring_card_payment($payment_result)
    {
        $is_registered_payment = sibsGeneralModels::sibs_is_registered_payment_db($payment_result['registrationId']);

        if (! $is_registered_payment) {
            $credentials                           = sibsGeneralFunctions::sibs_get_credentials($this->payment_id);
            $registered_payment['payment_group']   = $this->payment_group;
            $registered_payment['payment_brand']   = $payment_result['paymentBrand'];
            $registered_payment['server_mode']     = $credentials['server_mode'];
            $registered_payment['channel_id']      = $credentials['channel_id'];
            $registered_payment['registration_id'] = $payment_result['registrationId'];
            $registered_payment['payment_default'] = sibsGeneralModels::sibs_get_db_payment_default($this->payment_group, $credentials);

            // Credit Card
            $registered_payment['holder']          = $payment_result['card']['holder'];
            $registered_payment['email']           = $payment_result['customer']['email'];
            $registered_payment['last_4_digits']   = $payment_result['card']['last4Digits'];
            $registered_payment['expiry_month']    = $payment_result['card']['expiryMonth'];
            $registered_payment['expiry_year']     = $payment_result['card']['expiryYear'];

            wc_get_logger()->debug("registered_payment: $registered_payment", sibsConstants::SIBS_LOG);

            return sibsGeneralModels::sibs_save_db_registered_payment($registered_payment);
        }

        return true;
    }

    protected function sibs_token_info($payment_result)
    {
        $hasToken = isset($payment_result['token']);
        wc_get_logger()->info('hasToken ' . var_export($hasToken, true), sibsConstants::SIBS_LOG);

        if ($hasToken) {
            $token = $payment_result['token'];
            wc_get_logger()->debug('token: ' . print_r($token, true), sibsConstants::SIBS_LOG);

            $token_saved = sibsGeneralModels::sibs_save_or_update_db_token($token);
            wc_get_logger()->info('token_saved: ' . ($token_saved ? 'yes' : 'no'), sibsConstants::SIBS_LOG);
        }
    }

    private function sibs_add_order_notes($order_id, $status_name)
    {
        $user = get_user_by('id', get_current_user_id());

        $comments['order_id'] = $order_id;
        $comments['author']   = $user->display_name;
        $comments['email']    = $user->user_email;
        $comments['content']  = sprintf(
            __('Order status changed from %s to %s.', sibsConstants::SIBS_TRANSLATE),
            $status_name['original'],
            $status_name['new']
        );

        sibsGeneralModels::sibs_save_db_order_notes($comments);
    }

    public static function sibs_wpb_thankyou_text($thankyoutext, $order)
    {
        $payment_gateways = $order->get_payment_method();
        $orderStatus      = 'wc-' . $order->get_status();
        $orderIsPaid      = ($orderStatus == sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING);

        wc_get_logger()->debug('Thank You Payment Gateway: ' . $payment_gateways, sibsConstants::SIBS_LOG);

        switch ($payment_gateways) {
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAY_BY_LINK:
                $file       = esc_attr(plugins_url('../assets/images/pbl.png', __FILE__));
                $added_text = $orderIsPaid ?
                    __('<p>The payment was finalized using Pay By Link</p>', sibsConstants::SIBS_TRANSLATE) :
                    __('<p>Your Pay By Link payment is pending. You will receive an e-mail when your payment status changes.</p>', sibsConstants::SIBS_TRANSLATE);

                break;
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_PAY_BY_LINK_KEVIN:
                $file       = esc_attr(plugins_url('../assets/images/pbl.png', __FILE__));
                $added_text = $orderIsPaid ?
                    __('<p>The payment was finalized using Pay By Link Kevin</p>', sibsConstants::SIBS_TRANSLATE) :
                    __('<p>Your Pay By Link Kevin payment is pending. You will receive an e-mail when your payment status changes.</p>', sibsConstants::SIBS_TRANSLATE);

                break;
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_BLIK:
                $file       = esc_attr(plugins_url('../assets/images/blik.png', __FILE__));
                $added_text = $orderIsPaid ?
                    __('<p>The payment was finalized using BLIK</p>', sibsConstants::SIBS_TRANSLATE) :
                    __('<p>Your BLIK payment is pending. You will receive an e-mail when your payment status changes.</p>', sibsConstants::SIBS_TRANSLATE);

                break;
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD:
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD_SAVED:
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_DEBIT_CARD:
            case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_DEBIT_CARD_SAVED:
                $file       = esc_attr(plugins_url('../assets/images/cards.png', __FILE__));
                $added_text = $orderIsPaid ?
                    __('<p>The payment was finalized using SIBS Card</p>', sibsConstants::SIBS_TRANSLATE) :
                    __('<p>Your SIBS Card payment is pending. You will receive an e-mail when your payment status changes.</p>', sibsConstants::SIBS_TRANSLATE);

                break;
            default:
                $file       = null;
                $added_text = '';

                wc_get_logger()->warning('Unrecognized payment type', sibsConstants::SIBS_LOG);
        }

        $image = (! is_null($file)) ?
        "<p>
            <img src=\"$file\" style=\"height:40px; max-height:40px; margin:5px 10px 5px 0; float: none; vertical-align: middle;\"/>
        </p>" : '';

        return $image . $thankyoutext . $added_text;
    }

    public function checkout_result_to_data($checkout_response)
    {
        return [
            'transactionID' => $checkout_response['transactionID'],
            'paymentStatus' => sibsConstants::SIBS_RESULT_PENDING,
            'paymentMethod' => $checkout_response['paymentMethodList'][0] ?? '',
        ];
    }

    public static function sibs_status_inquiry_order_add_button($order)
    {
        $order_id = esc_attr($order->get_id());
        self::print_button($order_id, '1', esc_attr(__('SIBS Check Status', sibsConstants::SIBS_TRANSLATE)));
    }

    public static function sibs_capture_order_add_button($order)
    {
        $order_id = esc_attr($order->get_id());
        self::print_button($order_id, '2', esc_attr(__('SIBS Capture', sibsConstants::SIBS_TRANSLATE)));
    }

    public static function sibs_refund_inquiry_order_add_button($order)
    {
        $order_id = esc_attr($order->get_id());
        self::print_button($order_id, '3', esc_attr(__('SIBS Refund Inquiry', sibsConstants::SIBS_TRANSLATE)));
    }

    public static function sibs_cancel_authorization_order_add_button($order)
    {
        $order_id = esc_attr($order->get_id());
        self::print_button($order_id, '4', esc_attr(__('SIBS Cancel Authorization', sibsConstants::SIBS_TRANSLATE)));
    }

    public static function sibs_refund_async_order_add_button($order)
    {
        $order_id = esc_attr($order->get_id());
        self::print_button($order_id, '5', esc_attr(__('SIBS Async Refund', sibsConstants::SIBS_TRANSLATE)));
    }

    public static function print_button($order_id, $button_id, $label)
    {
        echo "<button
      type=\"button\"
      style=\"margin-right: 2px\"
      class=\"button sibs-button\"
      data-order_id=\"$order_id\"
      data-button_id=\"$button_id\">
      <b>$label</b>
    </button>";
    }

    public static function print_input($scenario, $class, $name, $placeholder = 'Enter Value', $type = 'text', $value = '')
    {
        echo "<input
      type=\"$type\"
      style=\"margin-right: 2px\"
      class=\"$class\"
      name=\"$name\"
      data-scenario=\"$scenario\"
      placeholder=\"$placeholder\"
      value=\"$value\"/>";
    }
}
