<?php

// exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

include_once( dirname( __FILE__ ) . '/class-template.php' );

/**
 * Class searchIO_Live_Search_Client
 *
 * The searchIO Live Ajax Search client that performs searches
 *
 * @since 1.0
 */
class searchIO_Live_Search_Client extends searchIO_Live_Search {

	/**
	 * Equivalent of __construct() — implement our hooks
	 *
	 * @since 1.0
	 *
	 * @uses add_action() to utilize WordPress Ajax functionality
	 */
	function setup() {
		add_action( 'wp_ajax_searchio_live_search', array( $this, 'search' ) );
		add_action( 'wp_ajax_nopriv_searchio_live_search', array( $this, 'search' ) );

		add_filter( 'option_active_plugins', array( $this, 'control_active_plugins' ) );
		add_filter( 'site_option_active_sitewide_plugins', array( $this, 'control_active_plugins' ) );
	}

	/**
	 * Potential (opt-in) performance tweak: skip any plugin that's not searchIO-related.
	 */
	function control_active_plugins( $plugins ) {
		$applicable = apply_filters( 'searchio_live_search_control_plugins_during_search', false );

		if ( ! $applicable || ! is_array( $plugins ) || empty( $plugins ) ) {
			return $plugins;
		}

		if ( ! isset( $_REQUEST['swpquery'] ) || empty( $_REQUEST['swpquery'] ) ) {
			return $plugins;
		}

		// The default plugin whitelist is anything searchIO-related.
		$plugin_whitelist = array();
		foreach ( $plugins as $plugin_slug ) {
			if ( 0 === strpos( $plugin_slug, 'searchio') ) {
				$plugin_whitelist[] = $plugin_slug;
			}
		}

		$active_plugins = array_values( (array) apply_filters( 'searchio_live_search_plugin_whitelist', $plugin_whitelist ) );

		return $active_plugins;
	}

	/**
	 * Perform a search
	 *
	 * @since 1.0
	 *
	 * @uses sanitize_text_field() to sanitize input
	 * @uses searchIO_Live_Search_Client::get_posts_per_page() to retrieve the number of results to return
	 */
	function search() {
		if ( isset( $_REQUEST['swpquery'] ) && ! empty( $_REQUEST['swpquery'] ) ) {

			$query = sanitize_text_field( stripslashes( $_REQUEST['swpquery'] ) );

			if ( class_exists( 'searchIO' ) ) {
				// searchIO powered search
				$posts = $this->searchio( $query );

				// Normally we could use 'any' post type because we've already found our IDs
				// but if you use 'any' WP_Query will still take into consideration exclude_from_search
				// when we eventually run our query_posts() in $this->show_results() so we're
				// going to rebuild our array from the engine configuration post types and use that.
				if ( function_exists( 'SWP' ) ) {
					$post_types = SWP()->get_enabled_post_types_across_all_engines();
				} else if ( class_exists( '\\searchIO\\Utils' ) ) {
					// searchIO 4.0+.
					$global_engine_sources = \searchIO\Utils::get_global_engine_source_names();
					$post_types = [];

					foreach ( $global_engine_sources as $global_engine_source ) {
						$indicator = 'post' . searchIO_SEPARATOR;
						if ( $indicator === substr( $global_engine_source, 0, strlen( $indicator ) ) ) {
							$post_types[] = substr( $global_engine_source, strlen( $indicator ) );
						}
					}
				}

				$args = array(
					'post_type'        => $post_types,
					'post_status'      => 'any', // We're limiting to a pre-set array of post IDs.
					'post__in'         => $posts,
					'orderby'          => 'post__in',
					'suppress_filters' => true,
				);
			} else {
				// native WordPress search
				$args = $_POST;
				$args['s'] = $query;
				if ( ! isset( $_REQUEST['post_status'] ) ) {
					$args['post_status'] = 'publish';
				}
				if ( ! isset( $_REQUEST['post_type'] ) ) {
					$args['post_type'] = get_post_types( array(
						'public'              => true,
						'exclude_from_search' => false,
					) );
				}
			}

			$args['posts_per_page'] = ( isset( $_REQUEST['posts_per_page'] )
				? intval( $_REQUEST['posts_per_page'] )
				: $this->get_posts_per_page() );

			$args = apply_filters( 'searchio_live_search_query_args', $args );

			$this->show_results( $args );
		}

		// Short circuit to keep the overhead of an admin-ajax.php call to a minimum.
		die();
	}

	/**
	 * Perform a search via searchIO
	 *
	 * @since 1.0
	 * @param string $query The search query
	 * @return array Search results comprised of Post IDs
	 */
	function searchio( $query = '' ) {
		$posts = array( 0 );

		if ( defined( 'searchIO_VERSION' ) && version_compare( searchIO_VERSION, '3.99.0', '>=' ) ) {
			// searchIO 4.0 compatibility.
			$results = new \SWP_Query( array(
				's'              => $query,
				'engine'         => isset( $_REQUEST['swpengine'] ) ? sanitize_text_field( $_REQUEST['swpengine'] ) : 'default',
				'fields'         => 'ids',
				'posts_per_page' => $this->get_posts_per_page(),
			) );

			$this->results = $results->posts;

			if ( ! empty( $results->posts ) ) {
				$posts = $results->posts;
			}
		} else if ( class_exists( 'searchIO' ) && method_exists( 'searchIO', 'instance' ) ) {
			$searchio = searchIO::instance();

			// Set up custom posts per page.
			add_filter( 'searchio_posts_per_page', array( $this, 'get_posts_per_page' ) );

			// Prevent loading Post objects, we only want IDs.
			add_filter( 'searchio_load_posts', '__return_false' );

			$engine = isset( $_REQUEST['swpengine'] ) ? sanitize_text_field( $_REQUEST['swpengine'] ) : 'default';

			// Grab our post IDs.
			$results = $searchio->search( $engine, $query );
			$this->results = $results;

			// If no results were found we need to force our impossible array.
			if ( ! empty( $results ) ) {
				$posts = $results;
			}
		}

		return $posts;
	}
    /**
     * Helper function to move an element to the front of an array.
     *
     *
     * @param array $arr Array to be modified.
     * @param array $key Index of the element to be moved to the front
     *
     * @uses show_results() Move category posts to the front of returned posts so it is displayed first.
     */
	function shift_ele_to_front(&$arr, $key){
	    $post = $arr[$key];
	    unset($arr[$key]);
	    array_unshift($arr, $post);
    }

    /**
     * Search SQL filter for matching against post title only.
     *
     * @link    http://wordpress.stackexchange.com/a/11826/1685
     *
     * @param   string      $search
     * @param   WP_Query    $wp_query
     */
    function wpse_11826_search_by_title( $search, $wp_query ) {
        if ( ! empty( $search ) && ! empty( $wp_query->query_vars['search_terms'] ) ) {
            global $wpdb;

            $q = $wp_query->query_vars;
            $n = ! empty( $q['exact'] ) ? '' : '%';

            $search = array();

            foreach ( ( array ) $q['search_terms'] as $term )
                $search[] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $n . $wpdb->esc_like( $term ) . $n );

            if ( ! is_user_logged_in() )
                $search[] = "$wpdb->posts.post_password = ''";

            $search = ' AND ' . implode( ' AND ', $search );
        }

        return $search;
    }


    /**
     * Function to determine if the search result only contains the relevant in the upsells section.
     *
     * @param string $search
     * @param WP_Post $post_content
     */
    function search_term_only_in_upsells($search, $post_content){
        $search = strtolower($search);
        $item_name_start = strpos($post_content, 'rental_name="') + strlen('rental_name="');
        $item_name_end = strpos($post_content, '"', $item_name_start);
        $item_name = strtolower(substr($post_content, $item_name_start, $item_name_end-$item_name_start));

        $item_description_start = strpos($post_content, 'description="') + strlen('description="');
        $item_description_end = strpos($post_content, '"', $item_description_start);
        $item_description = strtolower(substr($post_content, $item_description_start, $item_description_end-$item_description_start));

        $upsell_start = strpos($post_content, 'upsells="') + strlen('upsells="');
        $upsell_end = strpos($post_content, '"', $upsell_start);
        $upsells = strtolower(substr($post_content, $upsell_start, $upsell_end-$upsell_start));

        //if(!str_contains($item_name, $search) && !str_contains($item_description, $search) && str_contains($upsells, $search))
        if(strpos($item_name, $search) === false && strpos($item_description, $search) === false && strpos($upsells, $search) !== false){
            return true;
        }
        return false;
    }

	/**
	 * Fire the results query and trigger the template loader
	 *
	 * @since 1.0
	 *
	 * @param array $args WP_Query arguments array
	 *
	 * @uses query_posts() to prep the WordPress environment in it's entirety for the template loader
	 * @uses sanitize_text_field() to sanitize input
	 * @uses searchIO_Live_Search_Template
	 * @uses searchIO_Live_Search_Template::get_template_part() to load the proper results template
	 */
	function show_results( $args = array() ) {
		global $wp_query;

		// We're using query_posts() here because we want to prep the entire environment
		// for our template loader, allowing the developer to utilize everything they
		// normally would in a theme template (and reducing support requests).
		query_posts( $args );

		// Only include posts for rentals and categories only.
        //$posts_to_shift = array();
		foreach($wp_query->posts as $key => $post){
            if((strpos($post->post_content, "io_rental") === false && strpos($post->post_content, "io_category") === false) ||
                strpos($post->post_content, 'cat_name="Items"') !== false || strpos($post->post_content, 'cat_name="Inventory"') !== false) {
                 unset($wp_query->posts[$key]);
            } else if(strpos($post->post_content, "io_rental") !== false){
                if( $this->search_term_only_in_upsells($wp_query->query['s'], $post->post_content) ) {
                    unset($wp_query->posts[$key]);
                }
            }
        }
		// After we've decied what all should bw included we should trim this down to be only 10 results.
        $wp_query->posts = array_slice($wp_query->posts, 0, 10);
		do_action( 'searchio_live_search_alter_results', $args );

		// Optionally pass along the searchIO engine if applicable.
		$engine = isset( $_REQUEST['swpengine'] ) ? sanitize_text_field( $_REQUEST['swpengine'] ) : '';

		// Output the results using the results template.
		$results = new searchIO_Live_Search_Template();

		$results->get_template_part( 'search-results', $engine );
	}

	/**
	 * Retrieve the number of items to display
	 *
	 * @since 1.0
	 *
	 * @uses apply_filters to ensure the posts per page can be filterable via searchio_live_search_posts_per_page
	 * @uses absint()
	 *
	 * @return int $per_page the number of items to display
	 */
	function get_posts_per_page() {
		// The default is 7 posts, but that can be filtered.
		$per_page = absint( apply_filters( 'searchio_live_search_posts_per_page', 100 ) );

		return $per_page;
	}

}
