(function () {
    const STYLESHEET = document.createElement("style");
    let CAROUSAL_INFO = {};
    let CURRENT_PAGE = {};

    STYLESHEET.innerHTML = `
            .carousal {
                display: flex;
                gap: 24px;
                overflow-x: auto;
                scroll-behavior: smooth;
                padding: 16px 0;
                width: 100%;
                margin:0 auto;
                position:relative;
                box-sizing: border-box;
            }

            .carousal-card {
                flex: 0 0 auto;
               
            }

            .card h3 {
                margin: 0 0 8px 0;
                color: #333;
            }

            .card p {
                margin: 4px 0;
                color: #666;
            }

            .controller-button{
                position:absolute;
                top:50%;
                z-index:10;
                color:white;
                background-color:#03428E;
                padding:13.5px 15px;
                border-radius:50%;
                border:2px solid #03428E;
                transform: translateY(-50%);
                cursor: pointer;
                transition: opacity 0.3s;
                display:flex;
                justify-content:center;
                align-items:center; 
                transition:0.3s ease-in-out;
            }

            .controller-button svg{
                width:7px;
                height:11px;
            }

            .controller-button:not(:disabled):hover{
                background-color:#066ff01f;
                color:#03428E;
            }

            .controller-button:disabled{
                opacity: 0.3;
                cursor: not-allowed;
            }

            .track{
                display:flex;
                gap:24px;
                transition: transform 0.3s ease-in-out;
            }
            
            .controller-button-left{
                left:-19px;
            }
            
            .controller-button-right{
                right:-19px;
            }

            .track-container{
                overflow:hidden;
                width: 100%;
            }
        `;
    document.head.appendChild(STYLESHEET);

    const STATE = {
        kwargs: undefined
    }

    function getZone(width) {
        if (width <= 768) return "mobile";
        if (width <= 991) return "tablet";
        return "laptop";
    }

    function addIntersectionObserver(carousel) {

        const cards = carousel?.querySelectorAll(".carousal-card");
        if (!cards || cards.length < 4) return;

        const thirdLastCard = cards[cards.length - 4];

        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    document.dispatchEvent(new CustomEvent("carousalCardVisible", { detail: STATE, bubbles: true }));
                    observer.disconnect();
                }
            });
        }, {
            root: carousel,
            threshold: 0.5
        });

        observer.observe(thirdLastCard);
    }

    function computeCardWidth(kwargs) {
        let { carousal, maxCards, gap } = kwargs;
        maxCards = {
            mobile: 1,
            tablet: 2,
            laptop: 3,
            ...(maxCards || {})
        };

        const windowWidth = window.innerWidth;
        gap = gap || 24;

        let cardsPerRow;

        if (windowWidth < 768) {
            cardsPerRow = maxCards.mobile;
        } else if (windowWidth < 991) {
            cardsPerRow = maxCards.tablet;
        } else {
            cardsPerRow = maxCards.laptop;
        }

        const carousalRect = carousal.getBoundingClientRect();
        const carousalWidth = carousalRect.width;
        const totalGapWidth = (cardsPerRow - 1) * gap;
        const cardWidth = (carousalWidth - totalGapWidth) / cardsPerRow;


        return {
            width: Math.floor(cardWidth) - 1,
            cardsPerRow: cardsPerRow
        };

    };

    window.slideCarousal = function (containerId, direction) {
        const info = CAROUSAL_INFO[containerId];
        if (!info) return;

        const { carousal, data, gap, maxCards } = info;
        const track = carousal.querySelector(".track");
        const leftBtn = carousal.querySelector(".controller-button-left");
        const rightBtn = carousal.querySelector(".controller-button-right");

        if (!track) return;

        if (CURRENT_PAGE[containerId] === undefined) {
            CURRENT_PAGE[containerId] = 0;
        }

        const cardInfo = computeCardWidth({ carousal, maxCards, gap });
        const cardsPerRow = cardInfo.cardsPerRow;
        const cardWidth = cardInfo.width;
        const totalCards = data.length;

        const fullSlideDistance = (cardWidth + gap) * cardsPerRow;

        const totalPages = Math.ceil(totalCards / cardsPerRow);

        if (direction === "left") {
            CURRENT_PAGE[containerId] = Math.max(0, CURRENT_PAGE[containerId] - 1);
        } else {
            CURRENT_PAGE[containerId] = Math.min(totalPages - 1, CURRENT_PAGE[containerId] + 1);
        }

        let translateValue;

        if (CURRENT_PAGE[containerId] === totalPages - 1) {

            const remainder = totalCards % cardsPerRow || cardsPerRow;
            const lastSlideDistance = (cardWidth + gap) * remainder;

            translateValue = -(fullSlideDistance * (totalPages - 1) - (fullSlideDistance - lastSlideDistance));
        } else {
            translateValue = -(fullSlideDistance * CURRENT_PAGE[containerId]);
        }

        track.style.transform = `translateX(${translateValue}px)`;

        if (leftBtn && rightBtn) {
            leftBtn.disabled = CURRENT_PAGE[containerId] === 0;
            rightBtn.disabled = CURRENT_PAGE[containerId] >= totalPages - 1;

            leftBtn.style.opacity = CURRENT_PAGE[containerId] === 0 ? '0.3' : '1';
            rightBtn.style.opacity = CURRENT_PAGE[containerId] >= totalPages - 1 ? '0.3' : '1';
        }
        updateCarouselTabIndex(containerId);
    };


    function createButtonLayout(kwargs) {
        let { carousal, data, cardFunction, containerId, maxCards } = kwargs;

        maxCards = {
            mobile: 1,
            tablet: 2,
            laptop: 3,
            ...(maxCards || {})
        };

        if (!data || !cardFunction) {
            console.log("Data or card function not found");
            return;
        }

        carousal.style.overflow = 'visible';

        carousal.innerHTML = "";

        let track = `
        <button aria-label="slide carousel left" type="button" onclick="slideCarousal('${containerId}', 'left')" class="controller-button controller-button-left">
            <svg width="7" height="11" viewBox="0 0 7 11" fill="none">
                <path d="M5.167 10.334L0 5.167L5.167 0L6.396 1.229L2.459 5.167L6.396 9.105L5.167 10.334Z" fill="currentColor"/>
            </svg>
        </button>

        <button aria-label="slide carousel right" type="button" onclick="slideCarousal('${containerId}', 'right')" class="controller-button controller-button-right">
            <svg width="7" height="11" viewBox="0 0 7 11" fill="none">
                <path d="M1.229 10.334L0 9.105L3.937 5.167L0 1.229L1.229 0L6.396 5.167L1.229 10.334Z" fill="currentColor"/>
            </svg>
        </button>

        <div class='track-container'>
            <div class="track">
    `;

        const cardInfo = computeCardWidth(kwargs);

        data.forEach(element => {
            track += `
            <div class="carousal-card" style="width:${cardInfo.width}px;">
                ${cardFunction(element)}
            </div>`;
        });

        track += `</div></div>`;
        carousal.innerHTML = track;

        const leftBtn = carousal.querySelector(".controller-button-left");
        const rightBtn = carousal.querySelector(".controller-button-right");

        if (leftBtn) {
            leftBtn.disabled = true;
            leftBtn.style.opacity = '0.3';
        }

        let windowWidth = window.innerWidth;
        const totalCards = data.length;
        let visibleCards;

        if (windowWidth < 768) {
            visibleCards = maxCards.mobile;
        } else if (windowWidth < 991) {
            visibleCards = maxCards.tablet;
        } else {
            visibleCards = maxCards.laptop;
        }

        if (totalCards <= visibleCards) {
            leftBtn?.classList.add("hide");
            rightBtn?.classList.add("hide");
        } else {
            leftBtn?.classList.remove("hide");
            rightBtn?.classList.remove("hide");
        }
    };


    function createSliderLayout(kwargs) {
        let { carousal, data, cardFunction } = kwargs;

        if (!data || !cardFunction) {
            console.log("Data or card function not found");
            return;
        }

        let htmlToAdd = "";
        const cardInfo = computeCardWidth(kwargs);
        data.forEach(element => {
            htmlToAdd += `
                    <div class="carousal-card" style="width:${cardInfo.width}px;">
                        ${cardFunction(element)}
                    </div>`;
        });



        if (carousal.children.length == 0) {
            carousal.innerHTML = "";
            carousal.innerHTML = htmlToAdd;
        } else {
            carousal.innerHTML += htmlToAdd;
        }
    };

    function populateCarousal(kwargs) {
        const { containerId } = kwargs;
        const validTypes = ["button", "slide"];
        const CAROUSAL_LAYOUT = document.getElementById(containerId);

        if (!CAROUSAL_LAYOUT) {
            console.log("Element not found");
            return;
        }

        CURRENT_PAGE[containerId] = 0;

        let carousalType = (CAROUSAL_LAYOUT.dataset.type || "slide").toLowerCase();
        if (!validTypes.includes(carousalType)) {
            console.log("Invalid carousal type. Use: button or slide");
            return;
        }

        kwargs = { carousal: CAROUSAL_LAYOUT, ...kwargs };
        CAROUSAL_INFO[containerId] = kwargs;

        switch (carousalType) {
            case "slide":
                createSliderLayout(kwargs);
                break;
            case "button":
                createButtonLayout(kwargs);
                break;
        }

        addIntersectionObserver(CAROUSAL_LAYOUT);
    };


    function resizeCards(kwargs) {

        const { containerId } = kwargs;
        const CAROUSAL_LAYOUT = document.getElementById(containerId);
        const leftBtn = CAROUSAL_LAYOUT.querySelector(".controller-button-left");

        CAROUSAL_LAYOUT
        const cards = CAROUSAL_LAYOUT.querySelectorAll(".carousal-card");
        kwargs = { ...kwargs, carousal: CAROUSAL_LAYOUT }
        let newCardsWidth = computeCardWidth(kwargs);

        cards.forEach((card) => {
            card.style.width = `${newCardsWidth.width}px`
        })
        leftBtn.click()
    }

    function updateCarouselTabIndex(containerId) {

        const info = CAROUSAL_INFO[containerId];
        if (!info) return;
        const { carousal, gap, maxCards } = info;
        const cards = carousal.querySelectorAll(".carousal-card");
        const { cardsPerRow } = computeCardWidth({ carousal, gap, maxCards });

        const startIndex = CURRENT_PAGE[containerId] * cardsPerRow;
        const endIndex = startIndex + cardsPerRow;

        cards.forEach((card, index) => {
            const focusable = card.querySelectorAll(
                "a, button, input, select, textarea, [tabindex]"
            );
            const visible = index >= startIndex && index < endIndex;
            focusable.forEach(el => { el.tabIndex = visible ? 0 : -1; });
            card.setAttribute("aria-hidden", visible ? "false" : "true");
        });

    };

    function updateCards(newCards) {
        if (newCards.length == 0) return;
        STATE.kwargs.data = newCards;
        populateCarousal(STATE.kwargs);
    }



    window.updateCarousal = function (kwargs) {
        STATE.kwargs = kwargs;
        populateCarousal(kwargs);
        updateCarouselTabIndex(kwargs.containerId);
        let resizeTimeout;
        let lastZone = getZone(window.innerWidth);
        let lastWidth = window.innerWidth;
        window.addEventListener("resize", () => {

            const currentWidth = window.innerWidth;
            if (currentWidth === lastWidth) return;
            clearTimeout(resizeTimeout);
            resizeTimeout = setTimeout(() => {
                let w = window.innerWidth;
                let currentZone = getZone(w);
                if (currentZone !== lastZone) {
                    populateCarousal(kwargs);
                    lastZone = currentZone;
                }

                resizeCards(kwargs);
                if (kwargs.autoCall) {
                    kwargs.autoCall();
                }
            }, 250);
        });

        return { updateCards }
    };



    document.dispatchEvent(new CustomEvent("carousalReady", {
        detail: {
            message: "Carousal initialized successfully"
        },
    }));
})();