// OMSI LCD Panel - Bus Stop Display & Ad Rotation (Enhanced)

(function () {
    'use strict';

    // ===== Configuration =====
    const AD_IMAGE_DURATION = 10000;  // 10 seconds per image
    const VISIBLE_STOPS = 5;          // Reduced count for larger text
    const AT_STOP_DISPLAY_MS = 10000; // 10 seconds at-stop overlay
    const ZONE_NOTIFY_DELAY_MS = 5000; // 5 seconds delay for zone notification
    const ZONE_NOTIFY_DURATION_MS = 8000; // 8 seconds duration

    // ===== State =====
    let currentData = null;
    let adFiles = [];
    let currentAdIndex = 0;
    let adTimer = null;
    let adVideoElement = null;
    let atStopTimer = null;
    let atStopShowing = false;
    let zoneNotifyTimer = null;
    let zoneNotifyHideTimer = null;
    let lastNextStopName = "";
    
    // ===== DOM References =====
    const lineBadge = document.getElementById('line-badge');
    const destination = document.getElementById('destination');
    const stopList = document.getElementById('stop-list');
    const nextStopName = document.getElementById('next-stop-name');
    const nextStopBar = document.getElementById('next-stop-bar');
    const nextStopLabel = document.querySelector('#next-stop-bar .label');
    const adsPanel = document.getElementById('ads-panel');
    const noDataEl = document.getElementById('no-data');
    const stopsPanel = document.getElementById('stops-panel');
    const atStopOverlay = document.getElementById('at-stop-overlay');
    const atStopNameEl = document.getElementById('at-stop-name');
    const pageIndicator = document.getElementById('page-indicator');
    const clockEl = document.getElementById('clock');
    const delayEl = document.getElementById('delay');
    const zoneNotification = document.getElementById('zone-notification');
    const zoneLabel = document.querySelector('#zone-notification .zone-label');
    const zoneInfoText = document.querySelector('#zone-notification .zone-info');

    // ===== Helper: format delay =====
    function formatDelay(min) {
        if (min === undefined || min === null) return '';
        const m = parseFloat(min);
        if (isNaN(m)) return '';
        
        // Tolerance: -1 to +1 min considered "on time"
        if (m > 1.0) {
            delayEl.className = 'late';
            return `+${m.toFixed(1)} min`;
        } else if (m < -1.0) {
            delayEl.className = 'early';
            return `${m.toFixed(1)} min`;
        } else {
            delayEl.className = 'ontime';
            return ''; 
        }
    }

    // ===== Helper: extract stop name (supports both string and StopInfo object) =====
    function getStopName(stop) {
        if (typeof stop === 'string') return stop;
        if (stop && typeof stop === 'object') return stop.name || '';
        return '';
    }

    function isRequestStop(stop) {
        if (typeof stop === 'object' && stop) return !!stop.requestStop;
        return false;
    }

    function getFormattedZones(stop) {
        if (typeof stop !== 'object' || !stop) return [];
        var zones = [];
        if (stop.zonePID) zones.push(`PID: ${stop.zonePID}`);
        if (stop.zoneIDOL) zones.push(`IDOL: ${stop.zoneIDOL}`);
        if (stop.zoneDUK) zones.push(`DÚK: ${stop.zoneDUK}`);
        return zones;
    }

    // ===== At-Stop Overlay =====
    function showAtStopOverlay(stopName) {
        if (!atStopOverlay || !atStopNameEl) return;
        atStopNameEl.textContent = stopName;
        atStopOverlay.classList.add('visible');
        atStopShowing = true;

        if (atStopTimer) clearTimeout(atStopTimer);
        atStopTimer = setTimeout(function () {
            atStopOverlay.classList.remove('visible');
            atStopShowing = false;
            atStopTimer = null;
        }, AT_STOP_DISPLAY_MS);
    }

    function hideAtStopOverlay() {
        if (!atStopOverlay) return;
        atStopOverlay.classList.remove('visible');
        atStopShowing = false;
        if (atStopTimer) {
            clearTimeout(atStopTimer);
            atStopTimer = null;
        }
    }

    // ===== Zone Change Notification =====
    function showZoneNotification(type, info) {
        if (!zoneNotification) return;
        zoneLabel.textContent = type;
        zoneInfoText.textContent = info;
        
        zoneNotification.classList.add('visible');
        
        if (zoneNotifyHideTimer) clearTimeout(zoneNotifyHideTimer);
        zoneNotifyHideTimer = setTimeout(() => {
            zoneNotification.classList.remove('visible');
        }, ZONE_NOTIFY_DURATION_MS);
    }

    function checkZoneChange(data) {
        if (!data || !data.stops || data.stops.length === 0) return;
        
        const currentStop = data.stops[0]; // The upcoming stop
        
        // Ensure we have previous data
        const prevPID = data.prevPID || "";
        const prevIDOL = data.prevIDOL || "";
        const prevDUK = data.prevDUK || "";
        
        const currPID = currentStop.zonePID || "";
        const currIDOL = currentStop.zoneIDOL || "";
        const currDUK = currentStop.zoneDUK || "";

        // Check 1: System Change (IDOL vs DUK)
        const hasIDOL = !!currIDOL;
        const hadIDOL = !!prevIDOL;
        const hasDUK = !!currDUK;
        const hadDUK = !!prevDUK;

        if ((hasIDOL && hasDUK) && (!hadIDOL || !hadDUK)) {
             scheduleZoneNotify("ZMĚNA TARIFNÍHO SYSTÉMU", "IDOL + DÚK");
             return;
        }
        
        if (hasIDOL && !hadIDOL && hadDUK && !hasDUK) {
             scheduleZoneNotify("ZMĚNA TARIFNÍHO SYSTÉMU", "DÚK -> IDOL");
             return;
        }
        
        if (hasDUK && !hadDUK && hadIDOL && !hasIDOL) {
             scheduleZoneNotify("ZMĚNA TARIFNÍHO SYSTÉMU", "IDOL -> DÚK");
             return;
        }

        // Check 2: Zone Change (PID)
        if (prevPID && currPID && prevPID !== currPID) {
            scheduleZoneNotify("ZMĚNA PÁSMA PID", `${prevPID} -> ${currPID}`);
            return;
        }
        
        // Check 3: Zone Change (IDOL)
        if (prevIDOL && currIDOL && prevIDOL !== currIDOL) {
            scheduleZoneNotify("ZMĚNA PÁSMA IDOL", `${prevIDOL} -> ${currIDOL}`);
            return;
        }
        
        // Check 4: Zone Change (DUK)
        if (prevDUK && currDUK && prevDUK !== currDUK) {
            scheduleZoneNotify("ZMĚNA PÁSMA DÚK", `${prevDUK} -> ${currDUK}`);
            return;
        }
    }

    function scheduleZoneNotify(label, info) {
        if (zoneNotifyTimer) clearTimeout(zoneNotifyTimer);
        zoneNotifyTimer = setTimeout(() => {
            showZoneNotification(label, info);
        }, ZONE_NOTIFY_DELAY_MS);
    }

    // ===== Marquee Logic =====
    function updateDestination(text) {
        // Only update DOM if changed
        const span = destination.querySelector('span');
        const currentSpanText = span ? span.textContent : "";
        
        if (currentSpanText !== text) {
            destination.innerHTML = `<span>${text}</span>`;
            checkMarquee();
        }
    }

    function checkMarquee() {
        const span = destination.querySelector('span');
        if (!span) return;
        
        // Reset class to measure
        span.className = '';
        
        if (span.offsetWidth > destination.offsetWidth) {
            span.classList.add('marquee');
        } else {
            span.classList.remove('marquee');
        }
    }

    // ===== Bus Stop Rendering =====

    // Track previous atStop state to detect transition
    let prevAtStop = false;

    function updateStops(data) {
        if (!data) {
            resetDisplay();
            return;
        }

        currentData = data;

        // Update header
        lineBadge.textContent = data.line || '--';
        updateDestination(data.destination || '---');
        
        // Time & Delay
        if (data.time) {
            clockEl.textContent = data.time;
        }
        
        if (data.delay !== undefined) {
            delayEl.textContent = formatDelay(data.delay);
        } else {
            delayEl.textContent = '';
        }

        // STOP Request Logic (Footer)
        if (data.stopRequest) {
            nextStopBar.classList.add('stop-requested');
            nextStopLabel.textContent = 'ZASTAVÍME';
        } else {
            nextStopBar.classList.remove('stop-requested');
            if (data.isTerminus) {
                nextStopLabel.textContent = 'KONEČNÁ';
            } else {
                nextStopLabel.textContent = 'PŘÍŠTÍ ZASTÁVKA';
            }
        }

        // At-stop overlay logic
        if (data.atStop && !prevAtStop && data.previousStopName) {
            showAtStopOverlay(data.previousStopName);
        }
        prevAtStop = !!data.atStop;

        // Check for Zone Change
        if (data.stops && data.stops.length > 0) {
            const currentNextStop = data.stops[0].name;
            if (currentNextStop !== lastNextStopName) {
                lastNextStopName = currentNextStop;
                if (data.prevPID || data.prevIDOL || data.prevDUK) {
                    checkZoneChange(data);
                }
            }
        }

        // Terminus state
        if (data.isTerminus) {
            renderTerminus(data);
            return;
        }

        stopsPanel.classList.remove('terminus');
        // Label is handled in STOP Request Logic block above

        // Update next stop footer name
        var nextStop = data.nextStop || (data.stops && data.stops.length > 0 ? getStopName(data.stops[0]) : '---');
        nextStopName.textContent = nextStop;

        if (!data.stops || data.stops.length === 0) {
            stopList.innerHTML = '';
            pageIndicator.innerHTML = '';
            return;
        }

        renderStopList(data.stops);
    }

    function resetDisplay() {
        lineBadge.textContent = '--';
        destination.innerHTML = '<span>---</span>';
        nextStopName.textContent = '---';
        nextStopLabel.textContent = 'PŘÍŠTÍ ZASTÁVKA';
        nextStopBar.classList.remove('stop-requested');
        stopList.innerHTML = '';
        pageIndicator.innerHTML = '';
        stopsPanel.classList.remove('terminus');
        hideAtStopOverlay();
        if (zoneNotification) zoneNotification.classList.remove('visible');
    }

    function renderTerminus(data) {
        stopsPanel.classList.add('terminus');
        // Label handled in updateStops
        nextStopName.textContent = data.destination || 'Konečná';
        stopList.innerHTML = '';
        pageIndicator.innerHTML = '';
        hideAtStopOverlay();
        if (zoneNotification) zoneNotification.classList.remove('visible');

        const msg = document.createElement('div');
        msg.className = 'terminus-message';
        msg.innerHTML = '<div class="terminus-icon">&#9632;</div>' +
            '<div class="terminus-text">KONEČNÁ</div>' +
            '<div class="terminus-subtext">Prosím vystupte</div>';
        stopList.appendChild(msg);
    }

    function renderStopList(stops) {
        const visibleStopsList = stops.slice(0, VISIBLE_STOPS);

        stopList.innerHTML = '';
        pageIndicator.innerHTML = '';

        for (let i = 0; i < visibleStopsList.length; i++) {
            const stopData = visibleStopsList[i];
            const name = getStopName(stopData);
            const reqStop = isRequestStop(stopData);
            const zones = getFormattedZones(stopData);

            const row = document.createElement('div');
            row.className = 'stop-row';

            if (i === 0) {
                row.classList.add('current');
            } else {
                row.classList.add('future');
            }

            const marker = document.createElement('div');
            marker.className = 'stop-marker';

            const nameEl = document.createElement('div');
            nameEl.className = 'stop-name';
            nameEl.textContent = name;

            row.appendChild(marker);
            row.appendChild(nameEl);

            if (reqStop || zones.length > 0) {
                const rightSide = document.createElement('div');
                rightSide.className = 'stop-row-right';

                if (zones.length > 0) {
                    for (let z = 0; z < zones.length; z++) {
                        const badge = document.createElement('span');
                        badge.className = 'zone-badge';
                        badge.textContent = zones[z];
                        rightSide.appendChild(badge);
                    }
                }

                if (reqStop) {
                    const bell = document.createElement('span');
                    bell.className = 'request-stop-bell';
                    bell.textContent = '\uD83D\uDD14'; 
                    rightSide.appendChild(bell);
                }

                row.appendChild(rightSide);
            }

            stopList.appendChild(row);
        }
    }

    // ===== Ad Rotation =====

    function setAdFiles(files) {
        adFiles = files || [];
        currentAdIndex = 0;

        if (adFiles.length === 0) {
            noDataEl.style.display = 'flex';
            clearAdContent();
            return;
        }

        noDataEl.style.display = 'none';
        showCurrentAd();
    }

    function clearAdContent() {
        const items = adsPanel.querySelectorAll('.ad-item');
        items.forEach(item => item.remove());

        if (adVideoElement) {
            adVideoElement.pause();
            adVideoElement = null;
        }

        if (adTimer) {
            clearTimeout(adTimer);
            adTimer = null;
        }
    }

    function showCurrentAd() {
        if (adFiles.length === 0) return;

        clearAdContent();

        const file = adFiles[currentAdIndex];
        const ext = file.split('.').pop().toLowerCase();
        const isVideo = ['webm', 'ogg'].includes(ext);

        const adItem = document.createElement('div');
        adItem.className = 'ad-item';

        if (isVideo) {
            const video = document.createElement('video');
            video.src = file;
            video.muted = true;
            video.autoplay = true;
            video.playsInline = true;
            video.onended = function () {
                advanceAd();
            };
            video.onerror = function () {
                adTimer = setTimeout(advanceAd, 2000);
            };
            adItem.appendChild(video);
            adVideoElement = video;
        } else {
            const img = document.createElement('img');
            img.src = file;
            img.onerror = function () {
                adTimer = setTimeout(advanceAd, 2000);
            };
            adItem.appendChild(img);
            adTimer = setTimeout(advanceAd, AD_IMAGE_DURATION);
        }

        adsPanel.appendChild(adItem);

        requestAnimationFrame(() => {
            adItem.classList.add('active');
        });
    }

    function advanceAd() {
        if (adFiles.length === 0) return;
        currentAdIndex = (currentAdIndex + 1) % adFiles.length;
        showCurrentAd();
    }

    // ===== API for CefSharp =====
    
    window.lcdUpdateStops = function (jsonString) {
        try {
            const data = typeof jsonString === 'string' ? JSON.parse(jsonString) : jsonString;
            updateStops(data);
        } catch (e) {
            console.error('Failed to parse stop data:', e);
        }
    };

    window.lcdSetAds = function (fileListJson) {
        try {
            const files = typeof fileListJson === 'string' ? JSON.parse(fileListJson) : fileListJson;
            setAdFiles(files);
        } catch (e) {
            console.error('Failed to parse ad list:', e);
        }
    };

    // Mock data for browser testing...
    if (typeof CefSharp === 'undefined') {
        const mockStops = [
            { name: "Česká Lípa, Borská", requestStop: true, zonePID: "", zoneIDOL: "", zoneDUK: "2001" },
            { name: "Česká Lípa, Lada", requestStop: true, zonePID: "", zoneIDOL: "", zoneDUK: "2001" },
            { name: "Česká Lípa, Holý vrch", requestStop: false, zonePID: "", zoneIDOL: "101", zoneDUK: "2001" },
            { name: "Sloup v Čechách", requestStop: false, zonePID: "P3", zoneIDOL: "102", zoneDUK: "" },
            { name: "Nový Bor, náměstí", requestStop: false, zonePID: "P3", zoneIDOL: "102", zoneDUK: "2002" },
            { name: "Nový Bor, nemocnice", requestStop: true, zonePID: "P3", zoneIDOL: "", zoneDUK: "2002" },
            { name: "Nový Bor, aut.nádraží", requestStop: false, zonePID: "", zoneIDOL: "", zoneDUK: "" },
            { name: "Cvikov, aut.st.", requestStop: false, zonePID: "", zoneIDOL: "201", zoneDUK: "" },
            { name: "Jablonné v Podještědí", requestStop: false, zonePID: "", zoneIDOL: "202", zoneDUK: "" },
            { name: "Rynoltice", requestStop: true, zonePID: "", zoneIDOL: "203", zoneDUK: "" }
        ];

        const mockData = {
            stops: mockStops.slice(),
            line: "240",
            destination: "Liberec, aut.nádraží - Mock Text",
            nextStop: "Česká Lípa, Borská",
            isTerminus: false,
            atStop: false,
            previousStopName: "",
            prevPID: "1",
            prevIDOL: "100",
            prevDUK: "",
            time: "14:30",
            delay: 2.5,
            stopRequest: false
        };

        updateStops(mockData);

        // Simulation
        let mockTick = 0;
        setInterval(() => {
            mockTick++;
            if (mockTick % 3 === 0) mockData.stopRequest = !mockData.stopRequest;
            updateStops(mockData);
        }, 3000);
    }
})();