<?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:     3.0.0
 * 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.9.x
 * WooCommerce requires at least: 7.4.1
 * WooCommerce tested up to: 10.7.x.
 * Requires at least: 6.5
 * Requires PHP: 7.4.
 */
require_once __DIR__.'/vendor/autoload.php';

define('SIBS_VERSION', '3.0.0');
define('SIBS_PLUGIN_URL', plugin_dir_url(__FILE__));
define('SIBS_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('SIBS_PLUGIN_NAME', dirname(plugin_basename(__FILE__)));
define('SIBS_PLUGIN_BASENAME', plugin_basename(__FILE__));
define('DATE_FORMAT', 'Y-m-d\TH:i:s.vP'); // TODO: por algum motivo no pay by link nao esta a pegar isso

use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
use Sibs\Stargate\Admin\SibsGeneralSettings;
use Sibs\Stargate\Api\AsyncRefund;
use Sibs\Stargate\Api\CancelAuthorization;
use Sibs\Stargate\Api\Capture;
use Sibs\Stargate\Api\CheckStatus;
use Sibs\Stargate\Api\RefundInquiry;
use Sibs\Stargate\Blocks\SibsBlocksSupport;
use Sibs\Stargate\Config\SibsConfig;
use Sibs\Stargate\Constants\Logs;
use Sibs\Stargate\Constants\OrderStatus;
use Sibs\Stargate\Constants\PaymentTypes;
use Sibs\Stargate\Constants\Plugin;
use Sibs\Stargate\Constants\Tokens;
use Sibs\Stargate\Constants\WebhookVersions;
use Sibs\Stargate\Constants\WoocommerceOrderStatus;
use Sibs\Stargate\Constants\WoocommercePaymentMethods;
use Sibs\Stargate\Core\SibsFunctions;
use Sibs\Stargate\Core\SibsGeneralFunctions;
use Sibs\Stargate\Core\SibsPaymentCore;
use Sibs\Stargate\Cron\CancelOnholdOrders;
use Sibs\Stargate\Cron\ProcessWebhookCalls;
use Sibs\Stargate\Exceptions\SibsException;
use Sibs\Stargate\Gateways\Blik;
use Sibs\Stargate\Gateways\Card;
use Sibs\Stargate\Gateways\Pbl;
use Sibs\Stargate\Gateways\SibsPaymentGateway;
use Sibs\Stargate\Gateways\Xpay;
use Sibs\Stargate\Loggers\SibsLogger;
use Sibs\Stargate\Models\SibsGeneralModels;
use Sibs\Stargate\Utils\SibsNotes;
use Sibs\Stargate\Utils\SibsVersion;
use Sibs\Stargate\Utils\TemplateUtils;
use Sibs\Stargate\Utils\UrlUtils;
use Sibs\Stargate\Webhooks\SibsWebhookProcess;

defined('ABSPATH') || exit;

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

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

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('rest_api_init', 'sibs_stg_rest_api_init'); // https://developer.wordpress.org/reference/hooks/rest_api_init/
add_action('plugins_loaded', 'sibs_stg_plugins_loaded'); // https://developer.wordpress.org/reference/hooks/plugins_loaded/
add_action('admin_head', 'sibs_stg_hide_wc_refund_button'); // https://wp-kama.ru/hook/admin_head
add_action('woocommerce_order_item_add_action_buttons', 'sibs_stg_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_stg_ajax_add_button_to_order_admin'); // https://developer.wordpress.org/reference/hooks/wp_ajax_action/
add_action('woocommerce_cancel_unpaid_orders', 'sibs_stg_cancel_onhold_orders'); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_cancel_unpaid_order
add_action('sibs_stg_schedule_every_five_minutes', 'sibs_stg_process_webhook_calls');
add_action('woocommerce_review_order_before_submit', 'sibs_stg_woocommerce_review_order_before_submit_action'); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_review_order_before_submit
add_action('woocommerce_checkout_process', 'sibs_stg_woocommerce_checkout_process_action', 10, 1); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_checkout_process
add_action('wp_footer', 'sibs_stg_footer'); // https://developer.wordpress.org/reference/hooks/wp_footer/
add_action('admin_enqueue_scripts', 'sibs_stg_admin_scripts'); // https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/
add_action('wp_enqueue_scripts', 'sibs_stg_wordpress_scripts'); // https://developer.wordpress.org/reference/hooks/wp_enqueue_scripts/
add_action('wp_head', 'sibs_stg_custom_javascript'); // https://developer.wordpress.org/reference/functions/wp_head/
add_action('woocommerce_blocks_loaded', 'sibs_stg_woocommerce_blocks_support'); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_blocks_loaded]
add_action('woocommerce_admin_order_data_after_order_details', 'sibs_stg_update_order_status'); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_admin_order_data_after_order_details
add_action('woocommerce_admin_order_data_after_shipping_address', 'sibs_stg_add_additional_information'); // https://wp-kama.com/plugin/woocommerce/hook/woocommerce_admin_order_data_after_shipping_address
add_action('template_redirect', 'sibs_stg_template_redirect'); // https://developer.wordpress.org/reference/hooks/template_redirect/

add_filter('plugin_row_meta', 'sibs_stg_plugin_row_meta', 10, 2); // https://developer.wordpress.org/reference/hooks/plugin_row_meta/
add_filter('cron_schedules', 'sibs_stg_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_stg_schedule_every_five_minutes')) {
    wp_schedule_event(time(), 'every_five_minutes', 'sibs_stg_schedule_every_five_minutes');
}

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

    return $schedules;
}

/**
 * hook to init sibs gateway.
 *
 * @param mixed $network_wide
 */
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');
        }
        // 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();

        new SibsGeneralSettings();
        // new SibsStyleSettings();

        add_filter('woocommerce_payment_gateways', 'sibs_payment_gateways');
        add_filter('plugin_action_links_'.constant('SIBS_PLUGIN_BASENAME'), 'sibs_add_configuration_links'); // https://developer.wordpress.org/reference/hooks/plugin_action_links_plugin_file/

        add_action('http_api_curl', 'sibs_http_api_curl', 10, 3); // https://developer.wordpress.org/reference/hooks/http_api_curl/
    } catch (SibsException $e) {
        SibsLogger::critical($e->getErrorMessage());
    }
}

/**
 * hook to load plugin text domain.
 */
function sibs_stg_plugins_loaded()
{
    // Load the plugin text domain
    load_plugin_textdomain('sibs-woo-stg', false, constant('SIBS_PLUGIN_NAME').'/languages/');
}

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

    ?>
        <div id="notice" class="notice notice-error">
            <p>
                <a href="http://www.woothemes.com/woocommerce/" style="text-decoration:none" target="_new">
                    <?php echo __('WooCommerce', 'sibs-woo-stg'); ?>
                </a><?php echo $message; ?> <b><?php echo $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', 'sibs-woo-stg'));
    $message = esc_attr(__('Missing email library may cause issues with your shop’s payments. Please contact your web hosting support to troubleshoot', 'sibs-woo-stg'));

    ?>
        <div id="notice" class="notice notice-error">
            <p>
                <b><?php echo $pluginName; ?></b> - <?php echo $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>
                    <?php echo $link; ?>
                    <a href="<?php echo $admin_url; ?>"><?php echo $link_label; ?></a>
                </p>
            </div>
        <?php

        add_option(Plugin::PLUGIN_PREFIX.'_term', true);
    }
}

/**
 * Woocommerce Blocks Support.
 */
function sibs_stg_woocommerce_blocks_support()
{
    if (class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) {
        add_action(
            'woocommerce_blocks_payment_method_type_registration',
            function (PaymentMethodRegistry $payment_method_registry) {
                $payment_method_registry->register(new SibsBlocksSupport('sibs_stg_cc'));
                $payment_method_registry->register(new SibsBlocksSupport('sibs_stg_xpay'));
                $payment_method_registry->register(new SibsBlocksSupport('sibs_stg_blik'));
                $payment_method_registry->register(new SibsBlocksSupport('sibs_stg_pbl'));
                // $payment_method_registry->register(new SibsBlocksSupport('sibs_stg_pblkv'));
            }
        );
    }
}

/**
 * Admin Scripts.
 *
 * @param mixed $hook
 */
function sibs_stg_admin_scripts($hook)
{
    // put script on order admin
    wp_register_script('sibs_translations_script', constant('SIBS_PLUGIN_URL').'assets/js/sibs-translations-script.js', ['wp-i18n'], false, true);
    wp_register_script('sibs_admin_buttons_script', constant('SIBS_PLUGIN_URL').'assets/js/sibs-admin-buttons-script.js', ['jquery', 'sibs_translations_script'], false, true);
    wp_register_script('sibs_admin_settings_step_script', constant('SIBS_PLUGIN_URL').'assets/js/jquery.steps.min.js', ['jquery'], false, true);
    wp_register_script('sibs_admin_settings_script', constant('SIBS_PLUGIN_URL').'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', 'sibs-woo-stg', SIBS_PLUGIN_PATH.'languages/');

    // send the admin ajax url to the script
    wp_localize_script('sibs_admin_buttons_script', 'props', ['ajaxurl' => admin_url('admin-ajax.php')]);
    wp_localize_script('sibs_checkout_inline', 'props', ['methods' => WoocommercePaymentMethods::All(), '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', []);
}

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

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

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

/**
 * hook to add payment gateways.
 *
 * @param mixed $methods
 */
function sibs_payment_gateways($methods)
{
    return array_merge($methods, [
        Card::class,
        Blik::class,
        Pbl::class,
        // Pblkv::class,
        Xpay::class,
    ]);
}

/**
 * hook to add configuration links.
 *
 * @param mixed $links
 */
function sibs_add_configuration_links($links)
{
    $general_settings_url = esc_attr(SibsConfig::getSibsSettingsURL());
    $general_settings_aria_label = esc_attr__('View SIBS Settings', 'sibs-woo-stg');
    $general_settings_label = esc_html__('Settings', 'sibs-woo-stg');

    // $style_settings_url   = esc_attr(SibsConfig::getSibsStylesURL());
    // $style_settings_aria_label = esc_attr__('View SIBS Styles Settings', 'sibs-woo-stg');
    // $style_settings_label = esc_html__('SIBS Style', 'sibs-woo-stg');

    $payments_settings_url = esc_attr(SibsConfig::getPaymentsURL());
    $payments_settings_aria_label = esc_attr__('View Payments Settings', 'sibs-woo-stg');
    $payments_settings_label = esc_html__('Payments', 'sibs-woo-stg');

    $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 http api curl options.
 *
 * @param mixed $handle
 * @param mixed $parsed_args
 * @param mixed $url
 */
function sibs_http_api_curl($handle, $parsed_args, $url)
{
    if (!empty($parsed_args['sibs_request'])) {
        $conn_timeout = $parsed_args['conn_timeout'] ?? 90;
        $timeout = $parsed_args['timeout'] ?? 90;

        SibsLogger::debug(
            "Force timeout (conn: {$conn_timeout}, out: {$timeout}) options of: {$url}",
            Logs::DEFAULT
        );

        // Set Timeout
        curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, $conn_timeout);
        curl_setopt($handle, CURLOPT_TIMEOUT, $timeout);

        // Set TLS Version
        curl_setopt($handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);

        // Use Only Fresh Connections
        curl_setopt($handle, CURLOPT_FORBID_REUSE, true);
        curl_setopt($handle, CURLOPT_FRESH_CONNECT, true);

        // Use HTTP Version
        curl_setopt($handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    }
}

/**
 * hook to add row meta on the plugin screen.
 *
 * @param mixed $links
 * @param mixed $file
 */
function sibs_stg_plugin_row_meta($links, $file)
{
    if (plugin_basename(__FILE__) == $file) {
        $logs_url = esc_url(SibsConfig::getLogsURL());
        $logs_aria_label = esc_attr__('View Woocommerce logs', 'sibs-woo-stg');
        $logs_label = esc_html__('Logs', 'sibs-woo-stg');

        $docs_url = esc_url(SibsConfig::getDocsURL());
        $docs_aria_label = esc_attr__('View SIBS documentation', 'sibs-woo-stg');
        $docs_label = esc_html__('Docs', 'sibs-woo-stg');

        $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 hide refund button.
 */
function sibs_stg_hide_wc_refund_button()
{
    // Only allow users who can manage orders
    if (!current_user_can('edit_shop_orders')) {
        return;
    }

    // Ensure we are on the correct admin page
    if (
        !isset($_GET['page'], $_GET['action'], $_GET['id'])
        || 'wc-orders' !== $_GET['page']
        || 'edit' !== $_GET['action']
    ) {
        return;
    }

    $order_id = absint($_GET['id']);
    $wc_order = wc_get_order($order_id);

    if (!$wc_order instanceof WC_Order) {
        SibsLogger::warning('Buttons not added', Logs::ADMIN);

        return;
    }

    $paymentStatus = $wc_order->get_status();
    $paymentMethod = $wc_order->get_payment_method();

    /*
    |--------------------------------------------------------------------------
    | CONDITIONS
    |--------------------------------------------------------------------------
    */
    $isRefundableStatus = in_array($paymentStatus, [
        OrderStatus::PROCESSING,
        OrderStatus::COMPLETED,
    ], true);

    $isAsyncRefundMethod = WoocommercePaymentMethods::BLIK === $paymentMethod;

    // If it's refundable AND NOT async → keep default Woo button
    if ($isRefundableStatus && !$isAsyncRefundMethod) {
        return;
    }

    /*
    |--------------------------------------------------------------------------
    | HIDE DEFAULT WC REFUND UI
    |--------------------------------------------------------------------------
    */
    ?>
    <script>
        jQuery(function($) {
            $('.refund-items').hide();
            $('option[value="send_email_customer_refunded_order"]').remove();

            const refundedStatus = '<?php echo WoocommerceOrderStatus::REFUNDED; ?>';

            if ($('#original_post_status').val() === refundedStatus) {
                $('#s2id_order_status').html('<?php echo __('Refunded', 'sibs-woo-stg'); ?>');
            } else {
                $('#order_status option[value="' + refundedStatus + '"]').remove();
            }
        });
    </script>
    <?php
}

/**
 * hook to add buttons on order admin.
 */
function sibs_stg_add_admin_buttons(WC_Order $wc_order)
{
    $sibsOrderData = SibsGeneralModels::get_transaction($wc_order);

    $paymentMethod = $wc_order->get_payment_method();
    $paymentStatus = $wc_order->get_status();
    $paymentType = $sibsOrderData['payment_type'] ?? null;

    /*
    |--------------------------------------------------------------------------
    | STATUS INQUIRY
    |--------------------------------------------------------------------------
    */
    if (OrderStatus::REFUNDED !== $paymentStatus) {
        CheckStatus::add_button($wc_order);
    }

    /*
    |--------------------------------------------------------------------------
    | COMMON FLAGS
    |--------------------------------------------------------------------------
    */
    $isCardMethod = WoocommercePaymentMethods::CARD === $paymentMethod;
    $isBlikMethod = WoocommercePaymentMethods::BLIK === $paymentMethod;
    // $isPayByLinkMethod   = $paymentMethod === WoocommercePaymentMethods::PAY_BY_LINK;
    // $isXpayMethod        = $paymentMethod === WoocommercePaymentMethods::XPAY;
    $isAuthorization = PaymentTypes::AUTH === $paymentType;

    /*
    |--------------------------------------------------------------------------
    | CAPTURE
    |--------------------------------------------------------------------------
    */
    $canCaptureStatus = in_array($paymentStatus, [
        OrderStatus::PENDING,
        OrderStatus::AUTHORIZED,
        OrderStatus::PARTIALLY_CAPTURED,
    ], true);

    if ($isCardMethod && $isAuthorization && $canCaptureStatus) {
        Capture::add_button($wc_order);
    }

    /*
    |--------------------------------------------------------------------------
    | CANCEL AUTHORIZATION
    |--------------------------------------------------------------------------
    */
    $canCancelAuthorization = in_array($paymentStatus, [
        OrderStatus::AUTHORIZED,
        OrderStatus::PARTIALLY_CAPTURED,
    ], true);

    if ($canCancelAuthorization) {
        CancelAuthorization::add_button($wc_order);
    }

    /*
    |--------------------------------------------------------------------------
    | REFUND INQUIRY (ASYNC)
    |--------------------------------------------------------------------------
    */
    $canRefundInquiry = $isBlikMethod && OrderStatus::PENDING_REFUND === $paymentStatus;

    if ($canRefundInquiry) {
        RefundInquiry::add_button($wc_order);
    }

    /*
    |--------------------------------------------------------------------------
    | ASYNC REFUND
    |--------------------------------------------------------------------------
    */
    $canAsyncRefund = $isBlikMethod && in_array($paymentStatus, [
        OrderStatus::PROCESSING,
        OrderStatus::COMPLETED,
    ], true);

    if ($canAsyncRefund) {
        AsyncRefund::add_button($wc_order);
    }
}

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

    SibsLogger::debug('POST: '.SibsLogger::prettify($_POST), Logs::DEFAULT);
    SibsLogger::debug("order_id: {$order_id}", Logs::DEFAULT);
    SibsLogger::debug("button_id: {$button_id}", Logs::DEFAULT);

    $wc_order = wc_get_order($order_id);

    if (!$wc_order instanceof WC_Order) {
        SibsLogger::warning('Buttons not added', Logs::ADMIN);

        return;
    }

    $error = 0;

    try {
        switch ($button_id) {
            case 1:
                $message = CheckStatus::process($wc_order);

                break;

            case 2:
                $message = Capture::process($wc_order);

                break;

            case 3:
                $message = RefundInquiry::process($wc_order);

                break;

            case 4:
                $message = CancelAuthorization::process($wc_order);

                break;

            case 5:
                $message = AsyncRefund::process($wc_order);

                break;

            default:
                throw new Exception(__('Function not recognized', 'sibs-woo-stg'));
        }
    } catch (Throwable $e) {
        $message = ($e instanceof SibsException) ? $e->getErrorMessage() : $e->getMessage();
        $error = 1;
    }

    wp_send_json([
        'msg' => $message,
        'error' => $error,
    ]);
}

/**
 * Hook to process webhook calls.
 */
function sibs_stg_process_webhook_calls()
{
    SibsLogger::debug('sibs webhook call begin', Logs::CRON);

    ProcessWebhookCalls::process();

    SibsLogger::debug('sibs webhook call end', Logs::CRON);
}

/**
 * Hook to cancel old onhold orders.
 */
function sibs_stg_cancel_onhold_orders()
{
    SibsLogger::debug('sibs cancel onhold orders begin', Logs::CRON);

    CancelOnholdOrders::process();

    SibsLogger::debug('sibs cancel onhold orders end', Logs::CRON);
}

/**
 * Hook to render before submit payment form action.
 */
function sibs_stg_woocommerce_review_order_before_submit_action()
{
    $oneclick = SibsConfig::getPaymentOption(WoocommercePaymentMethods::CARD, 'tokenization');

    if (Tokens::ONECLICK === $oneclick && get_current_user_id()) {
        $termsAndConditionsLinkLabel = __('SIBS terms of service', 'sibs-woo-stg');
        $termsAndConditionsLink = "<a href='javascript:void(0)' id='opener'>{$termsAndConditionsLinkLabel}</a>";

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

        $checkoutLabel = sprintf(
            // translators: terms and conditions link, payment method name
            __('I agree to the %1$s and will adhere to them unconditionally for %2$s payment', 'sibs-woo-stg'),
            $termsAndConditionsLink,
            $oneclickExplanationLink,
        );

        $oneclick_payment_methods = [
            WoocommercePaymentMethods::CARD,
        ];

        $paymentMethodValue = WC()->checkout->get_value('payment_method');
        $customerAcceptorValue = WC()->checkout->get_value('sibs_stg_oneclick_customer_acceptor');

        woocommerce_form_field('sibs_stg_oneclick_customer_acceptor', [
            'id' => 'sibs_stg_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: Update Order Status.
 */
function sibs_stg_update_order_status(WC_Order $wc_order)
{
    $post_type = false;

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

    if (Plugin::WOOCOMMERCE_POST_TYPE_SHOP_ORDER !== $post_type) {
        $is_sibs_payment = SibsVersion::sibs_is_order_from_sibs($wc_order);

        if (!$is_sibs_payment) {
            return;
        }

        if (WoocommerceOrderStatus::PROCESSING === $wc_order->get_status()) {
            $request_section = SibsGeneralFunctions::sibs_get_request_value('section', false);

            if ('update-order' === $request_section) {
                sibs_update_payment_status($wc_order, WoocommerceOrderStatus::ON_HOLD);
                $redirect = get_admin_url()."post.php?post={$wc_order->get_id()}&action=edit";
                wp_safe_redirect($redirect);

                exit;
            }

            TemplateUtils::get_template('template-update-order', 'admin', [
                'order_id' => $wc_order->get_id(),
            ]);
        }
    }
}

/**
 * HOOK: Update Payment Status.
 */
function sibs_update_payment_status(WC_Order $wc_order, bool $original_post_status = false, bool $order_post_status = false)
{
    $transaction = SibsGeneralModels::get_transaction($wc_order);

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

    $backoffice_result = SibsPaymentCore::sibs_update_status($transaction['reference_id']);
    $backoffice_status = SibsPaymentCore::sibs_get_transaction_result($backoffice_result['result']['code']);
    $payment_status = SibsGeneralFunctions::convertTransactionStatus(
        $backoffice_result['paymentStatus'],
        $backoffice_result['paymentType']
    );

    if (Plugin::ACK === $backoffice_status && WoocommerceOrderStatus::FAILED !== $payment_status) {
        SibsGeneralModels::update_transaction_status($wc_order, $payment_status);
        SibsGeneralModels::sibs_update_posts_status($wc_order, $payment_status);

        if ($original_post_status !== $payment_status) {
            $unsuccess_Status = [
                WoocommerceOrderStatus::FAILED,
                WoocommerceOrderStatus::CANCELLED,
            ];

            if ($order_post_status && in_array($order_post_status, $unsuccess_Status)) {
                wc_increase_stock_levels($wc_order->get_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];
            SibsNotes::sibs_add_order_notes($wc_order, $status_name);
        }

        return true;
    }

    return false;
}

/**
 * HOOK add additional information.
 */
function sibs_stg_add_additional_information(WC_Order $wc_order)
{
    $is_sibs_payment = SibsVersion::sibs_is_order_from_sibs($wc_order);

    if (!$is_sibs_payment) {
        return;
    }

    TemplateUtils::get_template('template-additional-information', 'admin', [
        'transaction' => SibsGeneralModels::get_transaction($wc_order),
        'additional_information' => null,
    ]);
}

/**
 * SIBS REST API Init.
 */
function sibs_stg_rest_api_init()
{
    register_rest_route(
        Plugin::PLUGIN_PREFIX_NAME,
        '/webhook',
        [
            'permission_callback' => '__return_true',
            'methods' => 'POST',
            'callback' => 'sibs_webhook',
        ]
    );

    register_rest_route(
        Plugin::PLUGIN_PREFIX_NAME.'/'.WebhookVersions::V1,
        '/webhook',
        [
            'permission_callback' => '__return_true',
            'methods' => 'POST',
            'callback' => 'sibs_webhook',
        ]
    );
}

/**
 * SIBS Webhook.
 *
 * @return WP_REST_Response
 */
function sibs_webhook()
{
    return SibsWebhookProcess::execute();
}

/**
 * Hook to execute on process checkout action.
 */
function sibs_stg_woocommerce_checkout_process_action()
{
    WC()->session->__unset('sibs_stg_oneclick_customer_acceptor');
    $oneclick_customer_acceptor = !empty(SibsGeneralFunctions::sibs_get_request_value('sibs_stg_oneclick_customer_acceptor'));
    SibsLogger::debug('Customer accept Oneclick/Tokenization: '.(($oneclick_customer_acceptor) ? 'Yes' : 'No'));
    WC()->session->set('sibs_stg_oneclick_customer_acceptor', $oneclick_customer_acceptor);
}

/**
 * Hook to process template redirect.
 */
function sibs_stg_template_redirect()
{
    if (!is_wc_endpoint_url('order-received')) {
        return;
    }

    $wc_order = UrlUtils::get_order_from_request();

    if (!$wc_order) {
        return;
    }

    $gateway_method_id = $wc_order->get_payment_method();

    if (!$gateway_method_id) {
        return;
    }

    $available_gateways = WC()->payment_gateways()->get_available_payment_gateways();

    if (!isset($available_gateways[$gateway_method_id])) {
        return;
    }

    /** @var SibsPaymentGateway $gateway */
    $gateway = $available_gateways[$gateway_method_id];

    if (method_exists($gateway, 'sibs_stg_template_redirect')) {
        $gateway->sibs_stg_template_redirect($wc_order);
    }
}

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

    $oneclick = SibsConfig::getPaymentOption(WoocommercePaymentMethods::CARD, 'tokenization');

    if (Tokens::ONECLICK !== $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 = [
                    "<?php echo WoocommercePaymentMethods::CARD; ?>"
                ];

                let selected_payment_method = jQuery("input[name=payment_method]:checked").val();
                let sibs_terms_checkbox = document.getElementById("<?php echo Plugin::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 } ?>

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

<?php
}
