function getTemplate() {
    const template = document.createElement('template');
    template.id = 'my-marquee-template';
    template.innerHTML = `
<style>
    .marquee-wrapper {
        mask-image: linear-gradient(to right, transparent 0%, black 10%, black 90%, transparent 100%);
    }

    .marquee {
        overflow: hidden;
        overflow-x: auto;
        position: relative;
        scrollbar-width: none;
    }

    .marquee-content {
        display: flex;
        gap: 8px;
        width: max-content;
        animation: scroll-left 0s linear infinite;
        animation-play-state: running;
    }

    .marquee-content:hover {
        animation-play-state: paused;
    }

    /* Animation */
    @keyframes scroll-left {
        0% {
            transform: translateX(0);
        }
        100% {
            transform: translateX(-25%);
        }
    }
    
    @keyframes scroll-right {
        0% {
            transform: translateX(0);
        }
        100% {
            transform: translateX(25%);
        }
    }
</style>

<div class="marquee-wrapper">
    <div class="marquee">
        <div class="marquee-content">
            <slot></slot>
        </div>
    </div>
</div>
`;

    return template;
}

class MyMarquee extends HTMLElement {
    static observedAttributes = ['speed', 'direction'];

    constructor() {
        super();

        const wrapper = getTemplate().content.cloneNode(true);
        const marquee = wrapper.querySelector('.marquee');
        const content = wrapper.querySelector('.marquee-content');

        const shadowRoot = this.attachShadow({ mode: 'open' });
        shadowRoot.appendChild(wrapper);

        this.marquee = marquee;
        this.content = content;
        this.repetitions = 1;
        this.speed = 500; // Default speed
        this.direction = 'left'; // Default direction

        window.addEventListener('load', this.onLoad.bind(this));
        this.marquee.addEventListener('scroll', this.handleScroll.bind(this), { passive: true });
    }

    attributeChangedCallback(name, oldValue, newValue) {
        if (name === 'speed') {
            this.speed = parseInt(newValue, 10) || this.speed; // Default to 100 if not set
            this.updateAnimation();
        } else if (name === 'direction') {
            this.direction = newValue || this.direction; // Default to 'left' if not set
            this.updateAnimation();
        }
    }

    onLoad() {
        const slot = this.content.querySelector('slot');

        const slottedElements = slot.assignedNodes({ flatten: true }).filter(node => node.nodeType === Node.ELEMENT_NODE);
        this.content.innerHTML = slottedElements.map(el => el.outerHTML).join('');

        requestAnimationFrame(() => {
            const singleWidth = this.content.scrollWidth;

            // Calculate the needed repetitions
            let repetitions = Math.ceil(window.innerWidth / singleWidth) + 1;
            this.repetitions = repetitions * 4; // Double the repetitions for a seamless effect

            console.debug(`Single content width: ${singleWidth}, Repetitions: ${this.repetitions}`);

            this.content.innerHTML = this.content.innerHTML.repeat(this.repetitions);
            this.repeatedWidth = singleWidth * this.repetitions;

            this.updateAnimation();

            // Set initial scroll position
            this.marquee.scrollLeft = (this.repeatedWidth - window.innerWidth) / 2;
        });
    }

    updateAnimation() {
        // Set the animation duration
        const duration = (this.repeatedWidth / this.speed) * 1000; // Convert to milliseconds
        this.content.style.animationDuration = `${duration}ms`;

        // Set the animation direction
        console.assert(['left', 'right'].includes(this.direction))
        this.content.style.animationName = `scroll-${this.direction}`;
        console.debug(`Animation updated: Duration ${duration}ms, Direction ${this.direction}`);
    }

    handleScroll() {
        const scrollStep = this.content.scrollWidth * 2 / this.repetitions;

        const currentScroll = this.marquee.scrollLeft;

        // Handle scrolling to the right
        if (currentScroll >= this.content.scrollWidth * 0.7) {
            console.debug(`Jumping back by ${scrollStep}`);
            this.marquee.scrollLeft -= scrollStep;
        }

        // Handle scrolling to the left
        if (currentScroll <= this.content.scrollWidth * 0.3) {
            console.debug(`Jumping forward by ${scrollStep}`);
            this.marquee.scrollLeft += scrollStep;
        }
    }
}

customElements.define('my-marquee', MyMarquee);