(function() {
    'use strict';

    function pad(n, len) {
        len = len || 2;
        return String(n).padStart(len, '0');
    }

    function format(ms, showMs) {
        ms = Math.max(0, ms);
        var h = Math.floor(ms / 3600000);
        var m = Math.floor((ms % 3600000) / 60000);
        var s = Math.floor((ms % 60000) / 1000);
        var out = pad(h) + ':' + pad(m) + ':' + pad(s);
        if (showMs) out += '.' + pad(Math.floor((ms % 1000) / 10));
        return out;
    }

    function beep() {
        try {
            var ctx = new (window.AudioContext || window.webkitAudioContext)();
            var osc = ctx.createOscillator();
            var gain = ctx.createGain();
            osc.frequency.value = 880;
            osc.connect(gain);
            gain.connect(ctx.destination);
            gain.gain.setValueAtTime(0.15, ctx.currentTime);
            osc.start();
            osc.stop(ctx.currentTime + 0.15);
        } catch (e) { /* audio not available, ignore */ }
    }

    function initStopwatch(wrap) {
        var id        = wrap.id;
        var mode      = wrap.dataset.mode === 'countdown' ? 'countdown' : 'stopwatch';
        var fromSecs  = parseInt(wrap.dataset.from, 10) || 0;
        var showMs    = wrap.dataset.ms === '1';
        var useSound  = wrap.dataset.sound === '1';
        var persist   = wrap.dataset.persist === '1';
        var storeKey  = 'ssetu_' + id;

        var display  = wrap.querySelector('.ssetu-display');
        var lapsBox  = wrap.querySelector('.ssetu-laps');
        var btnStart = wrap.querySelector('.ssetu-start');
        var btnStop  = wrap.querySelector('.ssetu-stop');
        var btnReset = wrap.querySelector('.ssetu-reset');
        var btnLap   = wrap.querySelector('.ssetu-lap');
        var btnExport= wrap.querySelector('.ssetu-export');

        if (!display) return;

        var start = 0, elapsed = 0, timer = null, running = false, laps = [];

        if (persist) {
            try {
                var saved = JSON.parse(localStorage.getItem(storeKey) || 'null');
                if (saved && typeof saved.elapsed === 'number') {
                    elapsed = saved.elapsed;
                    laps    = saved.laps || [];
                    renderLaps();
                }
            } catch (e) { /* ignore corrupt storage */ }
        }

        function save() {
            if (!persist) return;
            try { localStorage.setItem(storeKey, JSON.stringify({ elapsed: elapsed, laps: laps })); } catch (e) {}
        }

        function clearSave() {
            if (!persist) return;
            try { localStorage.removeItem(storeKey); } catch (e) {}
        }

        function currentMs() {
            var live = running ? (Date.now() - start) : 0;
            return mode === 'countdown'
                ? (fromSecs * 1000) - elapsed - live
                : elapsed + live;
        }

        function renderLaps() {
            lapsBox.innerHTML = '';
            laps.forEach(function(l, i) {
                var item = document.createElement('div');
                item.className   = 'ssetu-lap-item';
                item.textContent = 'Lap ' + (i + 1) + ': ' + format(l, showMs);
                lapsBox.appendChild(item);
            });
            btnExport.style.display = laps.length ? '' : 'none';
        }

        function tick() {
            var ms = currentMs();
            display.textContent = format(ms, showMs);
            if (mode === 'countdown' && ms <= 0) {
                display.textContent = format(0, showMs);
                stop();
                if (useSound) beep();
            }
        }

        function start_() {
            if (running) return;
            running = true;
            start   = Date.now();
            timer   = setInterval(tick, showMs ? 50 : 250);
            btnStart.disabled = true;
            btnStop.disabled  = false;
            btnLap.disabled   = false;
            if (useSound) beep();
        }

        function stop() {
            if (!running) return;
            running = false;
            elapsed += Date.now() - start;
            clearInterval(timer);
            btnStart.disabled = false;
            btnStop.disabled  = true;
            btnLap.disabled   = true;
            save();
            if (useSound) beep();
        }

        function reset() {
            running = false;
            clearInterval(timer);
            elapsed  = 0;
            laps     = [];
            display.textContent = mode === 'countdown' ? format(fromSecs * 1000, showMs) : format(0, showMs);
            renderLaps();
            btnStart.disabled = false;
            btnStop.disabled  = true;
            btnLap.disabled   = true;
            clearSave();
        }

        function lap() {
            if (!running) return;
            laps.push(currentMs());
            renderLaps();
            save();
        }

        function exportLaps() {
            var text = laps.map(function(l, i) { return 'Lap ' + (i + 1) + ': ' + format(l, showMs); }).join('\n');
            var blob = new Blob([text], { type: 'text/plain' });
            var url  = URL.createObjectURL(blob);
            var a    = document.createElement('a');
            a.href     = url;
            a.download = 'laps.txt';
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }

        btnStart.addEventListener('click', start_);
        btnStop.addEventListener('click', stop);
        btnReset.addEventListener('click', reset);
        btnLap.addEventListener('click', lap);
        btnExport.addEventListener('click', exportLaps);

        // Render initial state (covers restored persisted state)
        display.textContent = format(currentMs(), showMs);
        renderLaps();
    }

    function initAll() {
        document.querySelectorAll('.ssetu-wrap').forEach(initStopwatch);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initAll);
    } else {
        initAll();
    }
})();
