/**
 * SiteStaffr Knowledge Search — client-side search module.
 *
 * Used by voice chat (DataChannel function call relay).
 * Sends query to WordPress AJAX, which embeds via middleware
 * and does local vector search, returning matching chunks.
 *
 * @since 1.8.0
 */
var SiteStaffrKnowledgeSearch = (function() {
    'use strict';

    var TIMEOUT_MS = 8000;

    /**
     * Get the knowledge search nonce from whichever widget data is available.
     */
    function getNonce() {
        return (window.sitestaffr_widget_data && window.sitestaffr_widget_data.knowledge_search_nonce)
            || (window.sitestaffr_button_data && window.sitestaffr_button_data.knowledge_search_nonce)
            || '';
    }

    /**
     * Get the AJAX URL from whichever widget data is available.
     */
    function getAjaxUrl() {
        return (window.sitestaffr_widget_data && window.sitestaffr_widget_data.ajax_url)
            || (window.sitestaffr_button_data && window.sitestaffr_button_data.ajax_url)
            || '';
    }

    /**
     * Search the knowledge base.
     *
     * @param {string} query      - The search query from the AI function call.
     * @param {number} maxResults - Maximum chunks to return (voice: 3, text: 5).
     * @param {number} postId     - Optional WordPress post ID to scope results to a single page.
     * @returns {Promise<object>}   Resolves with { success, chunks[] } or { success: false, error }.
     */
    function search(query, maxResults, postId) {
        var ajaxUrl = getAjaxUrl();
        var nonce = getNonce();

        if (!ajaxUrl) {
            return Promise.resolve({ success: false, error: 'No AJAX URL' });
        }
        if (!nonce) {
            return Promise.resolve({ success: false, error: 'No nonce' });
        }

        return new Promise(function(resolve) {
            var formData = new FormData();
            formData.append('action', 'sitestaffr_knowledge_search');
            formData.append('nonce', nonce);
            formData.append('query', query);
            formData.append('max_results', maxResults || 3);
            if (postId) {
                formData.append('post_id', postId);
            }

            var controller = new AbortController();
            var timeoutId = setTimeout(function() {
                controller.abort();
            }, TIMEOUT_MS);

            fetch(ajaxUrl, {
                method: 'POST',
                body: formData,
                signal: controller.signal,
            })
            .then(function(response) {
                clearTimeout(timeoutId);
                return response.json();
            })
            .then(function(data) {
                var chunks = (data.success && data.data && data.data.chunks) ? data.data.chunks : [];
                if (data.success && data.data && data.data.chunks) {
                    resolve({ success: true, chunks: data.data.chunks });
                } else if (data.success === false) {
                    // Server returned an explicit error (e.g. embed failed, nonce invalid).
                    var errMsg = (data.data && data.data.message) ? data.data.message : 'Server error';
                    resolve({ success: false, error: errMsg });
                } else {
                    resolve({ success: true, chunks: [] });
                }
            })
            .catch(function(err) {
                clearTimeout(timeoutId);
                resolve({ success: false, error: 'Search unavailable' });
            });
        });
    }

    /**
     * Format search results as a string for the AI function_call_output.
     *
     * @param {object} result - Result from search().
     * @returns {string} JSON string for DataChannel function_call_output.
     */
    function formatForFunctionOutput(result) {
        if (!result.success) {
            return JSON.stringify({ error: result.error || 'Search unavailable' });
        }
        if (!result.chunks || result.chunks.length === 0) {
            return JSON.stringify({ results: [] });
        }
        var formatted = result.chunks.map(function(chunk) {
            return {
                title: chunk.post_title || chunk.title || '',
                content: chunk.chunk_text || chunk.content || '',
            };
        });
        return JSON.stringify({ results: formatted });
    }

    return {
        search: search,
        formatForFunctionOutput: formatForFunctionOutput,
    };
})();
