/**
 * QUnit Tests for Realtime Search Functionality
 * Tests product filtering and search behavior
 */

odoo.define("website_sale_aplicoop.test_realtime_search", function (require) {
    "use strict";

    var QUnit = window.QUnit;

    QUnit.module(
        "website_sale_aplicoop.realtime_search",
        {
            beforeEach: function () {
                // Setup: Create test DOM with product cards
                this.$fixture = $("#qunit-fixture");

                this.$fixture.append(
                    '<input type="text" id="realtime-search-input" />' +
                        '<select id="realtime-category-select">' +
                        '<option value="">All Categories</option>' +
                        '<option value="1">Category 1</option>' +
                        '<option value="2">Category 2</option>' +
                        "</select>" +
                        '<div class="product-card" data-product-name="Cabbage" data-category-id="1"></div>' +
                        '<div class="product-card" data-product-name="Carrot" data-category-id="1"></div>' +
                        '<div class="product-card" data-product-name="Apple" data-category-id="2"></div>' +
                        '<div class="product-card" data-product-name="Banana" data-category-id="2"></div>'
                );

                // Initialize search object
                window.realtimeSearch = {
                    searchInput: document.getElementById("realtime-search-input"),
                    categorySelect: document.getElementById("realtime-category-select"),
                    productCards: document.querySelectorAll(".product-card"),

                    filterProducts: function () {
                        var searchTerm = this.searchInput.value.toLowerCase().trim();
                        var selectedCategory = this.categorySelect.value;

                        var visibleCount = 0;
                        var hiddenCount = 0;

                        this.productCards.forEach(function (card) {
                            var productName = card.getAttribute("data-product-name").toLowerCase();
                            var categoryId = card.getAttribute("data-category-id");

                            var matchesSearch = !searchTerm || productName.includes(searchTerm);
                            var matchesCategory =
                                !selectedCategory || categoryId === selectedCategory;

                            if (matchesSearch && matchesCategory) {
                                card.classList.remove("d-none");
                                visibleCount++;
                            } else {
                                card.classList.add("d-none");
                                hiddenCount++;
                            }
                        });

                        return { visible: visibleCount, hidden: hiddenCount };
                    },
                };
            },
            afterEach: function () {
                // Cleanup
                this.$fixture.empty();
                delete window.realtimeSearch;
            },
        },
        function () {
            QUnit.test("search input element exists", function (assert) {
                assert.expect(1);

                var searchInput = document.getElementById("realtime-search-input");
                assert.ok(searchInput, "search input element exists");
            });

            QUnit.test("category select element exists", function (assert) {
                assert.expect(1);

                var categorySelect = document.getElementById("realtime-category-select");
                assert.ok(categorySelect, "category select element exists");
            });

            QUnit.test("product cards are found", function (assert) {
                assert.expect(1);

                var productCards = document.querySelectorAll(".product-card");
                assert.equal(productCards.length, 4, "found 4 product cards");
            });

            QUnit.test("search filters by product name", function (assert) {
                assert.expect(2);

                // Search for "cab"
                window.realtimeSearch.searchInput.value = "cab";
                var result = window.realtimeSearch.filterProducts();

                assert.equal(result.visible, 1, "1 product visible (Cabbage)");
                assert.equal(result.hidden, 3, "3 products hidden");
            });

            QUnit.test("search is case insensitive", function (assert) {
                assert.expect(2);

                // Search for "CARROT" in uppercase
                window.realtimeSearch.searchInput.value = "CARROT";
                var result = window.realtimeSearch.filterProducts();

                assert.equal(result.visible, 1, "1 product visible (Carrot)");
                assert.equal(result.hidden, 3, "3 products hidden");
            });

            QUnit.test("empty search shows all products", function (assert) {
                assert.expect(2);

                window.realtimeSearch.searchInput.value = "";
                var result = window.realtimeSearch.filterProducts();

                assert.equal(result.visible, 4, "all 4 products visible");
                assert.equal(result.hidden, 0, "no products hidden");
            });

            QUnit.test("category filter works", function (assert) {
                assert.expect(2);

                // Select category 1
                window.realtimeSearch.categorySelect.value = "1";
                var result = window.realtimeSearch.filterProducts();

                assert.equal(result.visible, 2, "2 products visible (Cabbage, Carrot)");
                assert.equal(result.hidden, 2, "2 products hidden (Apple, Banana)");
            });

            QUnit.test("search and category filter work together", function (assert) {
                assert.expect(2);

                // Search for "ca" in category 1
                window.realtimeSearch.searchInput.value = "ca";
                window.realtimeSearch.categorySelect.value = "1";
                var result = window.realtimeSearch.filterProducts();

                // Should show: Cabbage, Carrot (both in category 1 and match "ca")
                assert.equal(result.visible, 2, "2 products visible");
                assert.equal(result.hidden, 2, "2 products hidden");
            });

            QUnit.test("search for non-existent product shows none", function (assert) {
                assert.expect(2);

                window.realtimeSearch.searchInput.value = "xyz123";
                var result = window.realtimeSearch.filterProducts();

                assert.equal(result.visible, 0, "no products visible");
                assert.equal(result.hidden, 4, "all 4 products hidden");
            });

            QUnit.test("partial match works", function (assert) {
                assert.expect(2);

                // Search for "an" should match "Banana"
                window.realtimeSearch.searchInput.value = "an";
                var result = window.realtimeSearch.filterProducts();

                assert.equal(result.visible, 1, "1 product visible (Banana)");
                assert.equal(result.hidden, 3, "3 products hidden");
            });

            QUnit.test("search trims whitespace", function (assert) {
                assert.expect(2);

                // Search with extra whitespace
                window.realtimeSearch.searchInput.value = "  apple  ";
                var result = window.realtimeSearch.filterProducts();

                assert.equal(result.visible, 1, "1 product visible (Apple)");
                assert.equal(result.hidden, 3, "3 products hidden");
            });

            QUnit.test("d-none class is added to hidden products", function (assert) {
                assert.expect(1);

                window.realtimeSearch.searchInput.value = "cabbage";
                window.realtimeSearch.filterProducts();

                var productCards = document.querySelectorAll(".product-card");
                var hiddenCards = Array.from(productCards).filter(function (card) {
                    return card.classList.contains("d-none");
                });

                assert.equal(hiddenCards.length, 3, "3 cards have d-none class");
            });

            QUnit.test("d-none class is removed from visible products", function (assert) {
                assert.expect(2);

                // First hide all
                window.realtimeSearch.searchInput.value = "xyz";
                window.realtimeSearch.filterProducts();

                var allHidden = Array.from(window.realtimeSearch.productCards).every(function (
                    card
                ) {
                    return card.classList.contains("d-none");
                });
                assert.ok(allHidden, "all cards hidden initially");

                // Then show all
                window.realtimeSearch.searchInput.value = "";
                window.realtimeSearch.filterProducts();

                var allVisible = Array.from(window.realtimeSearch.productCards).every(function (
                    card
                ) {
                    return !card.classList.contains("d-none");
                });
                assert.ok(allVisible, "all cards visible after clearing search");
            });

            QUnit.test("filterProducts returns correct counts", function (assert) {
                assert.expect(4);

                // All visible
                window.realtimeSearch.searchInput.value = "";
                var result1 = window.realtimeSearch.filterProducts();
                assert.equal(result1.visible + result1.hidden, 4, "total count is 4");

                // 1 visible
                window.realtimeSearch.searchInput.value = "apple";
                var result2 = window.realtimeSearch.filterProducts();
                assert.equal(result2.visible, 1, "visible count is 1");

                // None visible
                window.realtimeSearch.searchInput.value = "xyz";
                var result3 = window.realtimeSearch.filterProducts();
                assert.equal(result3.visible, 0, "visible count is 0");

                // Category filter
                window.realtimeSearch.searchInput.value = "";
                window.realtimeSearch.categorySelect.value = "2";
                var result4 = window.realtimeSearch.filterProducts();
                assert.equal(result4.visible, 2, "category filter shows 2 products");
            });
        }
    );

    return {};
});
