export const prefersReducedMotion = () =>
    window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false;

export function ensureClones(track, originalSlides, { minWidthFactor = 2 } = {}) {
    track.querySelectorAll('[data-clone="1"]').forEach((n) => n.remove());
    if (!originalSlides.length) return;

    const minWidth = track.clientWidth * minWidthFactor;
    while (track.scrollWidth < minWidth) {
        originalSlides.forEach((s) => {
            const c = s.cloneNode(true);
            c.dataset.clone = '1';
            track.appendChild(c);
        });
    }

    // always at least one clone pass
    if (!track.querySelector('[data-clone="1"]')) {
        originalSlides.forEach((s) => {
            const c = s.cloneNode(true);
            c.dataset.clone = '1';
            track.appendChild(c);
        });
    }
}

export function getOriginalSetWidth(track, originalSlides) {
    const last = originalSlides[originalSlides.length - 1];
    if (!last) return Math.max(track.scrollWidth / 2, 1);

    const lastRect = last.getBoundingClientRect();
    const trackRect = track.getBoundingClientRect();
    return Math.max((lastRect.right - trackRect.left) + track.scrollLeft, 1);
}

/**
 * Builds a bidirectional "true infinite" loop:
 * creates [before clones][original][after clones] and keeps originals marked.
 */
export function buildLoopClones(track, originalSlides, { beforeSets = 1, afterSets = 1 } = {}) {
    // clear previous clones and marks
    track.querySelectorAll('[data-clone="1"]').forEach((n) => n.remove());
    track.querySelectorAll('[data-original="1"]').forEach((n) => n.removeAttribute('data-original'));

    if (!originalSlides.length) return;

    originalSlides.forEach((n) => (n.dataset.original = '1'));

    const cloneSet = () =>
        originalSlides.map((s) => {
            const c = s.cloneNode(true);
            c.dataset.clone = '1';
            return c;
        });

    // prepend sets (reverse so order is preserved)
    for (let set = 0; set < beforeSets; set++) {
        const clones = cloneSet();
        for (let i = clones.length - 1; i >= 0; i--) track.prepend(clones[i]);
    }

    // append sets
    for (let set = 0; set < afterSets; set++) {
        cloneSet().forEach((n) => track.appendChild(n));
    }
}

/**
 * Returns loop metrics based on marked originals in the DOM.
 * startX = scrollLeft where the original set starts
 * setW   = width of one full original set
 */
export function getLoopMetrics(track) {
    const originals = Array.from(track.querySelectorAll('[data-original="1"]'));
    const first = originals[0];
    const last = originals[originals.length - 1];
    if (!first || !last) return { startX: 0, setW: 1 };

    const startX = first.offsetLeft;
    const setW = (last.offsetLeft + last.offsetWidth) - startX;

    return { startX, setW };
}