/**
 * VideoKonverter TV - Focus-Manager und Navigation
 * D-Pad Navigation fuer TV-Fernbedienungen (Samsung Tizen, Android TV)
 * + Lazy-Loading fuer Poster-Bilder
 */

// === Focus-Manager ===

class FocusManager {
    constructor() {
        this._enabled = true;
        this._currentFocus = null;
        // Merkt sich das letzte fokussierte Element im Content-Bereich
        this._lastContentFocus = null;
        // SELECT-Editier-Modus: erst Enter druecken, dann Hoch/Runter aendert Werte
        this._selectActive = false;
        // INPUT/TEXTAREA Editier-Modus: erst Enter druecken, dann tippen
        this._inputActive = false;

        // Tastatur-Events abfangen
        document.addEventListener("keydown", (e) => this._onKeyDown(e));

        // Focus-Tracking: merken wo wir zuletzt waren
        document.addEventListener("focusin", (e) => {
            // SELECT-Editier-Modus beenden wenn Focus sich aendert
            if (this._selectActive && e.target && e.target.tagName !== "SELECT") {
                this._selectActive = false;
                document.querySelectorAll(".select-editing").forEach(
                    el => el.classList.remove("select-editing"));
            }
            // INPUT-Editier-Modus beenden wenn Focus sich aendert
            if (this._inputActive && e.target &&
                e.target.tagName !== "INPUT" && e.target.tagName !== "TEXTAREA") {
                this._inputActive = false;
                document.querySelectorAll(".input-editing").forEach(
                    el => el.classList.remove("input-editing"));
            }
            if (e.target && e.target.hasAttribute && e.target.hasAttribute("data-focusable")) {
                if (!e.target.closest("#tv-nav")) {
                    // Nur echte Content-Elemente merken (nicht Filter/Controls)
                    if (e.target.closest(".tv-grid, .tv-list-compact, .tv-detail-list, .tv-folder-view, .tv-row, .tv-episode-list, .tv-episode-grid, .tv-tabs, .tv-detail-actions, .tv-alpha-sidebar, .tv-view-switch, .tv-filter-bar, .tv-season-actions, .profiles-grid")) {
                        this._lastContentFocus = e.target;
                    }
                }
            }
        });

        // Initiales Focus-Element setzen
        requestAnimationFrame(() => this._initFocus());
    }

    _initFocus() {
        // Erstes fokussierbares Element finden (nicht autofocus Inputs)
        const autofocusEl = document.querySelector("[autofocus]");
        if (autofocusEl) {
            autofocusEl.focus();
            return;
        }
        // Erstes Element im sichtbaren Content-Bereich (Karten bevorzugen)
        const contentAreas = document.querySelectorAll(
            ".tv-grid, .tv-list-compact, .tv-detail-list, .tv-folder-view, .tv-row, .tv-episode-list, .tv-episode-grid, .tv-tabs, .tv-detail-actions, .tv-alpha-sidebar, .tv-view-switch, .tv-filter-bar, .tv-season-actions, .profiles-grid"
        );
        for (const area of contentAreas) {
            if (!area.offsetHeight) continue;
            const firstEl = area.querySelector("[data-focusable]");
            if (firstEl) {
                firstEl.focus();
                return;
            }
        }
        // Fallback: erstes Content-Element
        const contentFirst = document.querySelector(".tv-main [data-focusable]");
        if (contentFirst) {
            contentFirst.focus();
            return;
        }
        const first = document.querySelector("[data-focusable]");
        if (first) first.focus();
    }

    _onKeyDown(e) {
        if (!this._enabled) return;

        // Samsung Tizen Remote Key-Codes mappen
        const keyMap = {
            37: "ArrowLeft", 38: "ArrowUp", 39: "ArrowRight", 40: "ArrowDown",
            13: "Enter", 27: "Escape", 8: "Backspace",
            // Samsung Tizen spezifisch
            10009: "Escape",   // RETURN-Taste
            10182: "Escape",   // EXIT-Taste
        };
        const key = keyMap[e.keyCode] || e.key;

        switch (key) {
            case "ArrowUp":
            case "ArrowDown":
            case "ArrowLeft":
            case "ArrowRight":
                this._navigate(key, e);
                break;
            case "Enter":
                this._activate(e);
                break;
            case "Escape":
            case "Backspace":
                this._goBack(e);
                break;
        }
    }

    _navigate(direction, e) {
        const active = document.activeElement;

        // Input-Felder: Nur im Editier-Modus Cursor-Navigation erlauben
        if (active && (active.tagName === "INPUT" || active.tagName === "TEXTAREA")) {
            if (active.type === "checkbox") {
                // Checkbox: normal navigieren
            } else if (this._inputActive) {
                // Editier-Modus: Links/Rechts fuer Cursor, Hoch/Runter navigiert weg
                if (direction === "ArrowLeft" || direction === "ArrowRight") return;
            }
            // Nicht aktiv: alle Richtungen navigieren weiter
        }

        // Select-Elemente: Nur wenn aktiviert (Enter gedrueckt) Hoch/Runter aendert Wert
        if (active && active.tagName === "SELECT") {
            if (this._selectActive) {
                // Editier-Modus: Wert manuell aendern (synthetische Events aendern SELECT nicht)
                if (direction === "ArrowUp" || direction === "ArrowDown") {
                    const idx = active.selectedIndex;
                    if (direction === "ArrowDown" && idx < active.options.length - 1) {
                        active.selectedIndex = idx + 1;
                    } else if (direction === "ArrowUp" && idx > 0) {
                        active.selectedIndex = idx - 1;
                    }
                    e.preventDefault();
                    return;
                }
            } else {
                // Nicht im Editier-Modus: Navigation statt Wert-Aenderung
                if (direction === "ArrowUp" || direction === "ArrowDown") {
                    e.preventDefault();
                }
            }
        }

        const focusables = this._getFocusableElements();
        if (!focusables.length) return;

        // Aktuelles Element
        const currentIdx = focusables.indexOf(active);
        if (currentIdx === -1) {
            // Kein fokussiertes Element -> erstes waehlen
            focusables[0].focus();
            e.preventDefault();
            return;
        }

        // Navigation innerhalb der Nav-Bar: Links/Rechts = sequentiell
        const inNav = active.closest("#tv-nav");
        if (inNav && (direction === "ArrowLeft" || direction === "ArrowRight")) {
            // Alle Nav-Elemente sequentiell (links + rechts zusammen)
            const navEls = focusables.filter(el => el.closest("#tv-nav"));
            const navIdx = navEls.indexOf(active);
            if (navIdx !== -1) {
                const nextIdx = direction === "ArrowRight" ? navIdx + 1 : navIdx - 1;
                if (nextIdx >= 0 && nextIdx < navEls.length) {
                    navEls[nextIdx].focus();
                    e.preventDefault();
                    return;
                }
            }
        }

        // Von Nav nach unten -> direkt zu Content-Karten (Filter/View-Switch ueberspringen)
        if (inNav && direction === "ArrowDown") {
            // Gespeicherten Content-Focus bevorzugen (nur wenn noch sichtbar)
            if (this._lastContentFocus && document.contains(this._lastContentFocus)
                && this._lastContentFocus.offsetHeight > 0) {
                this._lastContentFocus.focus();
                this._lastContentFocus.scrollIntoView({ block: "nearest", behavior: "smooth" });
                e.preventDefault();
                return;
            }
            // Direkt zum sichtbaren Content-Bereich (Karten/Listen-Eintraege)
            const contentAreas = document.querySelectorAll(
                ".tv-grid, .tv-list-compact, .tv-detail-list, .tv-folder-view, .tv-row, .tv-episode-list, .tv-episode-grid, .tv-tabs, .tv-detail-actions, .tv-alpha-sidebar, .tv-view-switch, .tv-filter-bar, .tv-season-actions, .profiles-grid"
            );
            for (const area of contentAreas) {
                if (!area.offsetHeight) continue;
                const firstEl = area.querySelector("[data-focusable]");
                if (firstEl) {
                    firstEl.focus();
                    firstEl.scrollIntoView({ block: "nearest", behavior: "smooth" });
                    e.preventDefault();
                    return;
                }
            }
            // Fallback: erstes Content-Element
            const contentFirst = document.querySelector(".tv-main [data-focusable]");
            if (contentFirst) {
                contentFirst.focus();
                contentFirst.scrollIntoView({ block: "nearest", behavior: "smooth" });
                e.preventDefault();
                return;
            }
        }

        // Vom Content nach oben zur Nav springen wenn am oberen Rand
        if (!inNav && direction === "ArrowUp") {
            const current = active.getBoundingClientRect();
            // Nur wenn Element nah am oberen Rand ist (< 200px vom Viewport-Top)
            if (current.top < 200) {
                // Pruefen ob es noch ein Element darueber im Content gibt
                const contentEls = focusables.filter(el => !el.closest("#tv-nav"));
                const above = contentEls.filter(el => {
                    const r = el.getBoundingClientRect();
                    return r.top + r.height / 2 < current.top - 5;
                });
                if (above.length === 0) {
                    // Kein Element darueber -> zur Nav springen
                    const activeNavItem = document.querySelector(".tv-nav-item.active");
                    if (activeNavItem) {
                        activeNavItem.focus();
                        e.preventDefault();
                        return;
                    }
                }
            }
        }

        // Naechstes Element in Richtung finden (Nearest-Neighbor)
        const currentRect = active.getBoundingClientRect();
        const cx = currentRect.left + currentRect.width / 2;
        const cy = currentRect.top + currentRect.height / 2;

        let bestEl = null;
        let bestDist = Infinity;

        // Nur Elemente im gleichen Bereich (Nav oder Content) bevorzugen
        const searchEls = inNav
            ? focusables.filter(el => el.closest("#tv-nav"))
            : focusables.filter(el => !el.closest("#tv-nav"));

        for (const el of searchEls) {
            if (el === active) continue;
            const rect = el.getBoundingClientRect();
            if (rect.width === 0 || rect.height === 0) continue;

            const ex = rect.left + rect.width / 2;
            const ey = rect.top + rect.height / 2;

            const dx = ex - cx;
            const dy = ey - cy;

            let valid = false;
            switch (direction) {
                case "ArrowUp":    valid = dy < -5; break;
                case "ArrowDown":  valid = dy > 5; break;
                case "ArrowLeft":  valid = dx < -5; break;
                case "ArrowRight": valid = dx > 5; break;
            }
            if (!valid) continue;

            let dist;
            if (direction === "ArrowUp" || direction === "ArrowDown") {
                dist = Math.abs(dy) + Math.abs(dx) * 3;
            } else {
                dist = Math.abs(dx) + Math.abs(dy) * 3;
            }

            if (dist < bestDist) {
                bestDist = dist;
                bestEl = el;
            }
        }

        if (bestEl) {
            bestEl.focus();
            bestEl.scrollIntoView({ block: "nearest", inline: "nearest", behavior: "smooth" });
            e.preventDefault();
        }
    }

    _activate(e) {
        const active = document.activeElement;
        if (!active || active === document.body) return;

        // Links, Buttons -> Click ausfuehren (natuerliches Enter-Verhalten)
        if (active.tagName === "A" || active.tagName === "BUTTON") {
            return;
        }

        // Select: Enter aktiviert/deaktiviert den Editier-Modus
        if (active.tagName === "SELECT") {
            if (this._selectActive) {
                // Wert bestaetigen, Editier-Modus beenden
                this._selectActive = false;
                active.classList.remove("select-editing");
                // onchange ausloesen falls sich Wert geaendert hat
                active.dispatchEvent(new Event("change", { bubbles: true }));
            } else {
                // Editier-Modus starten
                this._selectActive = true;
                active.classList.add("select-editing");
            }
            e.preventDefault();
            return;
        }

        // Input/Textarea: Enter aktiviert/deaktiviert Editier-Modus
        if ((active.tagName === "INPUT" && active.type !== "checkbox") ||
            active.tagName === "TEXTAREA") {
            if (this._inputActive) {
                // Editier-Modus beenden
                this._inputActive = false;
                active.classList.remove("input-editing");
            } else {
                // Editier-Modus starten
                this._inputActive = true;
                active.classList.add("input-editing");
            }
            e.preventDefault();
            return;
        }

        // Checkbox: Toggle
        if (active.tagName === "INPUT" && active.type === "checkbox") {
            active.checked = !active.checked;
            active.dispatchEvent(new Event("change", { bubbles: true }));
            e.preventDefault();
            return;
        }

        // Andere fokussierbare Elemente -> Click simulieren
        if (active.hasAttribute("data-focusable")) {
            active.click();
            e.preventDefault();
        }
    }

    _goBack(e) {
        const active = document.activeElement;

        // In Input-Feldern: Escape = Editier-Modus beenden oder Blur
        if (active && (active.tagName === "INPUT" || active.tagName === "TEXTAREA")) {
            if (this._inputActive) {
                // Editier-Modus beenden, Focus bleibt
                this._inputActive = false;
                active.classList.remove("input-editing");
            } else {
                // Nicht im Editier-Modus: Focus verlassen
                active.blur();
            }
            e.preventDefault();
            return;
        }

        // In Select-Feldern: Escape = Editier-Modus beenden oder Blur
        if (active && active.tagName === "SELECT") {
            if (this._selectActive) {
                // Editier-Modus beenden (Wert nicht uebernehmen)
                this._selectActive = false;
                active.classList.remove("select-editing");
            } else {
                // Nicht im Editier-Modus -> Focus verlassen
                active.blur();
            }
            e.preventDefault();
            return;
        }

        // Wenn Focus in der Nav: nicht zurueck navigieren
        if (active && active.closest && active.closest("#tv-nav")) {
            // Focus zurueck zum Content verschieben
            if (this._lastContentFocus && document.contains(this._lastContentFocus)) {
                this._lastContentFocus.focus();
            }
            e.preventDefault();
            return;
        }

        // Wenn ein Player-Overlay offen ist, zuerst das schliessen
        const overlay = document.querySelector(".player-overlay.visible, .player-next-overlay.visible");
        if (overlay) {
            overlay.classList.remove("visible");
            e.preventDefault();
            return;
        }

        // Zurueck navigieren
        if (window.history.length > 1) {
            window.history.back();
            e.preventDefault();
        }
    }

    _getFocusableElements() {
        const elements = document.querySelectorAll("[data-focusable]");
        return Array.from(elements).filter(el => {
            if (el.offsetParent === null && el.style.position !== "fixed") return false;
            const rect = el.getBoundingClientRect();
            return rect.width > 0 && rect.height > 0;
        });
    }
}

// === Horizontale Scroll-Reihen: Scroll per Pfeiltaste ===

function initRowScroll() {
    document.querySelectorAll(".tv-row").forEach(row => {
        // Maus-Rad horizontal scrollen
        row.addEventListener("wheel", (e) => {
            if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
                e.preventDefault();
                row.scrollLeft += e.deltaY;
            }
        }, { passive: false });
    });
}

// === Lazy-Loading fuer Poster (IntersectionObserver) ===

function initLazyLoad() {
    // Browser-natives loading="lazy" wird bereits verwendet
    // Zusaetzlich: Placeholder-Klasse entfernen nach Laden
    document.querySelectorAll("img.tv-card-img").forEach(img => {
        if (img.complete) return;
        img.style.opacity = "0";
        img.style.transition = "opacity 0.3s";
        img.addEventListener("load", () => {
            img.style.opacity = "1";
        }, { once: true });
        img.addEventListener("error", () => {
            // Fehlerhaftes Bild: Placeholder anzeigen
            img.style.display = "none";
            const placeholder = document.createElement("div");
            placeholder.className = "tv-card-placeholder";
            placeholder.textContent = img.alt || "?";
            img.parentNode.insertBefore(placeholder, img);
        }, { once: true });
    });
}

// === Navigation: Aktiven Tab highlighten ===

function initNavHighlight() {
    const path = window.location.pathname;
    document.querySelectorAll(".tv-nav-item").forEach(item => {
        const href = item.getAttribute("href");
        if (href === path || (href !== "/tv/" && path.startsWith(href))) {
            item.classList.add("active");
        }
    });
}

// === Init ===

document.addEventListener("DOMContentLoaded", () => {
    window.focusManager = new FocusManager();
    initRowScroll();
    initLazyLoad();
    initNavHighlight();
});
