import BaseComponent from "../BaseComponent";
import EventBus from "../../Events/EventBus";
import Events from "../../Events/Events";
import ProductCard from "./ProductCard";
import Storage from "../../Utils/Storage";

class ProductList {
    _$container = null;
    _$wrapper = null;
    _products = [];
    _allProducts = [];
    _currentOffset = 0;
    _initialLoadCount = 12;
    _loadMoreCount = 12;
    _showTimeout = null;
    _showCountTimeout = null;
    _showLoadMoreTimeout = null;

    init() {
        this._$container = jQuery('.fusecommerce-products');
        this._$wrapper = jQuery('.fusecommerce-products-wrapper');

        if (!this._$container.length || !this._$wrapper.length) {
            console.warn('Product container or wrapper not found');
            return;
        }

        // Read configuration from data attributes
        this._initialLoadCount = parseInt(this._$wrapper.data('initial-load')) || 12;
        this._loadMoreCount = parseInt(this._$wrapper.data('load-more-count')) || 12;

        this._listenToEvents();
        this._initLoadMoreButton();
    }

    _initLoadMoreButton() {
        const $loadMoreBtn = jQuery('.fuse-load-more');

        if ($loadMoreBtn.length) {
            $loadMoreBtn.on('click', (e) => {
                e.preventDefault();
                this._handleLoadMore();
            });
        }
    }

    _listenToEvents() {
        const eventBus = EventBus.getInstance();

        // Listen for products loaded
        eventBus.registerDynamicEvent({
            key: Events.PRODUCTS_LOADED,
            callback: (payload) => this._handleProductsLoaded(payload)
        });

        // Listen for filtered products
        eventBus.registerDynamicEvent({
            key: Events.PRODUCTS_FILTERED,
            callback: (payload) => this._handleProductsFiltered(payload)
        });

        // Listen for load errors
        eventBus.registerDynamicEvent({
            key: Events.PRODUCTS_LOAD_ERROR,
            callback: (payload) => this._handleLoadError(payload)
        });
    }

    _handleProductsLoaded(payload) {
        this._allProducts = payload?.products || [];
        this._currentOffset = this._initialLoadCount;

        // Render only initial batch
        const initialBatch = this._allProducts.slice(0, this._initialLoadCount);
        this._renderProducts(initialBatch, false);

        this._updateResultCount(this._allProducts.length);
        // this._updateLoadMoreButton();
        Storage.getInstance().setShowingProductsCount(this._allProducts.length);
    }

    _handleProductsFiltered(payload) {
        this._allProducts = payload?.products || [];
        this._currentOffset = this._initialLoadCount;

        // Render only initial batch
        const initialBatch = this._allProducts.slice(0, this._initialLoadCount);
        this._renderProducts(initialBatch, false);

        this._updateResultCount(payload?.totalCount || 0);
        // this._updateLoadMoreButton();
    }

    _handleLoadError(payload) {
        this._showErrorState(payload?.error);
    }

    _renderProducts(products, append = false) {
        jQuery('.product-count').empty();
        jQuery('.load-more-ui').addClass('hidden');
        try {
            clearTimeout(this._showTimeout);
        } catch (error) {
            console.warn(error);
        }

        // Only show loader when replacing (not appending)
        if (!append) {
            jQuery('.products-loading').removeClass('hidden');
            this._$container.html('');
        }

        this._showTimeout = setTimeout(() => {
            jQuery('.products-loading').addClass('hidden');

            if (!this._$container || !this._$container.length) {
                return;
            }

            if (!products || products.length === 0) {
                if (!append) {
                    this._showEmptyState();
                }
                return;
            }

            // Store products for variation selector initialization
            this._products = append
                ? [...this._products, ...products]
                : products;

            const productsHtml = products.map(product => ProductCard.render(product)).join('');

            if (append) {
                // Append new products to existing grid
                this._$container.append(productsHtml);
            } else {
                // Replace entire content
                this._$container.html(`${productsHtml}`);
            }

            this._updateLoadMoreButton();
            if (append) {
                // Scroll down 100px with jQuery easing
                jQuery('html, body').animate({
                    scrollTop: jQuery(window).scrollTop() + 150
                }, 400, 'swing');
            }
        }, Storage.getInstance().showingProductsDelay);
    }

    _handleLoadMore() {
        const $loadMoreUI = jQuery('.load-more-ui');
        $loadMoreUI.addClass('hidden');
        jQuery('.products-loading').removeClass('hidden');

        // Calculate next batch
        const nextOffset = this._currentOffset + this._loadMoreCount;
        const nextBatch = this._allProducts.slice(this._currentOffset, nextOffset);

        if (nextBatch.length === 0) {
            return; // No more products to load
        }

        // Update offset
        this._currentOffset = nextOffset;

        // Append products to DOM
        this._renderProducts(nextBatch, true);
    }

    _updateLoadMoreButton() {
        const $loadMoreUI = jQuery('.load-more-ui');

        if (!$loadMoreUI.length) {
            return;
        }

        // Show button if there are more products to load
        const hasMoreProducts = this._currentOffset < this._allProducts.length;

        if (hasMoreProducts) {
            $loadMoreUI.removeClass('hidden');
        } else {
            $loadMoreUI.addClass('hidden');
        }
    }

    _showEmptyState() {
        const labels = window.FuseCommerceSearch?.labels || {
            product_list_empty: 'No products found matching your filters.'
        };

        if (this._$container && this._$container.length) {
            this._$container.html(`
                <div class="product-list-empty">
                    <p>${labels.product_list_empty}</p>
                </div>
            `);
        }
    }

    _showErrorState(error) {
        const labels = window.FuseCommerceSearch?.labels || {
            product_list_error: 'Error loading products. Please try again later.'
        };

        if (this._$container && this._$container.length) {
            this._$container.html(`
                <div class="product-list-error">
                    <p>${labels.product_list_error}</p>
                    ${error ? `<small>${error.message || error}</small>` : ''}
                </div>
            `);
        }
    }

    _updateResultCount(count) {
        const labels = window.FuseCommerceSearch?.labels || {
            product_list_count_singular: 'product found',
            product_list_count_plural: 'products found'
        };

        try {
            clearTimeout(this._showCountTimeout);
        } catch (error) {
            console.warn(error);
        }
        this._showCountTimeout = setTimeout(() => {
            const $countContainer = jQuery('.product-count');
            if ($countContainer.length) {
                $countContainer.text(`${count} ${count !== 1 ? labels.product_list_count_plural : labels.product_list_count_singular}`);
            }
        }, Storage.getInstance().showingProductsDelay)
    }
}

export default ProductList;
