<?php

namespace DgoraWcas;

use DgoraWcas\Engines\TNTSearchMySQL\Indexer\Builder;
use DgoraWcas\Engines\TNTSearchMySQL\SearchQuery\SearchResultsPageQuery;
// Exit if accessed directly
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
class Search {
    /**
     * Search posts (products, posts or pages)
     *
     * @param string $phrase Search phrase.
     * @param array $args {
     *     Search arguments.
     *
     * @type string $post_type Post type.
     * @type string $fields Format of returned data. Accepts: 'ids', 'all'.
     * @type int $per_page The number of results to search for. Use -1 to request all results.
     * @type int $page The number of the current page.
     * @type int $offset The number of results to offset before retrieval.
     * @type string $orderby Sort retrieved results by parameter. Only in Pro version. Accepts: 'relevance', 'price', 'date', 'rating', 'popularity'.
     * @type string $order Designates ascending or descending order of results. Only in Pro version. Accepts: 'desc', 'asc'.
     * @type string $lang Language.
     * }
     *
     * @return array|\WP_Error
     */
    public function searchPosts( $phrase, $args ) {
        $args = wp_parse_args( $args, array(
            'post_type' => 'product',
            'fields'    => 'ids',
            'per_page'  => 10,
            'page'      => 1,
            'offset'    => 0,
            'orderby'   => 'relevance',
            'order'     => '',
            'lang'      => '',
        ) );
        $args = $this->validateArgs( $args );
        if ( is_wp_error( $args ) ) {
            return $args;
        }
        if ( !dgoraAsfwFs()->is_premium() ) {
            list( $results, $totalResults, $totalPages ) = $this->doSearch( $phrase, $args );
        }
        $response = array(
            'results'     => $results,
            'total'       => $totalResults,
            'total_pages' => $totalPages,
        );
        return json_decode( json_encode( $response ), true );
    }

    /**
     * Do a search via WordPress.
     *
     * @param string $phrase Search phrase.
     * @param array $args Search arguments.
     *
     * @return array Array with results.
     */
    private function doSearch( $phrase, $args ) : array {
        $searchResults = DGWT_WCAS()->nativeSearch->getSearchResults( $phrase, true, 'product-ids' );
        $results = array();
        if ( isset( $searchResults['suggestions'] ) && is_array( $searchResults['suggestions'] ) ) {
            $results = wp_list_pluck( $searchResults['suggestions'], 'ID' );
        }
        /*
         * If there are no results, native search returns a dummy product ID = 0 to force integrations to have no results.
         * However, here, when there are no results, we just want to return an empty array.
         */
        if ( isset( $results[0] ) && $results[0] === 0 ) {
            $results = array();
        }
        $totalResults = count( $results );
        $totalPages = (int) ceil( $totalResults / $args['per_page'] );
        if ( $args['page'] > $totalPages ) {
            $args['page'] = $totalPages;
        }
        if ( $args['per_page'] > 0 ) {
            $offset = ($args['page'] - 1) * $args['per_page'] + $args['offset'];
            $results = array_slice( $results, $offset, $args['per_page'] );
        } else {
            $totalPages = 1;
        }
        if ( $totalResults === 0 ) {
            $totalPages = 0;
        }
        if ( $args['fields'] === 'ids' ) {
            return array($results, $totalResults, $totalPages);
        }
        $results = DGWT_WCAS()->nativeSearch->getProductsData( $results, -1, array('price', 'sku', 'thumb_html') );
        return array($results, $totalResults, $totalPages);
    }

    /**
     * Validate search arguments
     *
     * @param array $args Search arguments.
     *
     * @return array|\WP_Error
     */
    private function validateArgs( $args ) {
        $error = new \WP_Error();
        $args['per_page'] = (int) $args['per_page'];
        if ( $args['per_page'] < -1 ) {
            $args['per_page'] = abs( $args['per_page'] );
        } elseif ( $args['per_page'] === 0 ) {
            $args['per_page'] = 1;
        }
        $args['offset'] = (int) $args['offset'];
        if ( $args['offset'] < 0 ) {
            $args['offset'] = 0;
        }
        $allowedPostTypes = array('product');
        if ( !in_array( $args['post_type'], $allowedPostTypes, true ) ) {
            $error->add( 'dgwt-wcas-invalid-arg-post-type', 'Invalid argument: post_type' );
        }
        if ( !in_array( $args['fields'], array('all', 'ids'), true ) ) {
            $error->add( 'dgwt-wcas-invalid-arg-fields', 'Invalid argument: fields' );
        }
        if ( $error->has_errors() ) {
            return $error;
        }
        return $args;
    }

}
