<?php

/**
 * Plugin Name: SIBS Payment Gateway for WooCommerce
 * Description: WooCommerce with SIBS Payment Gateway
 * Author:      SIBS
 * Text Domain: sibs-woo-stg
 * Author URI:  http://www.sibs.pt/
 * Version:     2.16.4
 * Requires Plugins: woocommerce
 * PHP requires at least: 7.4
 * PHP tested up to: 8.3.x
 * Wordpress requires at least: 5.9
 * Wordpress tested up to: 6.8.x
 * WooCommerce requires at least: 7.4.1
 * WooCommerce tested up to: 10.3.x.
 * Requires at least: 6.5
 * Requires PHP: 7.4.
 */
require_once __DIR__ . '/vendor/autoload.php';

define('SIBS_VERSION', '2.16.4');
define('SIBS_PLUGIN_FILE', __FILE__);
define('SIBS_PLUGIN_DIR', plugins_url('/', __FILE__));
define('DATE_FORMAT', "Y-m-d\TH:i:s.vP"); // TODO: por algum motivo no pay by link nao esta a pegar isso
define('WC_GATEWAY_SIBS_URL', untrailingslashit(plugins_url(basename(plugin_dir_path(__FILE__)), basename(__FILE__))));
define('WC_GATEWAY_SIBS_PATH', untrailingslashit(plugin_dir_path(__FILE__)));

use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
use Sibs2\sibsConfig;
use Sibs2\sibsConstants;
use Sibs2\sibsException;
use Sibs2\sibsFunctions;
use Sibs2\sibsGeneralFunctions;
use Sibs2\sibsGeneralModels;
use Sibs2\sibsLogger;
use Sibs2\sibsPaymentGateway;

defined('ABSPATH') || exit;

require_once __DIR__ . '/sibs-install.php';
require_once __DIR__ . '/sibs-additional.php';

// Incluir arquivo de administração
// Incluir nova estrutura de administração
add_action('plugins_loaded', function() {
    if (is_admin()) {
        //require_once __DIR__ . '/includes/admin/class-sibs-admin.php';
    }
}, 10);

register_activation_hook(__FILE__, 'sibs_activation_process');
register_deactivation_hook(__FILE__, 'sibs_deactivation_process');
register_uninstall_hook(__FILE__, 'sibs_uninstallation_process');

add_action('init', 'sibs_stg_init_payment_gateway'); // https://developer.wordpress.org/reference/hooks/init/
add_action('plugins_loaded', 'sibs_stg_plugins_loaded'); // https://developer.wordpress.org/reference/hooks/plugins_loaded/
add_action('wp_ajax_registered_payment', 'sibs_get_ajax_registered_payment'); // https://developer.wordpress.org/reference/hooks/wp_ajax_action/
add_action('admin_head', 'sibs_hide_wc_refund_button'); // https://wp-kama.ru/hook/admin_head
add_action('woocommerce_order_item_add_action_buttons', 'sibs_add_admin_buttons');  // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_order_item_add_action_buttons
add_action('wp_ajax_add_button_to_order_admin', 'sibs_ajax_add_button_to_order_admin'); // https://developer.wordpress.org/reference/hooks/wp_ajax_action/
add_action('woocommerce_cancel_unpaid_orders', 'sibs_cancel_onhold_orders'); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_cancel_unpaid_order
add_action('sibs_schedule_every_five_minutes', 'sibs_process_webhook_calls');
add_action('woocommerce_review_order_before_submit', 'sibs_woocommerce_review_order_before_submit_action'); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_review_order_before_submit
add_action('woocommerce_checkout_process', 'sibs_woocommerce_checkout_process_action', 10, 1); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_checkout_process
add_action('wp_footer', 'sibs_footer'); // https://developer.wordpress.org/reference/hooks/wp_footer/
add_action('admin_enqueue_scripts', 'sibs_admin_scripts'); // https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/
add_action('wp_enqueue_scripts', 'sibs_wordpress_scripts'); // https://developer.wordpress.org/reference/hooks/wp_enqueue_scripts/
add_action('wp_head', 'ti_custom_javascript'); // https://developer.wordpress.org/reference/functions/wp_head/
add_action('woocommerce_blocks_loaded', 'sibs_woocommerce_blocks_support'); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_blocks_loaded]

add_filter('plugin_row_meta', 'sibs_plugin_row_meta', 10, 2); // https://developer.wordpress.org/reference/hooks/plugin_row_meta/
add_filter('woocommerce_locate_template', 'sibs_override_woocommerce_template', 10, 3); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_locate_template
add_filter('cron_schedules', 'sibs_schedule_every_five_minutes'); // https://wp-kama.com/hook/cron_schedules

// Schedule an action if it's not already scheduled
if (! wp_next_scheduled('sibs_schedule_every_five_minutes')) {
    wp_schedule_event(time(), 'every_five_minutes', 'sibs_schedule_every_five_minutes');
}

/**
 * Hook to schedule every five minutes.
 */
function sibs_schedule_every_five_minutes()
{
    $schedules['every_five_minutes'] = [
        'interval'  => 60 * 5,
        'display'   => __('Every 5 Minutes', 'textdomain'),
    ];

    return $schedules;
}

/**
 * hook to init sibs gateway.
 */
function sibs_stg_init_payment_gateway($network_wide)
{
    try {
        sibs_activation_process($network_wide);

        if (! function_exists('mail')) {
            add_action('admin_notices', 'sibs_get_notice_mail_not_found__error'); // https://developer.wordpress.org/reference/hooks/admin_notices/
            // throw new sibsException('Mail function not Found');
        }

        // Notice on admin when init payment gateway
        if (! class_exists('WC_Payment_Gateway')) {
            add_action('admin_notices', 'sibs_get_notice_woocommerce_activation__error'); // https://developer.wordpress.org/reference/hooks/admin_notices/

            throw new sibsException('Woocommerce not Found');
        } else {
            // add_action('admin_notices', 'validate_sibs_term__info'); // https://developer.wordpress.org/reference/hooks/admin_notices/
        }

        $session_class = apply_filters('woocommerce_session_handler', 'WC_Session_Handler');
        wc()->session  = new $session_class();
        wc()->session->init();

        include_once __DIR__ . '/includes/core/class-sibspaymentcore.php';
        include_once __DIR__ . '/includes/sibs-admin-page.php';
        include_once __DIR__ . '/includes/sibs-style-page.php';

        foreach (glob(__DIR__ . '/includes/gateways/**.php') as $filename) {
            include_once $filename;
        }

        add_filter('woocommerce_payment_gateways', function ($methods) {
            return array_merge($methods, [
                Gateway_Sibs_STG_CC::class,
                Gateway_Sibs_STG_Blik::class,
                Gateway_Sibs_STG_Pbl::class,
                // Gateway_Sibs_STG_Pblkv::class,
                Gateway_Sibs_STG_Xpay::class,
            ]);
        });

        add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'sibs_add_configuration_links'); // https://developer.wordpress.org/reference/hooks/plugin_action_links_plugin_file/
    } catch(sibsException $e) {
        sibsLogger::critical($e->getErrorMessage(), sibsConstants::SIBS_LOG);
    }
}

/**
 * hook to load plugin text domain.
 */
function sibs_stg_plugins_loaded ()
{
    // Load the plugin text domain
    load_plugin_textdomain(sibsConstants::SIBS_TRANSLATE, false, dirname(plugin_basename(__FILE__)) . '/languages/');
}

/**
 * hook to add notice woocommerce activation.
 */
function sibs_get_notice_woocommerce_activation__error()
{
    $pluginName = esc_attr(__('SIBS Payment Gateway for WooCommerce', sibsConstants::SIBS_TRANSLATE));
    $message    = esc_attr(__('must be active for plugin', sibsConstants::SIBS_TRANSLATE));

    ?>
        <div id="notice" class="notice notice-error">
            <p>
                <a href="http://www.woothemes.com/woocommerce/" style="text-decoration:none" target="_new">
                    <?= __('WooCommerce', sibsConstants::SIBS_TRANSLATE) ?>
                </a><?= $message ?> <b><?= $pluginName ?></b>
            </p>
        </div>
    <?php
}

/**
 * hook to add notice woocommerce activation.
 */
function sibs_get_notice_mail_not_found__error()
{
    $pluginName = esc_attr(__('SIBS Payment Gateway for WooCommerce', sibsConstants::SIBS_TRANSLATE));
    $message    = esc_attr(__('Missing email library may cause issues with your shop’s payments. Please contact your web hosting support to troubleshoot', sibsConstants::SIBS_TRANSLATE));

    ?>
        <div id="notice" class="notice notice-error">
            <p>
                <b><?= $pluginName ?></b> - <?= $message ?>
            </p>
        </div>
    <?php
}

/**
 * hook to add validate sibs tems.
 */
function validate_sibs_term__info()
{
    if (! sibsConfig::getPluginOption('term')) {
        $admin_url  = esc_attr(sibsConfig::getSibsSettingsURL());
        $link       = esc_attr(__("By activating SIBS - WooCommerce, you agree to share your IP, email address, etc. with SIBS. If you don't want to share this information, you can change the setting via"));
        $link_label = esc_attr(__('Admin'));

        ?>
            <div id="notice" class="notice notice-info">
                <p>
                    <?= $link ?>
                    <a href="<?= $admin_url ?>"><?= $link_label ?></a>
                </p>
            </div>
        <?php

        add_option(sibsConstants::SIBS_PLUGIN_PREFIX . '_term', true);
    }
}

/**
 * Woocommerce Blocks Support.
 */
function sibs_woocommerce_blocks_support()
{
    if (class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) {
        require_once dirname(__FILE__) . '/includes/class-wc-gateway-sibs-blocks-support.php';
        add_action(
            'woocommerce_blocks_payment_method_type_registration',
            function (PaymentMethodRegistry $payment_method_registry) {
                $payment_method_registry->register(new WC_Sibs_Blocks_Support('sibs_stg_cc'));
                $payment_method_registry->register(new WC_Sibs_Blocks_Support('sibs_stg_xpay'));
                $payment_method_registry->register(new WC_Sibs_Blocks_Support('sibs_stg_blik'));
                $payment_method_registry->register(new WC_Sibs_Blocks_Support('sibs_stg_pbl'));
                // $payment_method_registry->register(new WC_Sibs_Blocks_Support('sibs_stg_pblkv'));
            }
        );
    }
}

/**
 * Admin Scripts.
 */
function sibs_admin_scripts($hook)
{
    // put script on order admin
    wp_register_script('sibs_translations_script', plugin_dir_url(__FILE__) . 'assets/js/sibs-translations-script.js', ['wp-i18n'], false, true);
    wp_register_script('sibs_admin_buttons_script', plugin_dir_url(__FILE__) . 'assets/js/sibs-admin-buttons-script.js', ['jquery', 'sibs_translations_script'], false, true);
    wp_register_script('sibs_admin_settings_step_script', plugin_dir_url(__FILE__) . 'assets/js/jquery.steps.min.js', ['jquery'], false, true);
    wp_register_script('sibs_admin_settings_script', plugin_dir_url(__FILE__) . 'assets/js/sibs-admin-settings-script.js', ['jquery', 'sibs_translations_script'], false, true);

    // queue script
    wp_enqueue_script('iris', admin_url('js/iris.min.js'), ['jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch'], false, 1);
    wp_enqueue_script('sibs_translations_script');
    wp_enqueue_script('sibs_admin_buttons_script');
    wp_enqueue_script('sibs_admin_settings_step_script');
    wp_enqueue_script('sibs_admin_settings_script');

    // set transalation
    wp_set_script_translations('sibs_translations_script', sibsConstants::SIBS_TRANSLATE, plugin_dir_path(__FILE__) . 'languages/');

    // send the admin ajax url to the script
    wp_localize_script('sibs_admin_buttons_script', 'mb_script_var', ['ajaxurl' => admin_url('admin-ajax.php')]);

    wp_enqueue_style('sibs_admin_box_style', 'https://cdn.jsdelivr.net/npm/boxicons@latest/css/boxicons.min.css', []);

    //wp_enqueue_style('sibs_sibsbug_style', 'https://plugin-stargate.store/bug-report/src/assets/css/sibs-bug.css', []);
    //wp_enqueue_style('sibs_admin_form_payment_style', plugin_dir_url(__FILE__) . '/assets/css/sibs-form-payment-style.css', []);
    wp_enqueue_style('wp-color-picker');

    if ($hook != 'woocommerce_page_sibs') {
        return;
    }

    // Adiciona o arquivo de CSS personalizado
    wp_enqueue_style('admin_style', plugin_dir_url(__FILE__) . '/assets/css/admin-style.css', []);
    wp_enqueue_style('sibs_admin_style', plugin_dir_url(__FILE__) . '/assets/css/sibs-admin-style.css', []);
}

/**
 * WordPress Scripts.
 */
function sibs_wordpress_scripts()
{
    wp_enqueue_script('sibs_form_payment_script', plugin_dir_url(__FILE__) . 'assets/js/sibs-form-payment-script.js', ['jquery']);
    wp_enqueue_style('sibs_form_payment_style', plugin_dir_url(__FILE__) . 'assets/css/sibs-form-payment-style.css', []);
    wp_enqueue_style('sibs_client_style', plugin_dir_url(__FILE__) . 'assets/css/sibs-client-style.css', []);

    if (is_order_received_page()) {
        wp_enqueue_style('sibs_thank_you_page_style', plugin_dir_url(__FILE__) . 'assets/css/sibs-thank-you-page-style.css', []);
    }
}

/**
 * Custom Javascript.
 */
function ti_custom_javascript()
{
    ?>
        <script>
            var sToken = "<?= wp_get_session_token(); ?>";
            var url_site = "<?= get_site_url(); ?>";
        </script>
    <?php
}

/**
 * hook to add configuration links.
 */
function sibs_add_configuration_links($links)
{
    $general_settings_url        = esc_attr(sibsConfig::getSibsSettingsURL());
    $general_settings_aria_label = esc_attr__('View SIBS General Settings', sibsConstants::SIBS_TRANSLATE);
    $general_settings_label      = esc_html__('General Settings', sibsConstants::SIBS_TRANSLATE);

    // $style_settings_url   = esc_attr(sibsConfig::getSibsStylesURL());
    // $style_settings_aria_label = esc_attr__('View SIBS Styles Settings', sibsConstants::SIBS_TRANSLATE);
    // $style_settings_label = esc_html__('SIBS Style', sibsConstants::SIBS_TRANSLATE);

    $payments_settings_url        = esc_attr(sibsConfig::getPaymentsURL());
    $payments_settings_aria_label = esc_attr__('View Payments Settings', sibsConstants::SIBS_TRANSLATE);
    $payments_settings_label      = esc_html__('Payments', sibsConstants::SIBS_TRANSLATE);

    $add_links = [
        "<a href=\"$general_settings_url\" aria-label=\"{$general_settings_aria_label}\">$general_settings_label</a>",
        // "<a href=\"$style_settings_url\" aria-label=\"{$style_settings_aria_label}\">$style_settings_label</a>",
        "<a href=\"$payments_settings_url\" aria-label=\"{$payments_settings_aria_label}\">$payments_settings_label</a>",
    ];

    return array_merge($add_links, $links);
}

/**
 * hook to add row meta on the plugin screen.
 */
function sibs_plugin_row_meta($links, $file)
{
    if (plugin_basename(__FILE__) == $file) {
        $logs_url        = esc_url(sibsConfig::getLogsURL());
        $logs_aria_label = esc_attr__('View Woocommerce logs', sibsConstants::SIBS_TRANSLATE);
        $logs_label      = esc_html__('Logs', sibsConstants::SIBS_TRANSLATE);

        $docs_url        = esc_url(sibsConfig::getDocsURL());
        $docs_aria_label = esc_attr__('View SIBS documentation', sibsConstants::SIBS_TRANSLATE);
        $docs_label      = esc_html__('Docs', sibsConstants::SIBS_TRANSLATE);

        $row_meta = [
            'logs' => "<a href=\"{$logs_url}\" aria-label=\"{$logs_aria_label}\">{$logs_label}</a>",
            'docs' => "<a href=\"{$docs_url}\" aria-label=\"{$docs_aria_label}\" target=\"_blank\">{$docs_label}</a>",
        ];

        return array_merge($links, $row_meta);
    }

    return (array) $links;
}

/**
 * hook to add notice woocommerce activation.
 */
function sibs_get_ajax_registered_payment()
{
    $uid        = sibsGeneralFunctions::sibs_get_request_value('user_id');
    $payment_id = sibsGeneralFunctions::sibs_get_request_value('payment_id');

    switch($payment_id) {
        case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD_SAVED:
            $payment_group = sibsConstants::SIBS_PAYMENT_METHOD_CC;

            break;
        case sibsConstants::SIBS_PAYMENT_METHOD_ORDER_DIRECT_DEBIT_SAVED:
            $payment_group = sibsConstants::SIBS_PAYMENT_METHOD_DD;

            break;
        default:
            $payment_group = '';
    }

    $registered_payment = sibsGeneralModels::sibs_get_payment_information($uid, $payment_group);
    echo wp_json_encode($registered_payment);

    wp_die();
}

/**
 * hook to Override new order email.
 */
function sibs_override_woocommerce_template($template, $template_name, $template_path)
{
    $template_directory = untrailingslashit(__DIR__);
    $path               = "$template_directory/$template_name";

    return file_exists($path) ? $path : $template;
}

/**
 * hook to hide refund button.
 */
function sibs_hide_wc_refund_button()
{
    global $post;

    if (! current_user_can('administrator') && ! current_user_can('editor')) {
        return;
    }

    if (strpos($_SERVER['REQUEST_URI'], 'post.php?post=') === false) {
        return;
    }

    if (empty($post) || $post->post_type != sibsConstants::WOOCOMMERCE_POST_TYPE_SHOP_ORDER) {
        return;
    }

    $methods_to_hide_refund_buttons = [
        sibsConstants::SIBS_PAYMENT_METHOD_ORDER_BLIK,
    ]; // Async Refunds

    $statuses_to_show_refund_buttons = [
        sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING,
        sibsConstants::WOOCOMMERCE_ORDER_STATUS_COMPLETED,
    ];

    $order          = new WC_Order($post->ID);
    $payment_status = 'wc-' . $order->get_status();
    $payment_method = $order->get_payment_method();

    $is_refund_status      = in_array($payment_status, $statuses_to_show_refund_buttons);
    $is_not_refund_methods = in_array($payment_method, $methods_to_hide_refund_buttons);

    if ($is_refund_status && ! $is_not_refund_methods) {
        return;
    }

    ?>
    <script>
        jQuery(function () {
            jQuery('.refund-items').hide();
            jQuery('.order_actions option[value=send_email_customer_refunded_order]').remove();
            if (jQuery('#original_post_status').val() == 'wc-refunded') {
                jQuery('#s2id_order_status').html('Refunded');
            } else {
                jQuery('#order_status option[value=wc-refunded]').remove();
            }
        });
    </script>
<?php
}

/**
 * hook to add buttons on order admin.
 */
function sibs_add_admin_buttons($order)
{
    $sibsOrderData = sibsGeneralModels::sibs_get_db_transaction_log($order->get_id());

    $payment_method = $order->get_payment_method();
    $payment_status = 'wc-' . $order->get_status();
    $payment_type   = isset($sibsOrderData['payment_type']) ? $sibsOrderData['payment_type'] : null;

    // STATUS INQUIRY BUTTON :: Reativado para poder validar se o webhook nao funcionar.
    if ($order->get_status() != 'refunded') {
        sibsPaymentGateway::sibs_status_inquiry_order_add_button($order);
    }

    // CAPTURE BUTTON FOR AUTHORIZATIONS
    $payments_auth_db = [
        sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD_SAVED,
        sibsConstants::SIBS_PAYMENT_METHOD_ORDER_DIRECT_DEBIT,
        sibsConstants::SIBS_PAYMENT_METHOD_ORDER_DIRECT_DEBIT_SAVED,
        sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD,
    ];

    $statuses_to_show_capture_buttons = [
        sibsConstants::WOOCOMMERCE_ORDER_STATUS_PENDING,
        sibsConstants::SIBS_ORDER_STATUS_AUTHORIZED,
        sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_CAPTURED,
    ];

    $method_has_auth   = in_array($payment_method, $payments_auth_db);
    $is_capture_status = in_array($payment_status, $statuses_to_show_capture_buttons);
    $is_auth           = $payment_type === sibsConstants::SPG_PAYMENT_TYPE_AUTH;

    if ($method_has_auth && $is_capture_status && $is_auth) {
        sibsPaymentGateway::sibs_capture_order_add_button($order);
    }

    // CANCEL AUTHORIZATION BUTTON
    $statuses_to_show_cancel_authorization_buttons = [
        sibsConstants::SIBS_ORDER_STATUS_AUTHORIZED,
        sibsConstants::SIBS_ORDER_STATUS_PARTIALLY_CAPTURED,
    ];
    $is_cancel_authorization_status = in_array($payment_status, $statuses_to_show_cancel_authorization_buttons);

    if ($is_cancel_authorization_status) {
        sibsPaymentGateway::sibs_cancel_authorization_order_add_button($order);
    }

    // REFUND INQUIRY BUTTON FOR ASYNC REFUNDS
    $payments_async_refund_db = [
        sibsConstants::SIBS_PAYMENT_METHOD_ORDER_BLIK,
    ];

    $statuses_to_show_refund_inquiry_buttons = [
        sibsConstants::SIBS_ORDER_STATUS_PENDING_REFUND,
    ];

    $method_is_async_refund   = in_array($payment_method, $payments_async_refund_db);
    $is_refund_inquiry_status = in_array($payment_status, $statuses_to_show_refund_inquiry_buttons);

    if ($method_is_async_refund && $is_refund_inquiry_status) {
        sibsPaymentGateway::sibs_refund_inquiry_order_add_button($order);
    }

    // ASYNC REFUND BUTTON
    $statuses_to_show_async_refund_buttons = [
        sibsConstants::WOOCOMMERCE_ORDER_STATUS_PROCESSING,
        sibsConstants::WOOCOMMERCE_ORDER_STATUS_COMPLETED,
    ];

    $is_async_refund_status = in_array($payment_status, $statuses_to_show_async_refund_buttons);

    if ($method_is_async_refund && $is_async_refund_status) {
        sibsPaymentGateway::sibs_refund_async_order_add_button($order);
    }
}

/**
 * Hook to add button to order admin.
 */
function sibs_ajax_add_button_to_order_admin()
{
    $order_id  = intval($_POST['order_id']);
    $button_id = intval($_POST['button_id']);

    sibsLogger::debug('POST: ' . sibsLogger::prettify($_POST), sibsConstants::SIBS_LOG);
    sibsLogger::debug("order_id: $order_id", sibsConstants::SIBS_LOG);
    sibsLogger::debug("button_id: $button_id", sibsConstants::SIBS_LOG);

    switch($button_id) {
        case 1:
            $back_data = sibsPaymentGateway::check_status($order_id);

            break;
        case 2:
            $back_data = sibsPaymentGateway::process_capture($order_id);

            break;
        case 3:
            $back_data = sibsPaymentGateway::refund_inquiry($order_id);

            break;
        case 4:
            $back_data = sibsPaymentGateway::cancel_authorization($order_id);

            break;
        case 5:
            $back_data = sibsPaymentGateway::async_refund($order_id);

            break;
        default:
            $back_data['msg']   = __('Function not recognized', sibsConstants::SIBS_TRANSLATE);
            $back_data['error'] = 1;
    }
    wp_send_json($back_data);
}

/**
 * Hook to process webhook calls.
 */
function sibs_process_webhook_calls()
{
    sibsLogger::debug('sibs webhook call begin', sibsConstants::SIBS_CRON_LOG);

    $unprocessed_webhook_calls = sibsGeneralModels::sibs_get_db_unprocessed_webhook_call();

    foreach ($unprocessed_webhook_calls as $key => $unprocessed_webhook_call) {
        sibsLogger::debug('Execute ' . ($key + 1) . 'º Unprocessed webhook with ID ' . $unprocessed_webhook_call['id'], sibsConstants::SIBS_CRON_LOG);

        try {
            $decoded_payload = $unprocessed_webhook_call['decoded_payload'];

            if (is_null($decoded_payload)) {
                throw new sibsException('WEBHOOK is not decrypted', sibsConstants::SIBS_CRON_LOG);
            }

            $webhook_payload = json_decode($decoded_payload, true);

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

            sibsLogger::debug("WEBHOOK order_id: $order_id", sibsConstants::SIBS_CRON_LOG);
            sibsLogger::debug("WEBHOOK transactionId: $transactionId", sibsConstants::SIBS_CRON_LOG);
            sibsLogger::debug("WEBHOOK payment_method: $payment_method", sibsConstants::SIBS_CRON_LOG);
            sibsLogger::debug("WEBHOOK payment_status: $payment_status", sibsConstants::SIBS_CRON_LOG);
            sibsLogger::debug("WEBHOOK payment_type: $payment_type", sibsConstants::SIBS_CRON_LOG);
            sibsLogger::debug("WEBHOOK amount_value: $amount_value", sibsConstants::SIBS_CRON_LOG);
            sibsLogger::debug("WEBHOOK notificationID: $notificationID", sibsConstants::SIBS_CRON_LOG);

            if ($transactionId === sibsConstants::WEBHOOK_TEST) {
                sibsGeneralModels::sibs_update_db_webhook_calls($unprocessed_webhook_call['id'], [
                    'processed_qty' => ($unprocessed_webhook_call['processed_qty']++),
                    'processed_at'  => sibsConfig::getStoreCurrentTime(),
                ]);

                continue;
            }

            $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_CRON_LOG);
                }
            }

            sibsLogger::debug('WEBHOOK order_no: ' . $sibs_transaction['order_no'], sibsConstants::SIBS_CRON_LOG);

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

            if (in_array($payment_status, [sibsConstants::SIBS_RESULT_IN_PROCESSING, sibsConstants::SIBS_RESULT_PENDING])) {
                sibsGeneralModels::sibs_update_db_webhook_calls($unprocessed_webhook_call['id'], [
                    'processed_qty' => ($unprocessed_webhook_call['processed_qty'] + 1),
                    'processed_at'  => sibsConfig::getStoreCurrentTime(),
                ]);

                continue;
            }

            switch($payment_type) {
                case sibsConstants::SPG_PAYMENT_TYPE_AUTH:
                case sibsConstants::SPG_PAYMENT_TYPE_PURS:
                    sibsPaymentGateway::webhook_payment($sibs_transaction, $payment_status, $payment_type);

                    break;
                case sibsConstants::SPG_PAYMENT_TYPE_CAPT:
                    sibsPaymentGateway::webhook_capture($sibs_transaction, $payment_status, $amount_value);

                    break;
                case sibsConstants::SPG_PAYMENT_TYPE_RFND:
                    sibsPaymentGateway::webhook_refund($sibs_transaction, $payment_status, $amount_value);

                    break;
                default:
                    throw new sibsException('Invalid payment type', sibsConstants::SIBS_CRON_LOG);
            }

            sibsGeneralModels::sibs_update_db_webhook_calls($unprocessed_webhook_call['id'], [
                'processed_qty' => ($unprocessed_webhook_call['processed_qty'] + 1),
                'processed_at'  => sibsConfig::getStoreCurrentTime(),
            ]);
        } catch (sibsException $e) {
            sibsLogger::warning('WEBHOOK problem: ' . $e->getExceptionMessage(), sibsConstants::SIBS_CRON_LOG);
            sibsGeneralModels::sibs_update_db_webhook_calls($unprocessed_webhook_call['id'], [
                'processed_qty' => ($unprocessed_webhook_call['processed_qty'] + 1),
                'exception'     => $e->getExceptionMessage(),
            ]);
        }
    }
    sibsLogger::debug('sibs webhook call end', sibsConstants::SIBS_CRON_LOG);
}

/**
 * Hook to cancel old onhold orders.
 */
function sibs_cancel_onhold_orders()
{
    $held_duration = sibsConfig::getWoocommerceOption('woocommerce_hold_stock_minutes');
    $manage_stock  = sibsConfig::getWoocommerceOption('woocommerce_manage_stock');

    if ($held_duration < 1 || $manage_stock !== 'yes') {
        return;
    }

    $seconds_delay = $held_duration * 60;
    $today         = strtotime(sibsConfig::getStoreCurrentTime());

    // Get unpaid orders
    $unpaid_orders = (array) wc_get_orders([
        'limit'        => -1,
        'status'       => sibsConstants::WOOCOMMERCE_ORDER_STATUS_ON_HOLD,
        'date_created' => '<' . ($today - $seconds_delay),
    ]);

    if (sizeof($unpaid_orders) > 0) {
        $cancelled_text = __('The order was cancelled due to no payment from customer', sibsConstants::SIBS_TRANSLATE);

        // Loop through orders
        foreach ($unpaid_orders as $unpaid_order) {
            sibsLogger::debug('sibs cancel on-hold order id: ' . sibsLogger::prettify($unpaid_order->get_id()), sibsConstants::SIBS_CRON_LOG);

            $payments_method_on_hold_to_cancel = [
                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($unpaid_order->get_payment_method(), $payments_method_on_hold_to_cancel)) {
                try {
                    $unpaid_order->update_status(sibsConstants::WOOCOMMERCE_ORDER_STATUS_CANCELLED, $cancelled_text);
                } catch (Throwable $t) {
                    sibsLogger::critical($t->getMessage(), sibsConstants::SIBS_CRON_LOG);
                }
            }
        }
    }

    wp_clear_scheduled_hook('woocommerce_cancel_unpaid_orders');
    wp_schedule_single_event(time() + (absint($held_duration) * 60), 'woocommerce_cancel_unpaid_orders');
}

/**
 * Hook to render before submit payment form action.
 *
 * @return void
 */
function sibs_woocommerce_review_order_before_submit_action()
{
    $oneclick = sibsConfig::getPaymentOption(sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD, 'tokenization');

    if ($oneclick === sibsConstants::SIBS_TOKEN_ONECLICK && get_current_user_id()) {
        $termsAndConditionsLinkLabel = __('SIBS terms of service', sibsConstants::SIBS_TRANSLATE);
        $termsAndConditionsLink      = "<a href='javascript:void(0)' id='opener'>{$termsAndConditionsLinkLabel}</a>";

        $oneclickExplanationLinkLabel = __('OneClick', sibsConstants::SIBS_TRANSLATE);
        $oneclickExplanationLink      = "<a href='javascript:void(0)' id='opener__oneclick_definition_page'>{$oneclickExplanationLinkLabel}</a>";

        $checkoutLabel = sprintf(
            __('I agree to the %s and will adhere to them unconditionally for %s payment', sibsConstants::SIBS_TRANSLATE),
            $termsAndConditionsLink,
            $oneclickExplanationLink,
        );

        $oneclick_payment_methods = [
            sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD,
        ];

        $paymentMethodValue    = WC()->checkout->get_value('payment_method');
        $customerAcceptorValue = WC()->checkout->get_value(sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_customer_acceptor');

        woocommerce_form_field(sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_customer_acceptor', [
            'id'                   => sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_terms_of_service',
            'type'                 => 'checkbox',
            'label'                => $checkoutLabel,
            'class'                => in_array($paymentMethodValue, $oneclick_payment_methods) ? 'm-fadeIn' : 'm-fadeOut',
            'required'             => false,
        ], $customerAcceptorValue);

        ?>
            <script type="text/javascript">
                jQuery("#opener").on("click", function(e) {
                    e.preventDefault();
                    jQuery("#dialog-message").dialog("open");
                });

                jQuery("#opener__oneclick_definition_page").on("click", function(e) {
                    e.preventDefault();
                    jQuery("#oneclick_definition_page").dialog("open");
                });
            </script>
        <?php
    }
}

/**
 * Hook to execute on process checkout action.
 */
function sibs_woocommerce_checkout_process_action()
{
    WC()->session->__unset(sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_customer_acceptor');
    $oneclick_customer_acceptor = ! empty(sibsGeneralFunctions::sibs_get_request_value(sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_customer_acceptor'));
    sibsLogger::debug('Customer accept Oneclick/Tokenization: ' . (($oneclick_customer_acceptor) ? 'Yes' : 'No'));
    WC()->session->set(sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_customer_acceptor', $oneclick_customer_acceptor);
}

/**
 * Hook to put script on woocommerce footer.
 */
function sibs_footer()
{
    if (! is_checkout()) {
        return;
    }

    $oneclick = sibsConfig::getPaymentOption(sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD, 'tokenization');

    if ($oneclick !== sibsConstants::SIBS_TOKEN_ONECLICK) {
        return;
    }
    ?>

    <style type="text/css">
        .m-fadeOut {
            visibility: hidden;
            opacity: 0;
            height: 0;
            padding: 0;
            margin: 0;
            border: 0;
            transition: visibility 0s linear 300ms, opacity 0ms;
        }
        .m-fadeIn {
            visibility: visible;
            opacity: 1;
            transition: visibility 0s linear 0s, opacity 300ms;
        }
    
    </style>    

    <?php if(get_current_user_id()): ?>
        <script type="text/javascript">
            function oneclick_show_or_hide() {
                let oneclick_payment_methods = [
                    "<?= sibsConstants::SIBS_PAYMENT_METHOD_ORDER_CREDIT_CARD ?>"
                ];

                let selected_payment_method = jQuery("input[name=payment_method]:checked").val();
                let sibs_terms_checkbox = document.getElementById("<?= sibsConstants::SIBS_PLUGIN_PREFIX . '_oneclick_terms_of_service' ?>_field");

                if (oneclick_payment_methods.includes(selected_payment_method)) {
                    sibs_terms_checkbox.classList.remove("m-fadeOut");
                    sibs_terms_checkbox.classList.add("m-fadeIn");
                } else {
                    sibs_terms_checkbox.classList.remove("m-fadeIn");
                    sibs_terms_checkbox.classList.add("m-fadeOut");
                }
            }

            jQuery(window).on("load", function() {
                jQuery("form.checkout").on("change", "input[name=payment_method]", function(e) {
                    e.preventDefault();
                    oneclick_show_or_hide();
                });
                var wWidth = jQuery(window).width();
                var dWidth = wWidth * 0.8;
                var wHeight = jQuery(window).height();
                var dHeight = wHeight * 0.8;
                var $link = jQuery(this);

                jQuery("#dialog-message").dialog({
                    autoOpen: false,
                    width: dWidth,
                    height: dHeight,
                    open: function() {
                        jQuery(".ui-dialog-buttonpane").hide();
                    },
                    buttons: {
                        Ok: function() {
                            jQuery(this).dialog("close");
                        }
                    }
                });

                jQuery("#oneclick_definition_page").dialog({
                    autoOpen: false,
                    width: dWidth,
                    height: dHeight,
                    open: function() {
                        jQuery(".ui-dialog-buttonpane").hide();
                    },
                    buttons: {
                        Ok: function() {
                            jQuery(this).dialog("close");
                        }
                    }
                });
            });
        </script>
    <?php endif; ?>

    <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css" />
    <style type="text/css">
        #dialog-message{
            z-index: 999999;
            height: 100%;
        }
        .no-close .ui-dialog-titlebar-close {
            display: none;
        }
        .ui-dialog .ui-dialog-content {
            padding: 0px !important;   
        }
    </style>

    <div id="dialog-message" title="<?= __('SIBS terms of service', sibsConstants::SIBS_TRANSLATE) ?>" style="display: none;">
        <?php
            $lang    = sibsFunctions::get_language();
    $pdf             = "sibs_terms_and_conditions_{$lang}.pdf";
    $siteUrl         = untrailingslashit(plugins_url('/', __FILE__));
    $pdfUrl          = "{$siteUrl}/assets/files/$pdf";
    ?>
        <embed src="<?= $pdfUrl ?>" frameborder="0" width="100%" style="float:left; position:relative; height:100%;">
    </div>
    <div id="oneclick_definition_page" title="<?= __('OneClick Definition Page', sibsConstants::SIBS_TRANSLATE) ?>" style="display: none;">
        <p>
            <?= __('If you activate OneClick, we will verify your card and you will see a transaction for 0 PLN on your account', sibsConstants::SIBS_TRANSLATE) ?>
            <?= __('Please note that your bank may require additional authorization', sibsConstants::SIBS_TRANSLATE) ?>
        </p>
        <p>
            <?= __('With OneClick activated, we will not ask you to enter your card details for future payments', sibsConstants::SIBS_TRANSLATE) ?>
        </p>
    </div>

<?php } ?>