function isStandalone() {
    return (
        window.matchMedia('(display-mode: standalone)').matches ||
        window.navigator.standalone === true
    );
}

function refreshLivewireOrReload() {
    const lw = window.Livewire;
    if (!lw || typeof lw.find !== 'function') {
        window.location.reload();
        return;
    }

    const seen = new Set();
    document.querySelectorAll('[wire\\:id]').forEach((el) => {
        const id = el.getAttribute('wire:id');
        if (!id || seen.has(id)) {
            return;
        }
        seen.add(id);
        try {
            const wire = lw.find(id);
            if (wire && typeof wire.$refresh === 'function') {
                wire.$refresh();
            }
        } catch {
            window.location.reload();
        }
    });
}

export function initPullToRefresh() {
    if (!isStandalone() || !('ontouchstart' in window)) {
        return;
    }

    const scrollEl = document.getElementById('pwa-scroll-root');
    if (!scrollEl || scrollEl.dataset.pwaPullInit === '1') {
        return;
    }
    scrollEl.dataset.pwaPullInit = '1';

    const indicator = document.getElementById('pwa-pull-indicator');
    let startY = 0;
    let pulling = false;
    let distance = 0;
    const threshold = 72;

    const setIndicator = (d, active) => {
        if (!indicator) {
            return;
        }
        indicator.style.transform = `translateY(${Math.min(d, threshold + 24) - 48}px)`;
        indicator.style.opacity = d > 8 ? String(Math.min(d / threshold, 1)) : '0';
        indicator.classList.toggle('pwa-pull-indicator--active', active);
    };

    scrollEl.addEventListener(
        'touchstart',
        (e) => {
            if (scrollEl.scrollTop > 0) {
                return;
            }
            startY = e.touches[0].clientY;
            pulling = true;
            distance = 0;
        },
        { passive: true },
    );

    scrollEl.addEventListener(
        'touchmove',
        (e) => {
            if (!pulling || scrollEl.scrollTop > 0) {
                return;
            }
            distance = Math.max(0, e.touches[0].clientY - startY);
            if (distance > 6) {
                setIndicator(distance, distance >= threshold);
            }
        },
        { passive: true },
    );

    scrollEl.addEventListener(
        'touchend',
        () => {
            if (!pulling) {
                return;
            }
            pulling = false;
            if (scrollEl.scrollTop <= 0 && distance >= threshold) {
                refreshLivewireOrReload();
            }
            distance = 0;
            setIndicator(0, false);
        },
        { passive: true },
    );

    scrollEl.addEventListener(
        'touchcancel',
        () => {
            pulling = false;
            distance = 0;
            setIndicator(0, false);
        },
        { passive: true },
    );
}
