<?php
/**
 * Plugin Name:       DooSearch - Ajax Search & Filters for WooCommerce
 * Description:       A blazing-fast WooCommerce search plugin with live AJAX search, SKU search, smart product filtering, custom search forms, and instant results.
 * Version:           1.0.3
 * Requires at least: 5.6
 * Requires PHP:      7.4
 * Author:            Aminul Islam
 * Requires Plugins: woocommerce
 * License:           GPL v2 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       doosearch-ajax-search-for-woo
 */

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

class DooSearchas_Search{
    /**
     * Constructor: Initialize plugin components and hooks.
     */
    function __construct(){
        $this->define_constants();
    
        // Load core functional files
        require_once(DOOSEARCHAS_SEARCH_PATH . 'functions/functions.php');
        require_once(DOOSEARCHAS_SEARCH_PATH . 'functions/doosearch-recent-slider.php');
        require_once(DOOSEARCHAS_SEARCH_PATH . 'functions/doosearch-cart-shortcode.php');
        require_once(DOOSEARCHAS_SEARCH_PATH . 'functions/customize-search-query.php');
        require_once(DOOSEARCHAS_SEARCH_PATH . 'functions/cart-ajax-hook.php');
        require_once(DOOSEARCHAS_SEARCH_PATH . 'functions/custom-rest-api.php');

        // Hook to add admin menu
        add_action('admin_menu', array($this, 'add_menu'),1);

        // Enqueue frontend scripts and styles
        add_action('wp_enqueue_scripts', array($this, 'register_scripts'), 999);

        // Enqueue admin scripts and styles
        add_action('admin_enqueue_scripts', array($this, 'register_admin_scripts'));

        // Initialize settings and shortcode classes
        require_once(DOOSEARCHAS_SEARCH_PATH . 'class.doosearch-search-settings.php');
        $doosearchas_search_settings = new DooSearchas_Search_Settings();
        require_once(DOOSEARCHAS_SEARCH_PATH . 'shortcodes/class.doosearch-search-shortcode.php');
        $doosearchas_search_shortcode = new DooSearchas_Search_Shortcode();
    }

    /**
     * Define plugin constants for path, URL, and version.
     */
    public function define_constants(){
        define('DOOSEARCHAS_SEARCH_PATH', plugin_dir_path(__FILE__));
        define('DOOSEARCHAS_SEARCH_URL', plugin_dir_url(__FILE__));
        define('DOOSEARCHAS_SEARCH_VERSION', '1.0.0');
    }

    /**
     * Register the main plugin settings menu page in WP admin.
     */
    public function add_menu(){
        add_menu_page( esc_html__('DOOSEARCH Options','doosearch-ajax-search-for-woo'), 'DooSearch', 'manage_options', 'doosearchas_search_menu_slug', array($this,'doosearchas_search_settings_page'), 'dashicons-search',50);
    }
    public function doosearchas_search_settings_page(){
        if( ! current_user_can(( 'manage_options') )){
            return;
        }
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if( isset( $_GET['settings-updated'])){
            add_settings_error('doosearchas_search_main_options', 'doosearchas_search_message_class', esc_html__('Settings Saved','doosearch-ajax-search-for-woo'), 'success');
        }
        settings_errors('doosearchas_search_main_options');
        require(DOOSEARCHAS_SEARCH_PATH . '/views/settings-page.php');
    }

    /**
     * Register and enqueue frontend scripts and styles.
     */
    public function register_scripts(){
        $doosearchas_search_settings = new DooSearchas_Search_Settings_Data();
        // Enqueue lz-string.min.js (minified version of lz-string.js)
        // Full readable version included at: /assets/js/libs/lz-string.js
        wp_register_script('lz-string',DOOSEARCHAS_SEARCH_URL . 'assets/js/libs/lz-string.min.js',[],DOOSEARCHAS_SEARCH_VERSION,true);

        // Enqueue frontend.min.js (minified version of frontend.js)
        // Full readable version included at: /assets/js/frontend.js
        wp_register_script('doosearchas-frontend-js',DOOSEARCHAS_SEARCH_URL . 'assets/js/frontend.min.js',['jquery', 'lz-string'],DOOSEARCHAS_SEARCH_VERSION,true);

        // Enqueue frontend.min.css (minified version of frontend.css)
        // Full readable version included at: /assets/css/frontend.css
        wp_enqueue_style('doosearchas-frontend-css',DOOSEARCHAS_SEARCH_URL . 'assets/css/frontend.min.css', array(), DOOSEARCHAS_SEARCH_VERSION, 'all');
        $doosearchas_strings = array(
            'view_cart_text' => esc_html__('View Cart', 'doosearch-ajax-search-for-woo'),
            'add_to_cart_text' => esc_html__('Add to cart', 'doosearch-ajax-search-for-woo'),
            'more'  => esc_html__('text', 'doosearch-ajax-search-for-woo'),
            // Add more if needed
        );
        wp_localize_script('doosearchas-frontend-js', 'doosearchasLocalizeFrontent', array(
            'root_url' => get_site_url(),
            'ajax_url' => admin_url('admin-ajax.php'),
            'settings_data' => $doosearchas_search_settings->get_settings_json(),
            'nonce'    => wp_create_nonce('doosearchas_search_nonce'),
            'cart_url' => wc_get_cart_url(),
            'text_domain' =>$doosearchas_strings,
            'icons_url'   => plugin_dir_url( __FILE__ ) . 'assets/icons/',
        ));
        wp_enqueue_style('doosearchas-fontawesome-css',DOOSEARCHAS_SEARCH_URL . 'assets/fontawesome/css/all.min.css',array(),'5.15.4');
        $product_count = wp_count_posts( 'product' )->publish;
        if ( $product_count > 0 ) {
            // Enqueue doosearch-slider.min.js (minified version of doosearch-slider.js)
            // Full readable version included at: /assets/js/doosearch-slider.js
            wp_enqueue_script('doosearchas-frontend-slider-script-js',DOOSEARCHAS_SEARCH_URL . 'assets/js/doosearch-slider.min.js',['jquery'],DOOSEARCHAS_SEARCH_VERSION,true);
            // Enqueue doosearch-slider.min.css (minified version of doosearch-slider.css)
            // Full readable version included at: /assets/css/doosearch-slider.css
            wp_enqueue_style('doosearchas-frontend-slider-style-css',DOOSEARCHAS_SEARCH_URL . 'assets/css/doosearch-slider.min.css', array(), DOOSEARCHAS_SEARCH_VERSION  , 'all');
        }
    }

    /**
     * Register and enqueue admin/backend scripts and styles.
     */
    public function register_admin_scripts(){
        // Enqueue backend.min.css (minified version of backend.css)
        // Full readable version included at: /assets/css/backend.css
        wp_enqueue_style('doosearchas-backend-css', DOOSEARCHAS_SEARCH_URL . 'assets/css/backend.min.css',array(), DOOSEARCHAS_SEARCH_VERSION  , 'all');
        // Enqueue backend.min.js (minified version of backend.js)
        // Full readable version included at: /assets/js/backend.js
        wp_enqueue_script('doosearchas-backend-js', DOOSEARCHAS_SEARCH_URL . 'assets/js/backend.min.js', array('jquery'), DOOSEARCHAS_SEARCH_VERSION , true);

        wp_enqueue_style('doosearchas-fontawesome-css',DOOSEARCHAS_SEARCH_URL . 'assets/fontawesome/css/all.min.css',array(),'5.15.4');
    }
    public static function activate(){
        update_option('rewrite_rules', '');
    }
    public static function deactivate(){
        flush_rewrite_rules();
    }
}

// Initialize plugin if the class exists
if( class_exists('DooSearchas_Search')){
    $doosearchas_search = new DooSearchas_Search();
    register_activation_hook(__FILE__, array('DooSearchas_Search','activate'));
    register_deactivation_hook(__FILE__, array('DooSearchas_Search','deactivate'));
}

/**
 * Class to manage and prepare plugin settings data for frontend usage.
 */
class DooSearchas_Search_Settings_Data {
    private $options;
    private $filterOptions;
    private $productOptions;
    public function __construct() {
        // Load saved options or default to empty arrays
        $this->options = get_option('doosearchas_search_additional_options', []);
        $this->filterOptions = get_option('doosearchas_search_filter_options', []);
        $this->productOptions = get_option('doosearchas_search_product_options', []);
    }
    
    public function get_settings_json() {
        $data = [
            'featuresList' => [
                $this->get_display_features_list(),
                $this->get_limit_features(),
                $this->get_exclude_features_array(),
                $this->get_prioritized_features_array()
            ],
            'brands' => $this->get_exclude_brands_array(),
            'categories' => $this->get_exclude_categories_array(),
            'attributes' => $this->process_string($this->filterOptions['doosearchas_search_attribute_filter_exclude_db'] ?? ''),
            'suggestions' => [
                $this->get_suggestion_limit(),
                $this->get_suggestions_priority_array(),
                $this->get_suggestions_stopwords_array(),
            ],
            'description'=>[
                $this->get_display_description_value(),
                $this->get_description_length_value(),
            ],
            'searchField' => $this->get_search_field_value(),
        ];
        return json_encode($data);
    }

    // The following private methods provide specific setting values with sanitization and defaults.
    private function get_suggestion_limit() {
        return isset($this->options['doosearchas_search_suggestion_list_limit_db']) 
            ? intval($this->options['doosearchas_search_suggestion_list_limit_db']) 
            : 3;
    }
    private function get_suggestions_priority_array() {
        return $this->explode_and_trim($this->options['doosearchas_search_suggestions_priority_db'] ?? '');
    }
    private function get_suggestions_stopwords_array() {
        return $this->explode_and_trim($this->options['doosearchas_search_suggestions_stopwords_db'] ?? '');
    }
    private function get_search_field_value() {
        return sanitize_text_field($this->filterOptions['doosearchas_search_s_field_db'] ?? 'title');
    }
    private function get_exclude_brands_array() {
        return $this->explode_and_trim($this->filterOptions['doosearchas_search_brand_filter_exclude_db'] ?? '');
    }
    private function get_exclude_categories_array() {
        return $this->explode_and_trim($this->filterOptions['doosearchas_search_category_filter_exclude_db'] ?? '');
    }
    private function get_display_description_value() {
        return sanitize_text_field($this->productOptions['doosearchas_search_disply_description_db'] ?? 'description');
    }
    private function get_description_length_value() {
    return isset($this->productOptions['doosearchas_search_description_length_db'])
        ? max(30, min(150, intval($this->productOptions['doosearchas_search_description_length_db'])))
        : 50;
    }
    private function get_display_features_list() {
        return !empty($this->productOptions['doosearchas_search_features_list_display_db']) && $this->productOptions['doosearchas_search_features_list_display_db'] == 1 
            ? 'on' 
            : 'off';
    }
    private function get_limit_features() {
        return isset($this->productOptions['doosearchas_search_features_list_limit_db']) 
            ? intval($this->productOptions['doosearchas_search_features_list_limit_db']) 
            : 3;
    }
    private function get_exclude_features_array() {
        return $this->explode_and_trim($this->productOptions['doosearchas_search_features_list_exclude_db'] ?? '');
    }
    private function get_prioritized_features_array() {
        return $this->explode_and_trim($this->productOptions['doosearchas_search_features_list_prioritized_db'] ?? '');
    }

    /**
     * Helper function to split a pipe-separated string and trim each element.
     */
    private function explode_and_trim($input) {
        return array_filter(array_map('trim', explode('|', $input)));
    }

    /**
     * Process complex attribute filter exclusion string into structured array.
     */
    private function process_string($input) {
        $parts = explode('|', $input);
        $result = [];
        foreach ($parts as $part) {
            $part = trim($part);
            if (strpos($part, '~') !== false) {
                $subParts = array_map('trim', explode('~', $part));
                $key = array_shift($subParts);
                if ($key && !empty($subParts)) {
                    $result[] = [$key => $subParts];
                }
            } else if (!empty($part)) {
                $result[] = $part;
            }
        }
        return $result;
    }
}

/**
 * Add quick access link on plugin page.
 */
function doosearchas_plugin_settings_page( $links ) {
    $setup_link = '<a href="admin.php?page=doosearchas_search_menu_slug">' . __( 'View Settings', 'doosearch-ajax-search-for-woo' ) . '</a>';
    $links[]    = $setup_link;
    return $links;
}
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'doosearchas_plugin_settings_page' ); 