class FuseSearch {
    _fuseInstance = null;
    _products = [];

    constructor(products, options = {}) {
        this._products = products || [];

        // Default keys configuration
        const defaultKeys = [
            { name: 'name', weight: 2 },
            { name: 'short_description', weight: 1 }
        ];

        // If custom weights are provided, convert them to Fuse.js keys format
        let keys = defaultKeys;
        if (options.weights && typeof options.weights === 'object') {
            keys = Object.entries(options.weights).map(([name, weight]) => ({
                name,
                weight: parseFloat(weight) || 1
            }));
        }

        const defaultOptions = {
            keys: keys,
            threshold: 0.3,
            includeScore: true,
            useExtendedSearch: true,
            ignoreLocation: true
        };

        // Merge options, but preserve the keys we just built
        const fuseOptions = { ...defaultOptions, ...options };
        // Ensure our keys take precedence
        fuseOptions.keys = keys;

        if (window.Fuse) {
            this._fuseInstance = new window.Fuse(this._products, fuseOptions);
        } else {
            console.error('Fuse.js library not loaded');
        }
    }

    search(query) {
        if (!this._fuseInstance) {
            return this._products;
        }

        if (!query || query.trim() === '') {
            return this._products;
        }

        const results = this._fuseInstance.search(query);
        return results.map(result => result.item);
    }

    filterByCategories(categoryIds) {
        if (!categoryIds || categoryIds.length === 0) {
            return this._products;
        }

        return this._products.filter(product => {
            if (!product.categories || !Array.isArray(product.categories)) {
                return false;
            }
            return product.categories.some(catId => categoryIds.includes(catId));
        });
    }

    filterByAttributes(attributes) {
        if (!attributes || Object.keys(attributes).length === 0) {
            return this._products;
        }

        return this._products.filter(product => {
            if (!product.attributes || !Array.isArray(product.attributes)) {
                return false;
            }

            // Check if product matches all selected attribute filters
            return Object.entries(attributes).every(([attributeName, selectedValues]) => {
                if (!Array.isArray(selectedValues) || selectedValues.length === 0) {
                    return true;
                }

                // Find the attribute in product's attributes array
                const productAttribute = product.attributes.find(attr => attr.name === attributeName);

                if (!productAttribute || !productAttribute.options) {
                    return false;
                }

                // Check if any of the product's options match the selected values
                return productAttribute.options.some(option =>
                    selectedValues.includes(option.toLowerCase())
                );
            });
        });
    }

    complexFilter(filters = {}) {
        let results = this._products;

        // Apply text search first
        if (filters.query && filters.query.trim() !== '') {
            results = this.search(filters.query);
        }

        // Apply category filter
        if (filters.categories && filters.categories.length > 0) {
            results = results.filter(product => {
                if (!product.categories || !Array.isArray(product.categories)) {
                    return false;
                }
                return product.categories.some(catId => filters.categories.includes(catId));
            });
        }

        // Apply tag filter
        if (filters.tags && filters.tags.length > 0) {
            results = results.filter(product => {
                if (!product.tags || !Array.isArray(product.tags)) {
                    return false;
                }
                return product.tags.some(tagId => filters.tags.includes(tagId));
            });
        }

        // Apply attribute filters
        if (filters.attributes && Object.keys(filters.attributes).length > 0) {
            results = results.filter(product => {
                if (!product.attributes || !Array.isArray(product.attributes)) {
                    return false;
                }

                // Check if product matches all selected attribute filters
                return Object.entries(filters.attributes).every(([attributeName, selectedValues]) => {
                    if (!Array.isArray(selectedValues) || selectedValues.length === 0) {
                        return true;
                    }

                    // Find the attribute in product's attributes array
                    const productAttribute = product.attributes.find(attr => attr.name === attributeName);

                    if (!productAttribute || !productAttribute.options) {
                        return false;
                    }

                    // Check if any of the product's options match the selected values
                    return productAttribute.options.some(option =>
                        selectedValues.includes(option.toLowerCase())
                    );
                });
            });
        }

        // Apply price range filter
        if (filters.priceRange) {
            const { min, max } = filters.priceRange;
            results = results.filter(product => {
                // For variable products with price_range, check if range overlaps with filter
                if (product.price_range && product.price_range.min !== null && product.price_range.max !== null) {
                    const productMin = parseFloat(product.price_range.min);
                    const productMax = parseFloat(product.price_range.max);

                    // Check if product's price range overlaps with filter range
                    if (min !== undefined && productMax < min) return false;
                    if (max !== undefined && productMin > max) return false;
                    return true;
                } else {
                    // For simple products, check single price
                    const price = parseFloat(product.price);
                    if (min !== undefined && price < min) return false;
                    if (max !== undefined && price > max) return false;
                    return true;
                }
            });
        }

        return results;
    }

    getAllProducts() {
        return this._products;
    }

    updateProducts(products) {
        this._products = products || [];
        if (this._fuseInstance && window.Fuse) {
            this._fuseInstance.setCollection(this._products);
        }
    }
}

export default FuseSearch;
