<?php
/**
 * Queryra Search Integration
 *
 * Overrides WordPress default search with Queryra AI semantic search
 */

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

class Queryra_Search_Integration {

    /**
     * API client
     */
    private $api;

    /**
     * Cache duration in seconds
     */
    private $cache_duration;

    /**
     * Constructor
     */
    public function __construct() {
        $this->api = new Queryra_API();

        // Get cache duration from settings (default: 1 day)
        $this->cache_duration = intval(get_option('queryra_cache_duration', 86400));

        // Override WordPress search with Queryra
        add_action('pre_get_posts', array($this, 'override_search'));
    }

    /**
     * Override WordPress search with Queryra AI
     *
     * Simple Strategy:
     * 1. Pre-flight checks (avoid unnecessary API calls)
     * 2. Fetch all matching IDs from Queryra API (limit=999)
     * 3. Set post__in with IDs, let WordPress/WooCommerce handle pagination
     * 4. Fallback: If any check fails or API down → WordPress MySQL search
     *
     * @param WP_Query $query WordPress query object
     */
    public function override_search($query) {
        // Only override frontend main search query
        if (is_admin() || !$query->is_main_query() || !$query->is_search()) {
            return;
        }

        // Skip during cron - prevents cache warmers from burning API credits
        if (wp_doing_cron()) {
            return;
        }

        $search_term = $query->get('s');

        // Check if AI search is enabled in settings
        $ai_enabled = get_option('queryra_ai_search', '0');
        if ($ai_enabled !== '1') {
            return; // AI search disabled, use WordPress default
        }

        // Empty search term - let WordPress handle
        if (empty($search_term)) {
            return;
        }

        // Get cached stats and status from WordPress DB (saved by admin page)
        $stats = get_option('queryra_cached_stats');
        $status = get_option('queryra_cached_status');

        // Pre-flight check: No synced records?
        if ($stats && isset($stats['synced_records']) && $stats['synced_records'] == 0) {
            return; // No records in Queryra at all
        }

        // Cache key (unique per search term)
        $cache_key = 'queryra_search_' . md5($search_term);

        // Check cache FIRST - even if stale, it's better than SQL
        $cached_ids = get_transient($cache_key);

        // SMART STRATEGY for FREE plan:
        // If window closed BUT we have cache → use cache (even if stale)
        // Better to show AI results from cache than fallback to SQL
        if ($stats && isset($stats['plan']) && $stats['plan'] === 'free' && $status) {
            $window_closed = false;

            // Check if window is closed
            if (isset($status['available']) && $status['available'] === false) {
                $window_closed = true;
            } elseif (isset($status['minutes_until_open']) && $status['minutes_until_open'] > 2) {
                $window_closed = true;
            }

            // If window closed BUT we have cache → use it!
            if ($window_closed && $cached_ids && count($cached_ids) > 0) {
                // Don't fetch from API, just use cache below
            } elseif ($window_closed && !$cached_ids) {
                // No cache available, must fallback to SQL
                return;
            }
        }

        // If no cache, fetch from API
        if (!$cached_ids) {
            // Check if we should skip API call (FREE plan window closed)
            $skip_api = false;

            if ($stats && isset($stats['plan']) && $stats['plan'] === 'free' && $status) {
                if ((isset($status['available']) && $status['available'] === false) ||
                    (isset($status['minutes_until_open']) && $status['minutes_until_open'] > 2)) {
                    $skip_api = true;
                }
            }

            if ($skip_api) {
                return; // Fallback to WordPress search
            }

            // Fetch all matching results from API (API filters by relevance threshold)
            $results = $this->api->search($search_term, 999);

            // If API fails or returns error, fallback to WordPress search
            if (is_wp_error($results)) {
                $error_msg = $results->get_error_message();
                $error_data = $results->get_error_data();

                // Special handling for FREE plan window closed
                if (strpos($error_msg, 'FREE plan') !== false || strpos($error_msg, 'window') !== false) {
                    if ($error_data && isset($error_data['data']['errors']['api_error'][0])) {
                        $error_info = $error_data['data']['errors']['api_error'][0];

                        $updated_status = array(
                            'available' => false,
                            'plan' => 'free',
                            'minutes_left' => 0,
                            'message' => isset($error_info['message']) ? $error_info['message'] : 'Search window closed',
                            'next_available_at' => isset($error_info['next_available_at']) ? $error_info['next_available_at'] : null,
                            'minutes_until_open' => isset($error_info['minutes_until_open']) ? $error_info['minutes_until_open'] : null
                        );

                        update_option('queryra_cached_status', $updated_status);
                    }
                }

                return; // Let WordPress handle search normally
            }

            if (empty($results['results'])) {
                return; // Let WordPress handle search normally
            }

            // Extract post IDs from results
            // Convert "wp-123" → 123, filter out non-WordPress records
            $all_ids = array();
            foreach ($results['results'] as $result) {
                if (strpos($result['id'], 'wp-') === 0) {
                    $id = (int) str_replace('wp-', '', $result['id']);
                    if ($id > 0) {
                        $all_ids[] = $id;
                    }
                }
            }

            // Track first search (only once per installation)
            if (!get_option('queryra_first_search_tracked')) {
                Queryra_Analytics::track('first_search');
                update_option('queryra_first_search_tracked', true);
            }

            // Cache the results based on settings
            if ($this->cache_duration === -1) {
                // Forever = 10 years
                set_transient($cache_key, $all_ids, YEAR_IN_SECONDS * 10);
            } elseif ($this->cache_duration > 0) {
                // Normal cache duration
                set_transient($cache_key, $all_ids, $this->cache_duration);
            }
            // cache_duration === 0 means disabled, don't cache

            $cached_ids = $all_ids;
        }

        // If no results from API, show empty
        if (empty($cached_ids)) {
            $query->set('post__in', array(0));
            return;
        }

        // === SIMPLE APPROACH ===
        // Just set the IDs and let WordPress/WooCommerce handle everything else
        // (pagination, posts_per_page, sorting display)

        // Flag that we used AI search (for attribution footer)
        $query->set('queryra_ai_used', true);

        // Tell WordPress: only show these posts, in this exact order
        $query->set('post__in', $cached_ids);
        $query->set('orderby', 'post__in');

        // Don't filter by search term anymore (we have exact IDs)
        // But keep 's' parameter for theme to display "Search results for: X"
        $query->set('s', '');

        // Store original search term for themes that need it
        $query->set('queryra_search_term', $search_term);
    }
}
