/**
 * useSmartSuggestions Hook
 *
 * AI-enhanced query suggestions with intent understanding
 * Provides context-aware suggestions based on user behavior and query patterns
 */
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { useSearchContext } from '../components/SearchProvider';
/**
 * Pattern-based intent detection (client-side fallback)
 */
function detectIntent(query) {
    const patterns = [
        { pattern: /^(buy|purchase|order|get)\s+/i, intent: 'purchase' },
        { pattern: /^(find|search|looking for|where)\s+/i, intent: 'search' },
        { pattern: /^(compare|vs|versus)\s+/i, intent: 'compare' },
        { pattern: /^(how (to|do)|what is|why)\s+/i, intent: 'informational' },
        { pattern: /under\s*\$?\d+|less than\s*\$?\d+|cheap|affordable/i, intent: 'price_sensitive' },
        { pattern: /best|top|recommended|popular/i, intent: 'recommendation' },
        { pattern: /\d+\s*(gb|tb|inch|cm|mm|kg|lb)/i, intent: 'specification' },
        { pattern: /(red|blue|green|black|white|pink|purple|yellow)\s+/i, intent: 'color_preference' },
        { pattern: /(size|small|medium|large|xl|xxl)\s+/i, intent: 'size_preference' },
    ];
    for (const { pattern, intent } of patterns) {
        if (pattern.test(query)) {
            return { intent, confidence: 0.8 };
        }
    }
    return null;
}
/**
 * Simple Levenshtein distance for spell checking
 */
function levenshteinDistance(a, b) {
    const matrix = [];
    for (let i = 0; i <= b.length; i++) {
        matrix[i] = [i];
    }
    for (let j = 0; j <= a.length; j++) {
        matrix[0][j] = j;
    }
    for (let i = 1; i <= b.length; i++) {
        for (let j = 1; j <= a.length; j++) {
            if (b.charAt(i - 1) === a.charAt(j - 1)) {
                matrix[i][j] = matrix[i - 1][j - 1];
            }
            else {
                matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1);
            }
        }
    }
    return matrix[b.length][a.length];
}
/**
 * Find potential corrections from a dictionary
 */
function findCorrections(query, dictionary, maxDistance = 2) {
    const words = query.toLowerCase().split(/\s+/);
    const corrections = [];
    words.forEach(word => {
        if (word.length < 3)
            return;
        dictionary.forEach(dictWord => {
            const distance = levenshteinDistance(word, dictWord.toLowerCase());
            if (distance > 0 && distance <= maxDistance && distance < word.length / 2) {
                const corrected = query.replace(new RegExp(word, 'gi'), dictWord);
                if (!corrections.includes(corrected)) {
                    corrections.push(corrected);
                }
            }
        });
    });
    return corrections.slice(0, 3);
}
/**
 * Expand query with synonyms and related terms
 */
function expandQuery(query) {
    const expansions = {
        phone: ['smartphone', 'mobile', 'cellphone'],
        laptop: ['notebook', 'computer', 'pc'],
        tv: ['television', 'smart tv', 'monitor'],
        headphones: ['earbuds', 'earphones', 'headset'],
        shoes: ['footwear', 'sneakers', 'boots'],
        shirt: ['top', 'blouse', 'tee'],
        pants: ['trousers', 'jeans', 'bottoms'],
        cheap: ['affordable', 'budget', 'inexpensive'],
        best: ['top-rated', 'popular', 'recommended'],
    };
    const queryLower = query.toLowerCase();
    const expanded = [];
    Object.entries(expansions).forEach(([term, synonyms]) => {
        if (queryLower.includes(term)) {
            synonyms.forEach(syn => {
                const exp = query.replace(new RegExp(term, 'gi'), syn);
                if (!expanded.includes(exp)) {
                    expanded.push(exp);
                }
            });
        }
    });
    return expanded.slice(0, 3);
}
export function useSmartSuggestions(query, options = {}) {
    const { minQueryLength = 1, maxSuggestions = 10, debounceMs = 200, enableSpellCorrection = true, enableQueryExpansion = true, enableIntentDetection = true, includeTrending = true, userContext, } = options;
    const { stateManager } = useSearchContext();
    const [suggestions, setSuggestions] = useState([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);
    const [detectedIntent, setDetectedIntent] = useState(null);
    const [corrections, setCorrections] = useState([]);
    const [expansions, setExpansions] = useState([]);
    const debounceTimer = useRef(null);
    // Sample dictionary for spell checking (in production, this would come from the API)
    const dictionary = useMemo(() => [
        'phone', 'laptop', 'computer', 'tablet', 'headphones', 'camera',
        'television', 'speaker', 'watch', 'keyboard', 'mouse', 'monitor',
        'shirt', 'pants', 'shoes', 'jacket', 'dress', 'skirt', 'sweater',
        'electronics', 'clothing', 'accessories', 'furniture', 'appliances',
    ], []);
    const processQuery = useCallback(async (q) => {
        const results = [];
        // Detect intent
        if (enableIntentDetection) {
            const intent = detectIntent(q);
            if (intent) {
                setDetectedIntent(intent.intent);
            }
            else {
                setDetectedIntent(null);
            }
        }
        // Find spell corrections
        if (enableSpellCorrection && q.length >= 3) {
            const correctionResults = findCorrections(q, dictionary);
            setCorrections(correctionResults);
            correctionResults.forEach(correction => {
                results.push({
                    text: correction,
                    type: 'correction',
                    confidence: 0.9,
                    metadata: { correctedFrom: q },
                });
            });
        }
        // Expand query
        if (enableQueryExpansion) {
            const expansionResults = expandQuery(q);
            setExpansions(expansionResults);
            expansionResults.forEach(exp => {
                results.push({
                    text: exp,
                    type: 'expansion',
                    confidence: 0.7,
                    metadata: { expandedTo: [exp] },
                });
            });
        }
        // Add the original query as a suggestion
        results.unshift({
            text: q,
            type: 'query',
            confidence: 1.0,
        });
        // Add related suggestions based on context
        if (userContext?.recentSearches) {
            userContext.recentSearches
                .filter(s => s.toLowerCase().includes(q.toLowerCase()) && s !== q)
                .slice(0, 2)
                .forEach(s => {
                results.push({
                    text: s,
                    type: 'related',
                    confidence: 0.6,
                });
            });
        }
        return results.slice(0, maxSuggestions);
    }, [dictionary, enableIntentDetection, enableSpellCorrection, enableQueryExpansion, maxSuggestions, userContext]);
    const getSuggestions = useCallback(async (q) => {
        if (q.length < minQueryLength) {
            return [];
        }
        return processQuery(q);
    }, [minQueryLength, processQuery]);
    // Debounced effect
    useEffect(() => {
        if (debounceTimer.current) {
            clearTimeout(debounceTimer.current);
        }
        if (query.length < minQueryLength) {
            setSuggestions([]);
            setCorrections([]);
            setExpansions([]);
            setDetectedIntent(null);
            return;
        }
        setLoading(true);
        debounceTimer.current = setTimeout(async () => {
            try {
                const results = await processQuery(query);
                setSuggestions(results);
                setError(null);
            }
            catch (err) {
                setError(err instanceof Error ? err : new Error(String(err)));
                setSuggestions([]);
            }
            finally {
                setLoading(false);
            }
        }, debounceMs);
        return () => {
            if (debounceTimer.current) {
                clearTimeout(debounceTimer.current);
            }
        };
    }, [query, minQueryLength, debounceMs, processQuery]);
    const clear = useCallback(() => {
        setSuggestions([]);
        setCorrections([]);
        setExpansions([]);
        setDetectedIntent(null);
        setError(null);
    }, []);
    return {
        suggestions,
        loading,
        error,
        detectedIntent,
        corrections,
        expansions,
        getSuggestions,
        clear,
    };
}
