/**
 * Product Display Handler - Unified for Grid, List, and Table
 * Handles client-side filtering and pagination for all product display widgets
 */
(function($) {
    'use strict';

    // Store active filters and original pagination
    window.ggmDisplayState = window.ggmDisplayState || {};

    function initProductDisplay(containerClass, itemClass) {

        var containerSelector = '.' + containerClass;
        var $container = $(containerSelector);


        if ($container.length === 0) {
            return;
        }

        var perPage = parseInt($container.data('products-per-page')) || 12;
        var $items = $container.find('.' + itemClass);

        var widgetType = containerClass.replace('ggmc-products-', '').replace('ggmc-product-', '');

        // Initialize state for this widget type
        if (!window.ggmDisplayState[widgetType]) {
            window.ggmDisplayState[widgetType] = {
                filterActive: false,
                filteredProductIds: [],
                originalPagination: null,
                containerClass: containerClass,
                itemClass: itemClass
            };
        }

        // Store original pagination HTML on page load
        if (!window.ggmDisplayState[widgetType].originalPagination) {
            var $pagination = $container.parent().find('.ggmc-pagination');
            if ($pagination.length > 0 && $pagination.html().trim() !== '') {
                window.ggmDisplayState[widgetType].originalPagination = $pagination.html();
            }
        }

        // Listen for filter changes
        $(document).on('ggm_commerce_products_filtered', function(event, filterData) {
            var ajaxIds = filterData.product_ids || [];

            // Intersect with products actually in the DOM so that on
            // category/tag pages (where only a subset is rendered) the
            // filter doesn't reference products that aren't on this page.
            var domIds = {};
            $container.find('.' + itemClass + '[data-product-id]').each(function() {
                domIds[$(this).attr('data-product-id')] = true;
            });
            var scopedIds = ajaxIds.filter(function(id) {
                return domIds[id] || domIds[String(id)];
            });

            // Store the filtered state
            window.ggmDisplayState[widgetType].filterActive = true;
            window.ggmDisplayState[widgetType].filteredProductIds = scopedIds;

            // Show ALL filtered products (reset to page 1)
            showFilteredProducts(containerClass, itemClass, scopedIds, 1);
        });

        // Listen for filter reset
        $(document).on('click', '.filter-reset-btn', function() {

            // Clear filter state
            window.ggmDisplayState[widgetType].filterActive = false;
            window.ggmDisplayState[widgetType].filteredProductIds = [];

            // Show only first page of products
            var $cont = $(containerSelector);
            var perPage = parseInt($cont.data('products-per-page')) || 12;
            var $items = $cont.find('.' + itemClass);

            $items.removeClass('filtered-out');
            $items.hide();
            $items.slice(0, perPage).show();

            // Restore or regenerate pagination
            var $pag = $cont.parent().find('.ggmc-pagination');
            var totalProducts = $items.length;
            var totalPages = Math.ceil(totalProducts / perPage);


            if (totalPages > 1) {
                if (window.ggmDisplayState[widgetType].originalPagination) {
                    $pag.html(window.ggmDisplayState[widgetType].originalPagination).show();
                } else {
                    updateNonFilteredPagination(containerClass, 1, totalPages);
                }
            } else {
                $pag.hide();
            }

            // Hide empty message
            $('.no-products-message').remove();
        });

        // Pagination click handling is now done globally below, outside this function

        // Hide products beyond first page initially and render pagination
        $items.slice(perPage).hide();

        // Render initial pagination
        var totalItems = $items.length;
        var totalPages = Math.ceil(totalItems / perPage);

        // Check if pagination div exists
        var $paginationCheck = $container.parent().find('.ggmc-pagination');

        if (totalPages > 1) {
            updateNonFilteredPagination(containerClass, 1, totalPages);
        } else {
        }
    }

    /**
     * Show filtered products with pagination
     */
    function showFilteredProducts(containerClass, itemClass, productIds, page) {
        page = page || 1;
        var $container = $('.' + containerClass);
        var productsPerPage = parseInt($container.data('products-per-page')) || 12;
        var totalProducts = productIds.length;
        var totalPages = Math.ceil(totalProducts / productsPerPage);


        // Calculate which products to show for this page
        var startIndex = (page - 1) * productsPerPage;
        var endIndex = startIndex + productsPerPage;
        var pageProductIds = productIds.slice(startIndex, endIndex);

        // Hide ALL products first
        var $items = $container.find('.' + itemClass);
        $items.hide().addClass('filtered-out');

        // Show only products for this page
        if (pageProductIds.length > 0) {
            var foundCount = 0;
            pageProductIds.forEach(function(id) {
                var $item = $container.find('.' + itemClass + '[data-product-id="' + id + '"]');
                if ($item.length > 0) {
                    $item.show().removeClass('filtered-out');
                    foundCount++;
                } else {
                }
            });
            $('.no-products-message').remove();
        } else {
            // No products found
            if ($('.no-products-message').length === 0) {
                $container.append('<div class="no-products-message" style="text-align: center; padding: 40px; color: #666;">No products match your filters.</div>');
            }
        }

        // Update pagination for filtered results
        updateFilteredPagination(containerClass, itemClass, page, totalPages, productIds, productsPerPage);
    }

    /**
     * Update pagination for filtered results
     */
    function updateFilteredPagination(containerClass, itemClass, currentPage, totalPages, productIds, perPage) {
        // Find pagination using the same method as non-filtered
        var paginationSelector = '.' + containerClass + '-container .ggmc-pagination';
        var $pagination = $(paginationSelector);

        // Fallback to alternative selector if needed
        if ($pagination.length === 0) {
            var $container = $('.' + containerClass);
            $pagination = $container.parent().find('.ggmc-pagination');
        }

        if (totalPages <= 1) {
            $pagination.hide();
            return;
        }

        var paginationHTML = '<div class="pagination-wrapper">';

        // Check if show_prev_next is enabled
        var $container = $('.' + containerClass);
        var showPrevNext = $container.data('show-prev-next') !== 'no';

        // Previous button
        if (showPrevNext && currentPage > 1) {
            paginationHTML += '<a href="#" class="pagination-prev filtered-page" data-page="' + (currentPage - 1) + '">&laquo; Previous</a>';
        }

        // Page numbers
        var startPage = Math.max(1, currentPage - 2);
        var endPage = Math.min(totalPages, currentPage + 2);

        for (var i = startPage; i <= endPage; i++) {
            if (i === currentPage) {
                paginationHTML += '<span class="pagination-current">' + i + '</span>';
            } else {
                paginationHTML += '<a href="#" class="pagination-page filtered-page" data-page="' + i + '">' + i + '</a>';
            }
        }

        // Next button
        if (showPrevNext && currentPage < totalPages) {
            paginationHTML += '<a href="#" class="pagination-next filtered-page" data-page="' + (currentPage + 1) + '">Next &raquo;</a>';
        }

        paginationHTML += '</div>';

        $pagination.html(paginationHTML).show();

        // Handle filtered pagination clicks
        $pagination.find('.filtered-page').on('click', function(e) {
            e.preventDefault();
            var page = parseInt($(this).data('page'));
            showFilteredProducts(containerClass, itemClass, productIds, page);

            // Scroll to top
            var $scrollTarget = $('.' + containerClass).parent();
            if ($scrollTarget.length > 0) {
                $('html, body').animate({
                    scrollTop: $scrollTarget.offset().top - 100
                }, 300);
            }
        });
    }

    /**
     * Update pagination for non-filtered (initial) state
     */
    function updateNonFilteredPagination(containerClass, currentPage, totalPages) {
        // Try multiple ways to find the pagination
        var paginationSelector = '.' + containerClass + '-container .ggmc-pagination';
        var $pagination = $(paginationSelector);


        // Alternative: find via parent of container
        var $container = $('.' + containerClass);
        var $paginationAlt = $container.parent().find('.ggmc-pagination');

        // Use whichever works
        if ($pagination.length === 0 && $paginationAlt.length > 0) {
            $pagination = $paginationAlt;
        }

        if (totalPages <= 1) {
            $pagination.hide();
            return;
        }

        var paginationHTML = '<div class="pagination-wrapper">';

        // Check if show_prev_next is enabled
        var $container = $('.' + containerClass);
        var showPrevNext = $container.data('show-prev-next') !== 'no';

        // Previous button
        if (showPrevNext && currentPage > 1) {
            paginationHTML += '<a href="#" class="pagination-prev">&laquo; Previous</a>';
        }

        // Page numbers
        var startPage = Math.max(1, currentPage - 2);
        var endPage = Math.min(totalPages, currentPage + 2);

        for (var i = startPage; i <= endPage; i++) {
            if (i === currentPage) {
                paginationHTML += '<span class="pagination-current">' + i + '</span>';
            } else {
                paginationHTML += '<a href="#" class="pagination-page">' + i + '</a>';
            }
        }

        // Next button
        if (showPrevNext && currentPage < totalPages) {
            paginationHTML += '<a href="#" class="pagination-next">Next &raquo;</a>';
        }

        paginationHTML += '</div>';

        $pagination.html(paginationHTML).show();
    }

    // Global pagination click handler (works for all widget types)
    $(document).on('click', '.ggmc-pagination a:not(.filtered-page)', function(e) {
        e.preventDefault(); // ALWAYS prevent default first

        var $link = $(this);

        // Find which container this pagination belongs to
        var $paginationParent = $link.closest('.ggmc-pagination').parent();
        var $container = null;
        var containerClass = null;
        var itemClass = null;
        var widgetType = null;

        // Detect which widget type by finding the container
        if ($paginationParent.find('.ggmc-products-grid').length > 0) {
            $container = $paginationParent.find('.ggmc-products-grid');
            containerClass = 'ggmc-products-grid';
            itemClass = 'product-grid-item';
            widgetType = 'grid';
        } else if ($paginationParent.find('.ggmc-products-list').length > 0) {
            $container = $paginationParent.find('.ggmc-products-list');
            containerClass = 'ggmc-products-list';
            itemClass = 'product-list-item';
            widgetType = 'list';
        } else if ($paginationParent.find('.ggmc-product-table').length > 0) {
            $container = $paginationParent.find('.ggmc-product-table');
            containerClass = 'ggmc-product-table';
            itemClass = 'product-table-row';
            widgetType = 'table';
        }

        if (!$container || !widgetType) {
            return;
        }


        // Check if filters are active
        var isFilterActive = window.ggmDisplayState[widgetType] && window.ggmDisplayState[widgetType].filterActive;

        if (isFilterActive) {
            return;
        }

        var perPage = parseInt($container.data('products-per-page')) || 12;

        var page = 1;
        var $currentPage = $('.pagination-current');

        if ($link.hasClass('pagination-next')) {
            if ($currentPage.length > 0) {
                page = parseInt($currentPage.text()) + 1;
            }
        } else if ($link.hasClass('pagination-prev')) {
            if ($currentPage.length > 0) {
                page = parseInt($currentPage.text()) - 1;
            }
        } else {
            page = parseInt($link.text());
        }

        var startIndex = (page - 1) * perPage;
        var endIndex = startIndex + perPage;


        // Show/hide products for current page
        var $items = $container.find('.' + itemClass);
        $items.hide();
        $items.slice(startIndex, endIndex).show();

        // Update pagination display
        var totalProducts = $items.length;
        var totalPages = Math.ceil(totalProducts / perPage);


        updateNonFilteredPagination(containerClass, page, totalPages);

        // Scroll to top
        if ($container.parent().length > 0) {
            $('html, body').animate({
                scrollTop: $container.parent().offset().top - 100
            }, 300);
        }
    });

    // Initialize on DOM ready
    $(document).ready(function() {
        initProductDisplay('ggmc-products-grid', 'product-grid-item');
        initProductDisplay('ggmc-products-list', 'product-list-item');
        initProductDisplay('ggmc-product-table', 'product-table-row');
    });

    // Also initialize when Elementor frontend loads
    $(window).on('elementor/frontend/init', function() {
        initProductDisplay('ggmc-products-grid', 'product-grid-item');
        initProductDisplay('ggmc-products-list', 'product-list-item');
        initProductDisplay('ggmc-product-table', 'product-table-row');
    });

    /**
     * Product Table Sorting Functionality
     */

    // Handle sort select change
    $(document).on('change', '.table-sort-select', function() {
        var $select = $(this);
        var sortValue = $select.val();
        var $table = $select.closest('.ggmc-product-table-container').find('.ggmc-product-table');

        if (!sortValue) return;


        // Parse sort value (e.g., "name_asc" -> field: "name", direction: "asc")
        var parts = sortValue.split('_');
        var field = parts[0];
        var direction = parts[1];

        sortTable($table, field, direction);

        // Clear any column header sort states
        $table.find('th.sortable').removeClass('sort-asc sort-desc');
    });

    // Handle column header click
    $(document).on('click', '.ggmc-product-table th.sortable', function(e) {
        var $th = $(this);
        var $table = $th.closest('.ggmc-product-table');
        var sortingType = $table.data('sorting-type');

        // Only allow header sorting if enabled
        if (sortingType !== 'headers' && sortingType !== 'both') {
            return;
        }

        var field = $th.data('sort');
        var newDirection;

        // Check if user clicked on a specific arrow
        var $target = $(e.target);
        if ($target.hasClass('eicon-arrow-up')) {
            newDirection = 'asc';
        } else if ($target.hasClass('eicon-arrow-down')) {
            newDirection = 'desc';
        } else {
            // Clicked on header text or th itself - toggle
            var currentDirection = $th.hasClass('sort-asc') ? 'asc' : ($th.hasClass('sort-desc') ? 'desc' : null);

            if (currentDirection === null || currentDirection === 'desc') {
                newDirection = 'asc';
            } else {
                newDirection = 'desc';
            }
        }


        // Remove all sort classes from headers
        $table.find('th.sortable').removeClass('sort-asc sort-desc');

        // Add new sort class to clicked header
        $th.addClass('sort-' + newDirection);

        // Clear select box
        var $select = $table.closest('.ggmc-product-table-container').find('.table-sort-select');
        if ($select.length) {
            $select.val('');
        }

        // Sort the table
        sortTable($table, field, newDirection);
    });

    /**
     * Sort table rows
     * @param {jQuery} $table - Table element
     * @param {string} field - Field to sort by (name, sku, price, stock, created_at)
     * @param {string} direction - Sort direction (asc, desc)
     */
    function sortTable($table, field, direction) {
        var $tbody = $table.find('tbody');

        // Check if filtering is active for product table
        var widgetType = 'table';
        var filterActive = window.ggmDisplayState &&
                          window.ggmDisplayState[widgetType] &&
                          window.ggmDisplayState[widgetType].filterActive;

        var $rows;
        if (filterActive) {
            // Use filteredProductIds to find ALL matching rows across all pages
            // (filtered-out class is also applied to paginated items, so we can't rely on it)
            var filteredIds = window.ggmDisplayState[widgetType].filteredProductIds || [];
            $rows = [];
            filteredIds.forEach(function(id) {
                var $row = $tbody.find('tr.product-table-row[data-product-id="' + id + '"]');
                if ($row.length > 0) {
                    $rows.push($row[0]);
                }
            });
        } else {
            // Sort all rows
            $rows = $tbody.find('tr.product-table-row').get();
        }


        // Map field names to data attributes
        var dataAttr = 'data-' + (field === 'created_at' ? 'created-at' : (field === 'price' ? 'price-sort' : field));

        // Check if all created_at values are 0 (invalid dates)
        if (field === 'created_at') {
            var hasValidDates = false;
            for (var i = 0; i < Math.min(3, $rows.length); i++) {
                var val = parseFloat($($rows[i]).attr(dataAttr)) || 0;
                if (val > 0) {
                    hasValidDates = true;
                    break;
                }
            }
            if (!hasValidDates) {
                return;
            }
        }

        // Sort rows
        $rows.sort(function(a, b) {
            var aVal = $(a).attr(dataAttr);
            var bVal = $(b).attr(dataAttr);

            // Handle numeric vs string comparison
            if (field === 'price' || field === 'stock' || field === 'created_at') {
                aVal = parseFloat(aVal) || 0;
                bVal = parseFloat(bVal) || 0;
            } else {
                aVal = (aVal || '').toString().toLowerCase();
                bVal = (bVal || '').toString().toLowerCase();
            }

            if (direction === 'asc') {
                return aVal > bVal ? 1 : (aVal < bVal ? -1 : 0);
            } else {
                return aVal < bVal ? 1 : (aVal > bVal ? -1 : 0);
            }
        });

        // Reorder DOM
        if (filterActive) {
            // Collect non-matching rows (those NOT in filteredProductIds)
            var filteredIdSet = {};
            (window.ggmDisplayState[widgetType].filteredProductIds || []).forEach(function(id) {
                filteredIdSet[id] = true;
            });
            var $nonMatchingRows = $tbody.find('tr.product-table-row').filter(function() {
                return !filteredIdSet[$(this).attr('data-product-id')];
            });

            // Clear tbody and append sorted matching rows first, then non-matching
            $tbody.empty();
            $.each($rows, function(index, row) {
                $tbody.append(row);
            });
            $nonMatchingRows.each(function() {
                $tbody.append(this);
            });
        } else {
            // Reorder all rows
            $.each($rows, function(index, row) {
                $tbody.append(row);
            });
        }

        // Reset pagination to page 1 after sorting
        var perPage = parseInt($table.data('products-per-page')) || 20;

        if (filterActive) {
            // Re-apply filtered pagination from page 1 using the sorted DOM
            var sortedFilteredIds = [];
            $.each($rows, function(index, row) {
                sortedFilteredIds.push($(row).attr('data-product-id'));
            });
            // Update the stored filteredProductIds to reflect new sort order
            window.ggmDisplayState[widgetType].filteredProductIds = sortedFilteredIds;
            showFilteredProducts('ggmc-product-table', 'product-table-row', sortedFilteredIds, 1);
        } else {
            // Get ALL rows regardless of current visibility
            var $allRows = $tbody.find('tr.product-table-row');
            $allRows.hide();
            $allRows.slice(0, perPage).show();
            var totalPages = Math.ceil($allRows.length / perPage);
            updateNonFilteredPagination('ggmc-product-table', 1, totalPages);
        }

    }

    /**
     * Product Grid Sorting Functionality
     */

    // Handle sort select change for grid
    $(document).on('change', '.grid-sort-select', function() {
        var $select = $(this);
        var sortValue = $select.val();
        var $grid = $select.closest('.ggmc-product-grid-container').find('.ggmc-products-grid');

        if (!sortValue) {
            // Reset to default order if empty value selected
            location.reload();
            return;
        }

        // Parse sort value (e.g., "name_asc" -> field: "name", direction: "asc")
        var parts = sortValue.split('_');
        var field = parts[0];
        var direction = parts[1];

        sortGrid($grid, field, direction);
    });

    /**
     * Sort grid items
     * @param {jQuery} $grid - Grid element
     * @param {string} field - Field to sort by (date, name, price, stock)
     * @param {string} direction - Sort direction (asc, desc)
     */
    function sortGrid($grid, field, direction) {
        // Check if filtering is active for product grid
        var widgetType = 'grid';
        var filterActive = window.ggmDisplayState &&
                          window.ggmDisplayState[widgetType] &&
                          window.ggmDisplayState[widgetType].filterActive;

        var $items;
        if (filterActive) {
            // Use filteredProductIds to find ALL matching items across all pages
            // (filtered-out class is also applied to paginated items, so we can't rely on it)
            var filteredIds = window.ggmDisplayState[widgetType].filteredProductIds || [];
            $items = [];
            filteredIds.forEach(function(id) {
                var $item = $grid.find('.product-grid-item[data-product-id="' + id + '"]');
                if ($item.length > 0) {
                    $items.push($item[0]);
                }
            });
        } else {
            // Sort all items
            $items = $grid.find('.product-grid-item').get();
        }

        // Map field names to data attributes
        var dataAttr = 'data-' + (field === 'date' ? 'created-at' : (field === 'price' ? 'price-sort' : field));

        // Sort items
        $items.sort(function(a, b) {
            var aVal = $(a).attr(dataAttr);
            var bVal = $(b).attr(dataAttr);

            // Handle numeric vs string comparison
            if (field === 'price' || field === 'stock' || field === 'date') {
                aVal = parseFloat(aVal) || 0;
                bVal = parseFloat(bVal) || 0;
            } else {
                aVal = (aVal || '').toString().toLowerCase();
                bVal = (bVal || '').toString().toLowerCase();
            }

            if (direction === 'asc') {
                return aVal > bVal ? 1 : (aVal < bVal ? -1 : 0);
            } else {
                return aVal < bVal ? 1 : (aVal > bVal ? -1 : 0);
            }
        });

        // Reorder DOM
        if (filterActive) {
            // Collect non-matching items (those NOT in filteredProductIds)
            var filteredIdSet = {};
            (window.ggmDisplayState[widgetType].filteredProductIds || []).forEach(function(id) {
                filteredIdSet[id] = true;
            });
            var $nonMatchingItems = $grid.find('.product-grid-item').filter(function() {
                return !filteredIdSet[$(this).attr('data-product-id')];
            });

            // Clear grid and append sorted matching items first, then non-matching
            $grid.empty();
            $.each($items, function(index, item) {
                $grid.append(item);
            });
            $nonMatchingItems.each(function() {
                $grid.append(this);
            });
        } else {
            // Reorder all items
            $.each($items, function(index, item) {
                $grid.append(item);
            });
        }

        // Reset pagination to page 1 after sorting
        var perPage = parseInt($grid.data('products-per-page')) || 12;

        if (filterActive) {
            // Re-apply filtered pagination from page 1 using the sorted DOM
            var sortedFilteredIds = [];
            $.each($items, function(index, item) {
                sortedFilteredIds.push($(item).attr('data-product-id'));
            });
            // Update the stored filteredProductIds to reflect new sort order
            window.ggmDisplayState[widgetType].filteredProductIds = sortedFilteredIds;
            showFilteredProducts('ggmc-products-grid', 'product-grid-item', sortedFilteredIds, 1);
        } else {
            // Get ALL items regardless of current visibility
            var $allItems = $grid.find('.product-grid-item');
            $allItems.hide();
            $allItems.slice(0, perPage).show();
            var totalPages = Math.ceil($allItems.length / perPage);
            updateNonFilteredPagination('ggmc-products-grid', 1, totalPages);
        }
    }

})(jQuery);
