<?php
if (!defined('ABSPATH'))
    die('No direct access allowed');

//02-12-2017
final class WOOF_EXT_QUICK_TEXT extends WOOF_EXT {

    public $type = 'application';
    public $folder_name = 'quick_search'; //should be defined!!
    //***
    public $cron = NULL;
    public $cron_system = 0;
    public $wp_cron_period = 'daily';
    public $tax_conditional = '';
    public $tax_serch_data = array();

    //***

    public function __construct() {
        parent::__construct();

        //***
        if (isset($this->woof_settings['woof_quick_search']['wp_cron_period']) AND ! empty($this->woof_settings['woof_quick_search']['wp_cron_period'])) {
            $this->wp_cron_period = $this->woof_settings['woof_quick_search']['wp_cron_period'];
        }
        if (isset($this->woof_settings['woof_quick_search']['quick_search_tax_conditionals']) AND ! empty($this->woof_settings['woof_quick_search']['quick_search_tax_conditionals'])) {
            $this->tax_conditional = $this->woof_settings['woof_quick_search']['quick_search_tax_conditionals'];
        }
        if (isset($this->woof_settings['woof_quick_search']['items_for_text_search']) AND ! empty($this->woof_settings['woof_quick_search']['items_for_text_search'])) {
            $this->tax_serch_data = $this->woof_settings['woof_quick_search']['items_for_text_search'];
        }
        $this->cron_system = 0;
        //***
        if (false) {
            $this->cron = new PN_WP_CRON_WOOF('woof_quick_search_cron');
            //***
            if ($this->cron_system === 1) {
                $this->woof_stat_wpcron_init(true);
                if (isset($_GET['woof_quick_search_collection'])) {
                    $cron_secret_key = 'woof_quick_search_updating';
                    if (isset($this->woof_settings['woof_quick_search']['cron_secret_key']) AND ! empty($this->woof_settings['woof_quick_search']['cron_secret_key'])) {
                        $cron_secret_key = sanitize_title($this->woof_settings['woof_quick_search']['cron_secret_key']);
                    }
                    if ($_GET['woof_quick_search_collection'] === $cron_secret_key) {
                        $this->create_data_search_files();
                        die('woof quick text assemble done!');
                    }
                }
            } else {
                add_action('woof_quick_search_wpcron', array($this, 'create_data_search_files_when_init'), 10);
                $this->woof_quick_wpcron_init();
            }
        }

        $this->init();
    }

    public function get_ext_path() {
        return plugin_dir_path(__FILE__);
    }

    public function get_ext_link() {
        return plugin_dir_url(__FILE__);
    }

    public function init() {
        add_shortcode('woof_quick_search', array($this, 'quick_search'));
        add_shortcode('woof_quick_search_results', array($this, 'quick_search_result'));
        add_action('woof_print_applications_tabs_' . $this->folder_name, array($this, 'woof_print_applications_tabs'), 10, 1);
        add_action('woof_print_applications_tabs_content_' . $this->folder_name, array($this, 'woof_print_applications_tabs_content'), 10, 1);
        //self::$includes['js']['woof_quick_search_html_items'] = $this->get_ext_link() . 'js/quick_search.js';
        self::$includes['css']['woof_' . $this->folder_name . '_html_items'] = $this->get_ext_link() . 'css/' . $this->folder_name . '.css';
        add_action('wp_footer', array($this, 'wp_footer'), 12);
        //ajax
        add_action('wp_ajax_woof_qt_update_file', array($this, 'create_data_search_files'));
        add_action('wp_ajax_nopriv_woof_qt_update_file', array($this, 'create_data_search_files'));
    }

    public function quick_search($atts) {
        global $WOOF;
        $data = (shortcode_atts(array(
                    'short_id' => '0000', /* this is needed when using several data files now it is not used */
                    'preload' => 1, /* download a file  with the page = 1    file download by click =0 */
                    'placeholder' => __('Text search', 'woocommerce-products-filter'),
                    'price_filter' => 0, /* show price filter  1 or 0 ( only for extended filter ) */
                    'extended_filter' => 0, /* use  extend filter(alaSQL) with special template  1 or 0 */
                    'target' => '_blank', /* link behavior */
                    'reset_btn' => 1, /* show reset btn   1 or 0 ( only for extended filter ) */
                    'add_filters' => '', /* [drop-down|multi-drop-down|checkbox|radio] example  drop-down:product_cat,multi-drop-down:pa_size ( only for extended filter ) */
                    'filter_title' => '', /* Example "product_cat:Type,pa_size:Color of the item" ( only for extended filter ) */
                    'term_logic' => '', /* example  pa_color:AND,product_cat:OR ( only for extended filter ) */
                    'tax_logic' => 'AND', /*  logic  beetwin taxonomies  AND or OR ( only for extended filter ) */
                    'text_group_logic' => 'AND', /* logic for a few words, all words must be found=AND   [AND | OR} ( only for extended filter ) */
                    'exclude_terms' => '', /* ids any taxonomies exclude_terms="56,5288,8,1299"  ( only for extended filter ) */
                    'reset_text' => __('Reset', 'woocommerce-products-filter'),
                    'class' => 'woof_qs_3_col',
                        ), $atts));

        $curr_lang = 'xxx';
        if (class_exists('SitePress')) {
            $curr_lang = ICL_LANGUAGE_CODE;
        }
        $_REQUEST['woof_qt'] = true;
        $_REQUEST['woof_quick_search_link'] = $this->get_ext_link() . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'data_' . $data['short_id'] . '_' . $curr_lang . '.json';
        //$_REQUEST['woof_quick_search_preload']=$data['preload'];
        //$_REQUEST['woof_quick_search_extended']=$data['extended_filter'];
        return $WOOF->render_html($this->get_ext_path() . 'views' . DIRECTORY_SEPARATOR . 'shortcodes' . DIRECTORY_SEPARATOR . 'woof_quick_search.php', $data);
    }

    public function create_data_search_files_when_init() {
        add_action('init', array($this, 'create_data_search_files'));
    }

    public function quick_search_result($atts) {
        global $WOOF;
        $data = (shortcode_atts(array(
                    'per_page' => 12,
                    'template_result' => 'list_1',
                    'always_show_products' => 1,
                    'template_structure' => 'img,title,price,sku,key_words',
                    'orderby' => 'title-asc',
                    'header_text' => "",
                        ), $atts));
        $data = apply_filters('woof_qs_shortcode_data', $data); // possibility to change a template for example for a mobile
        $_REQUEST['woof_qt_extended'] = $data['template_result'];
        $all_data = array();
        $all_data['data'] = $data;
        return $WOOF->render_html($this->get_ext_path() . 'views' . DIRECTORY_SEPARATOR . 'shortcodes' . DIRECTORY_SEPARATOR . 'woof_quick_search_results.php', $all_data);
    }

    public function wp_footer() {
        if (!isset($_REQUEST['woof_qt'])) {
            return;
        }
        if (isset($_REQUEST['woof_qt_extended'])) {
            wp_enqueue_script('woof_alasql', $this->get_ext_link() . "/js/alasql/alasql.min.js",array(),WOOF_VERSION);
            $parse_tpl = explode("/", $_REQUEST['woof_qt_extended']);
            if (count($parse_tpl) > 1 AND $parse_tpl[0] == 'custom') {
                wp_enqueue_style('woof_qs_style', get_stylesheet_directory_uri() . "/woof_qs_templates/" . $parse_tpl[1] . "/css/" . $parse_tpl[1] . ".css",array(),WOOF_VERSION);
                wp_enqueue_script('woof_qs_script', get_stylesheet_directory_uri() . "/woof_qs_templates/" . $parse_tpl[1] . "/js/" . $parse_tpl[1] . ".js",array(),WOOF_VERSION);
            } else {
                wp_enqueue_style('woof_qs_style', $this->get_ext_link() . "/views/templates/" . $parse_tpl[0] . "/css/" . $parse_tpl[0] . ".css",array(),WOOF_VERSION);
                wp_enqueue_script('woof_qs_script', $this->get_ext_link() . "/views/templates/" . $parse_tpl[0] . "/js/" . $parse_tpl[0] . ".js",array(),WOOF_VERSION);
            }
        } else {
            wp_enqueue_script('easy-autocomplete', WOOF_LINK . 'js/easy-autocomplete/jquery.easy-autocomplete.min.js',array(),WOOF_VERSION);
            wp_enqueue_style('easy-autocomplete', WOOF_LINK . 'js/easy-autocomplete/easy-autocomplete.min.css',array(),WOOF_VERSION);
            wp_enqueue_style('easy-autocomplete-theme', WOOF_LINK . 'js/easy-autocomplete/easy-autocomplete.themes.min.css',array(),WOOF_VERSION);
        }
        wp_enqueue_script('woof_quick_search', $this->get_ext_link() . 'js/quick_search.js',array(),WOOF_VERSION);
        $link = '';
        if (isset($_REQUEST['woof_quick_search_link'])) {
            $link = $_REQUEST['woof_quick_search_link'];
        } else {
            $link = $this->get_ext_link() . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'data_0000_xxx.json';
        }
        $currency_data = array();
        if (class_exists('WOOCS')) {
            global $WOOCS;
            $currencies = $WOOCS->get_currencies();
            $currency_data['symbol'] = $currencies[$WOOCS->default_currency]['symbol'];
            $currency_data['decimal'] = $currencies[$WOOCS->default_currency]['decimals'];
            $currency_data['position'] = $currencies[$WOOCS->default_currency]['position'];
        } else {
            $currency_data['symbol'] = get_woocommerce_currency_symbol();
            $currency_data['decimal'] = wc_get_price_decimals();
            $currency_data['position'] = get_option('woocommerce_currency_pos');
        }
        $currency_data['t_separ'] = wc_get_price_thousand_separator();
        $currency_data['d_separ'] = wc_get_price_decimal_separator();
        $text_data = array(
            'link' => $link,
            'site_url' => get_site_url(),
            'no_image' => '/wp-content/plugins/woocommerce/assets/images/placeholder.png',
            'currency_data' => $currency_data,
        );
        wp_localize_script('woof_quick_search', 'wooftextfilelink', $text_data);
    }

    public function woof_print_applications_tabs() {
        ?>
        <li>
            <a href="#tabs-quick-text">
                <svg viewBox="0 0 80 60" preserveAspectRatio="none"><use xlink:href="#tabshape"></use></svg>
                <svg viewBox="0 0 80 60" preserveAspectRatio="none"><use xlink:href="#tabshape"></use></svg>
                <span><?php _e("Quick search", 'woocommerce-products-filter') ?></span>
            </a>
        </li>
        <?php
    }

    public function woof_print_applications_tabs_content() {
        wp_enqueue_script('woof_qs_admin_', $this->get_ext_link() . 'js/admin.js',array(),WOOF_VERSION);
        //***
        global $WOOF;
        $data = array();

        $data['woof_settings'] = $this->woof_settings;

        echo $WOOF->render_html($this->get_ext_path() . 'views/tabs_content.php', $data);
    }

    public function get_woof_cron_schedules($key = '') {
        $schedules = array(
            'daily' => DAY_IN_SECONDS,
            'week' => WEEK_IN_SECONDS,
            'twicemonthly' => WEEK_IN_SECONDS * 2,
            'month' => WEEK_IN_SECONDS * 4,
            'min1' => MINUTE_IN_SECONDS,
        );

        if (!empty($key)) {
            return $schedules[$key];
        }

        return $schedules;
    }

    public function create_data_search_files() {
        global $WOOF;
        $tax_query = array();
        $start = 0;
        $step = 10;
        $do = true;
        $id = "0000";

        if (isset($_POST['qs_start'])) {
            $start = intval($_POST['qs_start']);
        }

        /*
          if(!isset($_REQUEST['woof_qt_update_file']) OR !wp_verify_nonce( $_REQUEST['woof_qt_update_file'], 'woof-qs-nonce' )){
          $result = array( 'total' => -1);
          echo json_encode( $result );
          exit;
          }
         *
         */

        if ($start == 0) {
            $this->delete_all_files();
            ;
        }
        $tax_query = $this->_expand_additional_taxes_string($this->tax_conditional, $tax_query);
        if (version_compare(WOOCOMMERCE_VERSION, '3.0', '>=')) {
            $tax_query[] = array(
                'taxonomy' => 'product_visibility',
                'field' => 'name',
                'terms' => 'exclude-from-catalog',
                'operator' => 'NOT IN',
            );
        }
        $args = array(
            'post_type' => array('product'/* ,'product_variation' */),
            'post_status' => 'publish',
            'tax_query' => $tax_query,
            'offset' => $start,
            'posts_per_page' => $step,
            'fields' => 'ids',
            'cache_results' => false,
            //'no_found_rows'=>false,
            'update_post_meta_cache' => false,
            'update_post_term_cache' => false,
            'orderby' => 'ID',
            'order' => 'DESC',            
        );

        if (class_exists('SitePress')) {
            global $sitepress;
            $default_lang = $sitepress->get_default_language(); // Get WPML default language
            $current_lang = $sitepress->get_current_language(); //save current language
            $sitepress->switch_lang($default_lang);
        }

        $start += $step;
        $limit = apply_filters("woof_quick_search_products_limit", 10000);
        if ($start > $limit) { // limiting the number of products
            $do = false;
        }
        $product_ids = new WP_Query($args);
        if ($product_ids->found_posts < 1) {
            $do = false;
        }
        if ($do) {
            if ($product_ids->found_posts < $step) {
                $start -= $step;
                $start += $product_ids->found_posts;
            }

            $this->push_products_data($product_ids, $id);
        } else {
            $start = -1;
        }
        $result = array('total' => $start);
        echo json_encode($result);
        exit;
    }

    public function push_products_data($product_ids, $id) {
        $langs = $this->get_all_lang_wpml();
        $posts = array();
        $posts_data = array();

        if ($langs) {
            foreach ($langs as $lang) {
                $posts_data = array();
                foreach ($product_ids->posts as $post) {
                    $posts_lang = $this->get_post_id_by_lang($post, $lang['language_code']);
                    if ($posts_lang) {
                        $posts_data[] = $this->get_data_by_id($posts_lang, $lang['language_code']);
                    }
                }
                $this->push_data_into_file($posts_data, $id, $lang['language_code']);
            }
        } else {

            foreach ($product_ids->posts as $post) {
                //$posts[]=$post->ID;
                $posts_data[] = $this->get_data_by_id($post);
            }
            $this->push_data_into_file($posts_data, $id);
        }
    }

    public function get_data_by_id($id, $lang = 'xxx') {
        global $WOOF;
        if (!$id OR $id < 1) {
            return array();
        }
        $product = wc_get_product($id);
        if (!$product) {
            return array();
        }
        $data = array();
        $data['id'] = $id;
        $data['title'] = $product->get_name();
        $data['url'] = $product->get_permalink();
        $img = wp_get_attachment_image_src($product->get_image_id($id), 'shop_single');
        $data['img'] = $this->optimize_url($img[0]);
        $data['sku'] = $product->get_sku();
        $data['price'] = $this->get_all_prices($product);
        $data['key_words'] = "";
        $data['term_ids'] = " ";
        $data['meta_data'] = array();
        $term_ids = array();
        $all_taxonomies = $WOOF->get_taxonomies();
        foreach ($this->tax_serch_data as $tax) {
            unset($all_taxonomies[$tax]); //not to do double work  (get all id terms)
            $terms = get_the_terms($id, $tax);
            if (!is_array($terms)) {
                continue;
            }
            $term_name = array();
            $term_ids = array();
            foreach ($terms as $term) {
                $term_ids[] = $term->term_id;
                $term_name[] = html_entity_decode($term->name);
            }
            if (!empty($term_name)) {
                if (!empty($data['key_words'])) {
                    $data['key_words'] .= "; ";
                }
                $data['key_words'] .= implode(', ', $term_name);
            }
            if (!empty($term_ids)) {
                $data['term_ids'] .= " ";
                $data['term_ids'] .= implode(' ', $term_ids);
            }
        }
        $data['term_ids'] .= " ";
        if (true) {   // if you want search in all taxonomies by additional filters( ignore $this->tax_serch_data )
            foreach ($all_taxonomies as $key_slug => $val_tax) {
                $_terms = get_the_terms($id, $key_slug);
                if (!is_array($_terms)) {
                    continue;
                }
                $term_ids = array();
                foreach ($_terms as $term) {
                    $term_ids[] = $term->term_id;
                }
                if (!empty($term_ids)) {
                    //$data['term_ids'].=" ";
                    $data['term_ids'] .= implode(' ', $term_ids);
                }
                $data['term_ids'] .= " ";
            }
        }
        $data['meta_data'] = $this->get_meta_data_by_id($id);
        //wp_cache_flush();
        return $data;
    }

    public function get_meta_data_by_id($id) {
        $meta_data = array();
        if (class_exists('WOOF_META_FILTER')) {
            $meta_fields = $this->woof_settings['meta_filter'];
            if (!empty($meta_fields)) {
                foreach ($meta_fields as $key => $meta) {
                    if ($meta['meta_key'] == "__META_KEY__") {
                        continue;
                    }
                    $meta = get_post_meta($id, $meta['meta_key'], true);
                    if ($meta) {
                        $meta_data[$key] = $meta;
                    }
                }
            }
        }
        return $meta_data;
    }

    public function get_all_prices($product) {
        if (!$product) {
            return array();
        }
        $include_tax = false;
        if (wc_tax_enabled() && 'incl' === get_option('woocommerce_tax_display_shop') && !wc_prices_include_tax()) {
            $include_tax = true;
        }
        if (class_exists('WOOCS')) {
            global $WOOCS;
            $def_currency = $WOOCS->default_currency;
            if ($def_currency != $WOOCS->current_currency) {
                $WOOCS->current_currency = $def_currency;
                $WOOCS->storage->set_val('woocs_current_currency', $def_currency);
            }
        }
        //$product = wc_get_product($id);
        $prices = array();
        if ($product->is_type('variable')) {
            $available_variations = $product->get_children();
            foreach ($available_variations as $var_id) {
                $var_product = wc_get_product($var_id);
                $regular_v = $var_product->get_regular_price();
                $sale_v = $var_product->get_sale_price();
                if ($include_tax) {
                    $regular_v = wc_get_price_including_tax($var_product, array('price' => $regular_v));
                    $sale_v = wc_get_price_including_tax($var_product, array('price' => $sale_v));
                }
                $prices[] = array(
                    'regular' => $regular_v,
                    'sale' => $sale_v,
                );
            }
        } else {
            $regular = $product->get_regular_price();
            $sale = $product->get_sale_price();
            if ($include_tax) {
                $regular = wc_get_price_including_tax($product, array('price' => $regular));
                $sale = wc_get_price_including_tax($product, array('price' => $sale));
            }
            $prices[] = array(
                'regular' => $regular,
                'sale' => $sale,
            );
        }
        return $prices;
    }

    // wpml compatibility
    public function get_all_lang_wpml() {
        if (class_exists('SitePress')) {
            return $langs = icl_get_languages('skip_missing=0&orderby=KEY&order=DIR&link_empty_to=str');
        }
        return false;
    }

    public function get_post_id_by_lang($post_id, $lang_code, $type = 'product') {
        if (class_exists('SitePress')) {
            return icl_object_id($post_id, $type, false, $lang_code);
        }
        return false;
    }

    // +++

    public function woof_quick_wpcron_init($reset = false) {
        $hook = 'woof_quick_search_wpcron';

        if ($reset) {
            $this->cron->remove($hook);
            return;
        }

        if ($this->cron_system === 0) {//wp cron
            if (!$this->cron->is_attached($hook, $this->get_woof_cron_schedules($this->wp_cron_period))) {
                $this->cron->attach($hook, time(), $this->get_woof_cron_schedules($this->wp_cron_period));
            }

            $this->cron->process();
        }
    }

    //  File works
    private function delete_all_files() {
        $path = $this->get_ext_path() . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR;
        if ($handle = opendir($path)) {
            while (false !== ($file = readdir($handle)))
                if ($file != "." && $file != "..")
                    unlink($path . $file);
            closedir($handle);
        }
    }

    private function push_data_into_file($data, $id = '0000', $lang = 'xxx') {

        $file = $this->get_ext_path() . '/data/data_' . $id . '_' . $lang . '.json';
        try {
            clearstatcache(true, $file);
        } catch (Exception $e) {
            
        }
        //***
        if ($fh = fopen($file, 'a+')) {

            if ($fh) {
                $contents = '';
                $file_size = filesize($file);

                if ($file_size > 0) {
                    $contents = fread($fh, $file_size);
                }
                //***
                if (!empty($contents)) {
                    $contents = json_decode(trim($contents), true);

                    if (json_last_error() === JSON_ERROR_NONE) {
                        $data = array_merge($contents, $data);
                    }
                }
                //***
                ftruncate($fh, 0);
                fwrite($fh, json_encode($data));
                fclose($fh);

                return true;
            }
        }

        return false;
    }

    private function _expand_additional_taxes_string($additional_taxes, $res = array()) {
        if (!empty($additional_taxes)) {
            $t = explode('+', $additional_taxes);
            if (!empty($t) AND is_array($t)) {
                foreach ($t as $string) {
                    $tmp = explode(':', $string);
                    $tax_slug = $tmp[0];
                    $tax_terms = explode(',', $tmp[1]);
                    $slugs = array();
                    foreach ($tax_terms as $term_id) {
                        $term = get_term(intval($term_id), $tax_slug);
                        if (is_object($term)) {
                            $slugs[] = $term->slug;
                        }
                    }

                    //***
                    if (!empty($slugs)) {
                        $res[] = array(
                            'taxonomy' => $tax_slug,
                            'field' => 'slug', //id
                            'terms' => $slugs
                        );
                    }
                }
            }
        }

        return $res;
    }

    //themplate helper
    public static function show_sort_html_by_title() {
        return self::show_sort_html('title-asc', 'title-desc');
    }

    public static function show_sort_html_by_price() {
        return self::show_sort_html('price-asc', 'price-desc');
    }

    public static function show_sort_html_select() {
        $data = array(
            'price-asc' => sprintf(__('Price- %s ', 'woocommerce-products-filter'), '&uarr;'),
            'price-desc' => sprintf(__('Price- %s ', 'woocommerce-products-filter'), '&darr;'),
            'title-asc' => sprintf(__('Title- %s ', 'woocommerce-products-filter'), '&uarr;'),
            'title-desc' => sprintf(__('Title- %s ', 'woocommerce-products-filter'), '&darr;'),
        );
        return self::show_sort_select_html(apply_filters('woof_qs_sort_select_data', $data));
    }

    public static function show_sort_html($asc = 'title-asc', $desc = 'title-desc') {
        global $WOOF;
        $data = array(
            'asc' => $asc,
            'desc' => $desc,
        );
        return $WOOF->render_html(WOOF_EXT_PATH . 'quick_search' . DIRECTORY_SEPARATOR . 'views/sort_html.php', $data);
    }

    public static function show_sort_select_html($args) {
        $data = array(
            'sort' => $args,
        );
        global $WOOF;
        return $WOOF->render_html(WOOF_EXT_PATH . 'quick_search' . DIRECTORY_SEPARATOR . 'views/sort_select_html.php', $data);
    }

    //+++
    public static function parse_template_structure($str) {
        $tpl_str = array(); //array('key'=>'title',title=>'Title',class=>'woof_qs_title','alias'=>'__TITLE__')
        //img,title,price,sku,key_words
        $default_titles = array(
            'title' => __('Title', 'woocommerce-products-filter'),
            'img' => '',
            'price' => __('Price', 'woocommerce-products-filter'),
            'sku' => __('SKU', 'woocommerce-products-filter'),
            'key_words' => __('Tags', 'woocommerce-products-filter'),
        );
        $temp_arr = explode(',', $str);
        foreach ($temp_arr as $item) {
            $item = trim($item);
            if (!isset($default_titles[$item])) {
                continue;
            }
            $tpl_str[$item] = array(
                'key' => $item,
                'title' => $default_titles[$item],
                'class' => 'woof_qs_' . $item,
                'alias' => sprintf("__%s__", strtoupper($item))
            );
        }

        return apply_filters('woof_qs_get_template_structure', $tpl_str);
    }

    public function optimize_url($url) {
        $site_url = get_site_url();
        return str_replace($site_url, "", $url);
    }

}

WOOF_EXT::$includes['applications']['quick_search'] = new WOOF_EXT_QUICK_TEXT();
