<?php

if ( ! defined( 'ABSPATH' ) ) exit;


class WCISUpsellWidget {

    const UPSELL_WIDGET_SHORTCODE = 'fast_simon_upsell_widget';
    const CONFIG_OPTION_NAME = 'upsell_widgets_config';
    const CUSTOM_CSS_TRANSIENT_NAME = 'upsell_widgets_custom_css';

    public static $config_added = false;
    public static $is_widget_on_page = false;
    public static $config_script_handler = 'fs-upsell-config';
    public static $init_script_handle = 'fs-upsell-init';
    public static $is_async_filter_added = false;

    public static function update_config($show_message = false) {
        $url = WCISPlugin::DASHBOARD_URL . 'api/recommendation_editor/upsell_settings';
        $plugin = WCISPlugin::get_instance();
        $message = '';

        $args = array(
            'headers' => array(
                'Store-ID' => get_current_blog_id(),
                'UUID' => get_option('wcis_site_id'),
                "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
            ),
            'timeout' => 15,
        );

        try {
            $resp = wp_remote_get( $url , $args );
            if (is_wp_error($resp) || $resp['response']['code'] != 200) {
                $err_msg = "update upsell widgets config failed";
                $plugin->send_error_report($err_msg);
                $status_code = wp_remote_retrieve_response_code($resp);
                $message = 'error while sending a request to fetch upsell widgets config
                            from fast simon';
                $message .= ' '. $url . ' ' . $status_code; //$resp->get_error_message();
            }
            else {
                $plugin->isp_update_option(self::CONFIG_OPTION_NAME, $resp['body']);
                $config_obj = json_decode($resp['body'], true);
                if (!is_array($config_obj)) {
                    return '<script>
                        console.error("Failed to decode upsell widgets config.");
                    </script>';
                }

                self::set_minified_custom_css_transient($config_obj);

                $message = 'Upsell widgets config from fast simon were fetched and saved';
            }

        }
        catch (Exception $e) {
            $message = 'Failed to send upsell widgets config fetch request to fast simon server';
        }

        if ($show_message) {
            echo $message;
            exit();
        }
    }

    public static function display_config($is_pretty = false) {
        $config = get_option(self::CONFIG_OPTION_NAME);

        if (empty($config)) {
            echo 'upsell config was not set';
            exit();
        }

        $config_array = json_decode($config, true);
        if (json_last_error()) {
            exit('<script>console.error("Failed to decode upsell widgets config JSON.");</script>');
        }

        $escape_flags = ENT_QUOTES | ENT_SUBSTITUTE;

        if ($is_pretty) {
            $config_encoded = json_encode($config_array, JSON_PRETTY_PRINT);

            echo '<pre>';
            echo htmlspecialchars($config_encoded, $escape_flags, 'UTF-8');
            echo '</pre>';
        }
        else {
            $config_encoded = json_encode($config_array);
            echo htmlspecialchars($config_encoded, $escape_flags, 'UTF-8');
        }

        exit();
    }

    public static function add_config_script() {
        $config_json = get_option(self::CONFIG_OPTION_NAME, null);

        if (!$config_json) {
            return;
        }

        $config = json_decode($config_json, true);
        if (!is_array($config)) {
            WCISPlugin::console_error_inline("Failed to decode upsell widgets config.");
            return;
        }


        $custom_css_minified = self::get_minified_custom_css($config);
        $config['customCSS'] = $custom_css_minified;

        $json_flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_INVALID_UTF8_SUBSTITUTE;
        $config_json = wp_json_encode($config, $json_flags);
        if (false === $config_json) {
            WCISPlugin::console_error_inline("Failed to encode upsell widgets config JSON.");
            return;
        }

        wp_register_script( self::$config_script_handler, '', [], null, true );
        wp_add_inline_script( self::$config_script_handler, 'window.FAST_UPSELL_CONFIG = ' . $config_json . ';');
        wp_enqueue_script(self::$config_script_handler);

        self::$config_added = true;

        return;
    }

    private static function minify_css($css) {
        // remove comments
        $css = preg_replace('!/\*.*?\*/!s', '', $css);
        // remove space after colons
        $css = preg_replace('/\s*:\s*/', ':', $css);
        // remove whitespace
        $css = preg_replace('/\s+/', ' ', $css);
        // remove unnecessary spaces
        $css = preg_replace('/;\s*/', ';', $css);
        $css = preg_replace('/\{\s*/', '{', $css);
        $css = preg_replace('/\}\s*/', '}', $css);
        $css = preg_replace('/,\s*/', ',', $css);

        return trim($css);
    }

    private static function get_minified_custom_css($config) {
        $cached = get_transient(self::CUSTOM_CSS_TRANSIENT_NAME);
        if ($cached !== false) {
            return $cached;
        }

        return self::set_minified_custom_css_transient($config);
    }

    private static function set_minified_custom_css_transient($config) {
        $css_raw = $config['customCSS'] ?? '';
        $minified = self::minify_css($css_raw);

        $week_in_seconds = 3600 * 24 * 7;
        set_transient(self::CUSTOM_CSS_TRANSIENT_NAME, $minified,  $week_in_seconds);

        return $minified;
    }

    /**
     * Embed upsell & cross-sell widget inside a template
     *
     * @param array $attr Shortcode attributes.
     * @return string
     */
    public static function widget_shortcode($attr)
    {
        $attr = shortcode_atts(array('id' => 0), $attr, self::UPSELL_WIDGET_SHORTCODE);

        if (empty($attr['id'])) {
            return '<p>Please add the id parameter to the shortcode, using a valid 
                       Upsell & Cross-Sell widget ID from the Fast Simon dashboard → 
                       Upsell & Cross-Sell tab → Widgets. For example: [' .
                       self::UPSELL_WIDGET_SHORTCODE . ' id="0123456789"]</p>';
        }

        $is_config_set =  !empty(get_option(self::CONFIG_OPTION_NAME));
        if (!$is_config_set) {
            return '<p>Styling for Upsell & Cross-Sell Widgets has not been set yet. 
                       Please visit the Fast Simon dashboard → Upsell & Cross-Sell 
                       tab → Widgets tile,  create/edit a widget, and save it.
                    </p>';
        }

        self::$is_widget_on_page = true;

        return sprintf('
            <!-- Fast Simon Product Recommendation Widget START -->
            <div class="fast-simon-new-upsell-%1$s" 
                 data-settings="FAST_UPSELL_CONFIG" 
                 style="display:block;height:100%%;"> 
            </div>
            <!-- Fast Simon Product Recommendation Widget END -->',
            esc_attr($attr['id'])
        );
    }

    public static function enqueue_upsell_scripts() {
        if (self::$is_widget_on_page) {
            self::add_config_script();
            self::add_init_script();
        }
    }

    public static function add_init_script() {
        $uuid = get_option('wcis_site_id');
        $store_id = get_current_blog_id();
        $upsell_js = 'https://static-recommendations.fastsimon.com/' .
            'no-code-recommendations/fs-recommendations-init.js';

        $script_src = add_query_arg(
            [
                'uuid'      => $uuid,
                'store_id'  => $store_id,
                'platform'  => 'WooCommerce'
            ],
            $upsell_js
        );

        wp_register_script(
            self::$init_script_handle, $script_src, [self::$config_script_handler], null, true);

        if ( function_exists('wp_script_add_data') && !self::$is_async_filter_added) {
            wp_script_add_data( self::$init_script_handle, 'async', true );
            self::$is_async_filter_added = true;
        } else if (!self::$is_async_filter_added) {
            add_filter('script_loader_tag', function ($tag, $handle) {
                if ($handle === self::$init_script_handle &&
                        !preg_match('/\sasync(\s|>)/i', $tag)) {
                    $tag = preg_replace('/<script\b/',
                        '<script async', $tag, 1);
                }
                return $tag;
            }, 10, 2);

            self::$is_async_filter_added = true;
        }

        wp_enqueue_script(self::$init_script_handle);
    }
}