import { t, setLanguage, currentLang } from './i18n.js';
import { Assets, Sprite, NineSliceSprite, Container, TilingSprite, Text, wordWrap, fragmentGPUTemplate, Graphics, mapFormatToGlFormat } from 'pixi.js';
import { loginUser, registerUser, verifyEmailUser, resendOTPCode, requestPasswordResetUser, resetPasswordUser, refreshAccessTokenUser } from './api/auth.js';
import { initDropdowns, updateTranslations } from './ui/dropdowns.js';
import { initForms, formState, setOtpMode, setResetPasswordMode, startVisualCountdown, setRegisterMode } from './ui/forms.js';
import { fetchSectorsList, joinSectorUser } from './api/sectors.js';
import { app, initPixi, setupResize, triggerResize } from './core/pixi-app.js';
import { buildLoginScene, LOGIN_COLORS } from './scenes/login-scene.js';
import { buildLobbyBase, createSectorTabPixi, createSectorCardPixi, buildOnboardingModalPixi } from './scenes/lobby-scene.js';

let globalSheet = null;
let background = null;
let uiContainer = null;
let lobbyPixiContainer = null;
let sectorPixiContainer = null;
let sectorTabsPixiContainer = null;
let footerBackground = null;
let footerPattern = null;
let footerBackgroundContainer = null;
let onboardingPixiContainer = null;
let onboardingPixiRefs = null;
let selectedSectorId = null;
let selectedOnboardingGender = 'male';
let sectorPollingInterval = null;

async function initGame() {
    await initPixi('pixi-container');

    try {
        const assetsToLoad = {
            background: 'src/raw-assets/backgrounds/Background_A.png',
            uiAtlas: 'src/assets/ui-atlas.json' 
        };
        const backgroundTexture = await Assets.load(assetsToLoad.background);
        const uiSpritesheet = await Assets.load(assetsToLoad.uiAtlas);

        await document.fonts.load('16px "UI Font"');
        await document.fonts.load('16px "Logo Font"');

        updateTranslations();

        buildScene(backgroundTexture, uiSpritesheet);

        document.getElementById('username').placeholder = t('ph_username_reg');
        document.getElementById('email').placeholder = t('ph_email');
        document.getElementById('password').placeholder = t('ph_password');
        document.getElementById('btn-register').textContent = t('btn_register');

        await checkAuthOnStartup();

    } catch (error) {
        console.error("Fehler beim Laden der Assets:", error);
    }
}

function buildScene(bgTexture, sheet) {
    globalSheet = sheet;

    // --- Hintergrund ---
    background = new Sprite(bgTexture);
    app.stage.addChild(background);

    // --- Haupt-UI-Container ---
    uiContainer = new Container();
    app.stage.addChild(uiContainer);

    lobbyPixiContainer = new Container();
    lobbyPixiContainer.visible = false;
    app.stage.addChild(lobbyPixiContainer);

    sectorPixiContainer = buildLobbyBase(lobbyPixiContainer, sheet);

    const htmlSectorList = document.getElementById('sector-list-container');
    if (htmlSectorList) {
        htmlSectorList.addEventListener('scroll', (e) => {
            sectorPixiContainer.y = -e.target.scrollTop;
        });
    }

    // --- Footer Hintergund ---
    footerBackgroundContainer = new Container();

    footerBackground = new TilingSprite({
        texture: sheet.textures['SPR_SciFiMenus_Background_01'],
        height: 40,
    });
    footerBackground.tileScale.set(1.0);
    footerBackground.tint = 0x000000;
    footerBackground.alpha = 1.0;
    footerBackgroundContainer.addChild(footerBackground);

    footerPattern = new TilingSprite({
        texture: sheet.textures['SPR_SciFiMenus_Background_Hexagons_01'],
        height: 40,
    });
    footerPattern.tileScale.set(0.3);
    footerPattern.tint = LOGIN_COLORS.PATTERN;
    footerPattern.alpha = 0.01;
    footerBackgroundContainer.addChild(footerPattern);

    app.stage.addChild(footerBackgroundContainer);

    onboardingPixiRefs = buildOnboardingModalPixi(app.stage, sheet);
    onboardingPixiContainer = onboardingPixiRefs.container;

    const loginRefs = buildLoginScene(uiContainer, sheet);

    initForms({
        tabLogin: loginRefs.tabLogin, 
        tabRegister: loginRefs.tabRegister, 
        inputUser: loginRefs.inputUser, 
        inputEmail: loginRefs.inputEmail, 
        inputLock: loginRefs.inputLock, 
        btnRegister: loginRefs.btnRegister,
        discordIcon: loginRefs.discordIcon, 
        discordText: loginRefs.discordText,
        COLOR_TAB_ACTIVE: LOGIN_COLORS.TAB_ACTIVE, 
        COLOR_TAB_INACTIVE: LOGIN_COLORS.TAB_INACTIVE, 
        COLOR_TAB_HOVER: LOGIN_COLORS.TAB_HOVER, 
        COLOR_BTN_HOVER: LOGIN_COLORS.BTN_HOVER, 
        COLOR_BTN_DEFAULT: LOGIN_COLORS.BTN_DEFAULT
    });

    setupResize({
        background, 
        discordContainer: loginRefs.discordContainer, 
        logoContainer: loginRefs.logoContainer, 
        uiContainer, 
        panelFrame: loginRefs.panelFrame, 
        lobbyPixiContainer, 
        footerBackground, 
        footerPattern, 
        footerBackgroundContainer,
        onboardingPixiContainer 
    });

    formState.isLoginMode = true;
    setRegisterMode();
}

const form = document.getElementById('register-form');
const msgBox = document.getElementById('msg-box');

form.addEventListener('submit', async (e) => {
    e.preventDefault();

    const usernameVal = document.getElementById('username').value;
    const emailVal = document.getElementById('email').value;
    const passwordVal = document.getElementById('password').value;

    msgBox.textContent = '...';
    msgBox.style.color = 'var(--color-text-main)';

    if (formState.isForgotPasswordMode) {
        try {
            const result = await requestPasswordResetUser(emailVal);
            if (!result.ok) {
                msgBox.style.color = 'var(--color-error)';
                msgBox.textContent = t(result.data.error) || t('ERR_INTERNAL_SERVER');
                return;
            }

            msgBox.style.color = 'var(--color-green-bright)';
            msgBox.textContent = t(result.data.message);

            setTimeout(() => {
                setResetPasswordMode(emailVal);
            }, 1500);

        } catch (error) {
            msgBox.style.color = 'var(--color-error)';
            msgBox.textContent = t('ERR_INTERNAL_SERVER');
        }
        return;
    }

    if (formState.isResetPasswordMode) {
        try {
            const result = await resetPasswordUser(formState.resetEmail, emailVal, passwordVal);
            if (!result.ok) {
                msgBox.style.color = 'var(--color-error)';
                msgBox.textContent = t(result.data.error) || t('ERR_INTERNAL_SERVER');
                return;
            }

            msgBox.style.color = 'var(--color-green-bright)';
            msgBox.textContent = t(result.data.message);

            setTimeout(() => {
                window.location.reload();
            }, 1500);

        } catch (error) {
            msgBox.style.color = 'var(--color-error)';
            msgBox.textContent = t('ERR_INTERNAL_SERVER');
        }
        return;
    }

    if (formState.isOtpMode) {
        try {
            const result = await verifyEmailUser(formState.pendingVerificationEmail, passwordVal);
            if (!result.ok) {
                msgBox.style.color = 'var(--color-error)';
                msgBox.textContent = t(result.data.error) || t('ERR_INTERNAL_SERVER');
                return;
            }

            msgBox.style.color = 'var(--color-green-bright)';
            msgBox.textContent = t('msg_verify_success');

            setTimeout(() => {
                window.location.reload();
            }, 1500);

        } catch (error) {
            msgBox.style.color = 'var(--color-error)';
            msgBox.textContent = t('ERR_INTERNAL_SERVER');
        }
        return;
    }

    if (formState.isLoginMode) {
        try {
            const result = await loginUser(usernameVal, passwordVal);

            if (!result.ok) {
                msgBox.style.color = 'var(--color-error)';
                msgBox.textContent = t(result.data.error) || t('ERR_INTERNAL_SERVER');

                if (result.data.error === 'ERR_EMAIL_NOT_VERIFIED') {
                    setTimeout(() => {
                        setOtpMode(result.data.email);
                    }, 1500);
                }
                return;
            }

            msgBox.style.color = 'var(--color-green-bright)';
            msgBox.textContent = t(result.data.message);

            const rememberMe = document.getElementById('remember').checked;
            sessionStorage.setItem('void_access_token', result.data.accessToken);
            sessionStorage.setItem('void_user', JSON.stringify(result.data.user));

            if (rememberMe) {
                localStorage.setItem('void_refresh_token', result.data.refreshToken);
                sessionStorage.removeItem('void_refresh_token');
            } else {
                sessionStorage.setItem('void_refresh_token', result.data.refreshToken);
                localStorage.removeItem('void_refresh_token');
            }
            transitionToLobby();

        } catch (error) {
            msgBox.style.color = 'var(--color-error)';
            msgBox.textContent = t('ERR_INTERNAL_SERVER');
        }
    } else { // Register Mode
        try {
            const result = await registerUser(usernameVal, emailVal, passwordVal);

            if (!result.ok) {
                msgBox.style.color = 'var(--color-error)';
                msgBox.textContent = t(result.data.error)|| t('ERR_INTERNAL_SERVER');
                return;
            }

            msgBox.style.color = 'var(--color-green-bright)';
            msgBox.textContent = t(result.data.message);

            setTimeout(() => {
                setOtpMode(emailVal);
            }, 1500);

        } catch (error) {
            msgBox.style.color = 'var(--color-error)';
            msgBox.textContent = t('ERR_INTERNAL_SERVER');
        }
    }
});

const resendOtpLink = document.getElementById('resend-otp-link');
if (resendOtpLink) {
    resendOtpLink.addEventListener('click', async (e) => {
        e.preventDefault();

        if (!pendingVerificationEmail) return;

        msgBox.textContent = '...';
        msgBox.style.color = 'var(--color-text-main)';

        try {
            const result = await resendOTPCode(pendingVerificationEmail);
            if (!result.ok) {
                msgBox.style.color = 'var(--color-error)';
                msgBox.textContent = t(result.data.error) || t('ERR_INTERNAL_SERVER');
                return;
            }

            msgBox.style.color = 'var(--color-green-bright)';
            msgBox.textContent = t(result.data.message);
            startVisualCountdown(resendOtpLink, 'link_resend_otp', 120);
        } catch (error) {
            msgBox.style.color = 'var(--color-error)';
            msgBox.textContent = t('ERR_INTERNAL_SERVER');
        }
    });
}

/**
 * Diese Funktion wird aufgerufenm wenn der Login erfolgreich war und die Tokens
 * sicher gespeichert sind, Sie baut das HTML-Formulat ab und bereitet PixiJS
 * auf die Lobby-Ansicht vor
 */
async function transitionToLobby() {
    const formElement = document.getElementById('register-form');
    if (formElement) {
        formElement.style.display = 'none';
    }

    uiContainer.visible = false;
    lobbyPixiContainer.visible = true;

    try {
        const lobbyBGPath = 'src/raw-assets/backgrounds/SPR_SciFiMenus_Example_Image_SpookyComputer_01.png';
        const lobbyBGTexture = await Assets.load(lobbyBGPath);
        background.texture = lobbyBGTexture;
        triggerResize();
        buildLobbyUI();
    } catch (error) {
        console.error("Fehler beim Laden des Lobby-Hintergrunds:", error);
    }
}

/**
 * Blendet die Top-Bar ein, setzt den Spilernamen und aktiviert den Logout
 */
async function buildLobbyUI() {
    const userDropdown = document.getElementById('user-dropdown');
    if (userDropdown) {
        userDropdown.style.display = 'block';
    }

    const userDataStr = sessionStorage.getItem('void_user');
    if (userDataStr) {
        try {
            const userData = JSON.parse(userDataStr);
            const usernameEl = document.getElementById('lobby-username');
            if (usernameEl && userData.username) {
                usernameEl.textContent = userData.username;
            }
            
            const emailEl = document.getElementById('lobby-email');
            if (emailEl && userData.email) {
                emailEl.textContent = userData.email;
            } 

            const premiumEl = document.getElementById('lobby-premium');
            if (premiumEl && userData.res_premium !== undefined) {
                premiumEl.textContent = userData.res_premium;
            }
        } catch (e) {
            console.error("Fehler beim Auslesen der User-Daten:", e);
        }
    }

    await loadAndRenderSectorBrowser();
}

/**
 * Läd die Sektordaten von der API und steuert die Tab-Sichtbarkeiten
 */
async function loadAndRenderSectorBrowser() {
    const token = sessionStorage.getItem('void_access_token') || localStorage.getItem('void_access_token');
    if (!token) return;

    try {
        const result = await fetchSectorsList();
        if (!result.ok || !result.data.success) {
            console.error("Fehler beim Laden der Sektoren:", result.data.error);
            return;
        }

        const data = result.data;
        const layer = document.getElementById('sector-browser-layer');
        layer.style.display = 'block';

        const tabLastSector = document.getElementById('tab-last-sector');
        const tabMySectors = document.getElementById('tab-my-sectors');
        const tabNewSectors = document.getElementById('tab-new-sectors');

        if (sectorTabsPixiContainer) {
            lobbyPixiContainer.removeChild(sectorTabsPixiContainer);
            sectorTabsPixiContainer.destroy({ children: true });
        }
        sectorTabsPixiContainer = new Container();
        lobbyPixiContainer.addChild(sectorTabsPixiContainer);

        const isMobilePortrait = window.innerWidth <= 800 && window.innerHeight > window.innerWidth;
        const centerPos = isMobilePortrait ? 325 : 620;

        if (data.mySectors.length === 0) {
            // Szenario A: Keine eigenen Sektoren
            tabLastSector.style.display = 'none';
            tabMySectors.style.display = 'none';
            tabNewSectors.classList.add('active');

            const singleTabX = centerPos - 90;
            const tabNewBg = createSectorTabPixi(globalSheet, singleTabX, 20, LOGIN_COLORS.TAB_ACTIVE, 0.6);
            sectorTabsPixiContainer.addChild(tabNewBg.container); 
            renderSectorList(data.newSectors, 'new');

        } else {
            // Szenario B: Eigene Sektoren vorhanden
            tabLastSector.style.display = 'inline-block';
            tabMySectors.style.display = 'inline-block';
            tabNewSectors.style.display = 'inline-block';

            const lastPlayedSectorArray = [data.mySectors[0]];
            const otherMySectorsArray = data.mySectors.slice(1);

            const leftTabX = centerPos - 290;
            const midTabX = centerPos - 90;
            const rightTabX = centerPos + 110;

            const tabLastBg = createSectorTabPixi(globalSheet, leftTabX, 20, LOGIN_COLORS.TAB_ACTIVE, 0.6);
            const tabMyBg = createSectorTabPixi(globalSheet, midTabX, 20, LOGIN_COLORS.TAB_INACTIVE, 0.4);
            const tabNewBg = createSectorTabPixi(globalSheet, rightTabX, 20, LOGIN_COLORS.TAB_INACTIVE, 0.4);
            
            sectorTabsPixiContainer.addChild(tabLastBg.container, tabMyBg.container, tabNewBg.container);

            const updateTabVisuals = (activeHtmlId) => {
                tabLastSector.classList.remove('active');
                tabMySectors.classList.remove('active');
                tabNewSectors.classList.remove('active');
                
                document.getElementById(activeHtmlId).classList.add('active');

                tabLastBg.fill.tint = LOGIN_COLORS.TAB_INACTIVE; tabLastBg.fill.alpha = 0.4;
                tabMyBg.fill.tint = LOGIN_COLORS.TAB_INACTIVE; tabMyBg.fill.alpha = 0.4;
                tabNewBg.fill.tint = LOGIN_COLORS.TAB_INACTIVE; tabNewBg.fill.alpha = 0.4;

                if (activeHtmlId === 'tab-last-sector') { tabLastBg.fill.tint = LOGIN_COLORS.TAB_ACTIVE; tabLastBg.fill.alpha = 0.6; }
                if (activeHtmlId === 'tab-my-sectors') { tabMyBg.fill.tint = LOGIN_COLORS.TAB_ACTIVE; tabMyBg.fill.alpha = 0.6; }
                if (activeHtmlId === 'tab-new-sectors') { tabNewBg.fill.tint = LOGIN_COLORS.TAB_ACTIVE; tabNewBg.fill.alpha = 0.6; }
            };

            tabLastSector.onclick = () => {
                updateTabVisuals('tab-last-sector');
                renderSectorList(lastPlayedSectorArray, 'my'); 
            };

            tabMySectors.onclick = () => {
                updateTabVisuals('tab-my-sectors');
                renderSectorList(otherMySectorsArray, 'my'); 
            };

            tabNewSectors.onclick = () => {
                updateTabVisuals('tab-new-sectors');
                renderSectorList(data.newSectors, 'new');
            };

            const setupTabHover = (htmlEl, pixiRef) => {
                htmlEl.onmouseenter = () => {
                    if (!htmlEl.classList.contains('active')) {
                        pixiRef.fill.tint = LOGIN_COLORS.TAB_HOVER;
                        pixiRef.fill.alpha = 0.8;
                    }
                };
                htmlEl.onmouseleave = () => {
                    if (!htmlEl.classList.contains('active')) {
                        pixiRef.fill.tint = LOGIN_COLORS.TAB_INACTIVE;
                        pixiRef.fill.alpha = 0.4;
                    }
                };
            };

            setupTabHover(tabLastSector, tabLastBg);
            setupTabHover(tabMySectors, tabMyBg);
            setupTabHover(tabNewSectors, tabNewBg);

            renderSectorList(lastPlayedSectorArray, 'my');
        }

        console.log("[Polling] Initiales Rendern beendet. Aktiviere Hintergrund-Schleife...");
        startSectorPolling();

    } catch (error) {
        console.error("Netzwerkfehler beim Sektor-Abruf:", error);
    }
}

/**
 * Rendert die HTML-Karte und die dazugehöhrigen PixiJS-Hintergrundboxen
 */
function renderSectorList(sectors, type) {
    const listContainer = document.getElementById('sector-list-container');
    listContainer.innerHTML = '';

    if (sectorPixiContainer) {
        sectorPixiContainer.removeChildren();
        sectorPixiContainer.y = 0; 
    }

    activePixiCardsMap.clear();

    const htmlSectorList = document.getElementById('sector-list-container');
    if (htmlSectorList) htmlSectorList.scrollTop = 0;

    if (sectors.length === 0) {
        listContainer.innerHTML = '<p style="text-align:center; color:var(--color-text-inactive);">Keine Sektoren in dieser Kategorie verfügbar.</p>';
        return;
    }

    sectors.forEach((sector, index) => {
        const cardLink = document.createElement('a');
        cardLink.className = 'sector-card-link';
        cardLink.href = `#`;

        // HTML-Karte im DOM blitzschnell zu finden, ohne das Grid neu aufzubauen.
        cardLink.setAttribute('data-sector-id', sector.id);

        // --- ECHTE DATEN STATT PLATZHALTER ---
        const createdDate = new Date(sector.created_at);
        const ageDays = Math.max(1, Math.ceil((new Date() - createdDate) / (1000 * 60 * 60 * 24))); 

        // Tooltip mit echten Konfigurationswerten aus der Sektor-DB aufbauen
        const tooltipLines = [
            `Anzahl der Galaxien: ${sector.max_galaxies}`,
            `Ökonomie-Tempo: ${sector.speed_economy}x`,
            `Forschungs-Tempo: ${sector.research_speed}x`,
            `Flotten Geschwindigkeiten:`,
            `Feindliche Flotte: ${sector.fleet_speed_hostile}x`,
            `Friedliche Flotte: ${sector.fleet_speed_peaceful}x`,
            `Freundliche Flotte: ${sector.fleet_speed_friendly}x`
        ];

        // BEDINGUNG: Treibstoff-Verbrauchsfaktor nur anzeigen, wenn er ungleich 1 ist
        if (sector.fuel_consumption_factor !== undefined && parseInt(sector.fuel_consumption_factor, 10) !== 1) {
            tooltipLines.push(`Treibstoff Verbrauch: ${sector.fuel_consumption_factor}x`);
        }

        // Standardmäßig immer das Flotten-Trümmerfeld-Prozent anzeigen
        tooltipLines.push(`${sector.fleet_to_debris_percentage}% der Flotten ins Trümmerfeld`);

        // BEDINGUNG: Verteidigungs-Trümmerfeld-Prozent nur anzeigen, wenn es größer als 0 ist
        if (sector.defense_to_debris_percentage !== undefined && parseInt(sector.defense_to_debris_percentage, 10) > 0) {
            tooltipLines.push(`${sector.defense_to_debris_percentage}% der Verteidigungsanlagen ins Trümmerfeld`);
        }

        // BEDINGUNG: Treibstoff im Trümmerfeld anzeigen, wenn das Flag true (oder ungleich 0 / false) ist
        if (sector.fuel_included_in_debris === true || sector.fuel_included_in_debris === 1 || sector.fuel_included_in_debris === 'true') {
            tooltipLines.push(`Treibstoff im Trümmerfeld: Ja`);
        }

        // BEDINGUNG: Start-Premium-Währung nur auflisten, wenn sie ungleich 0 ist
        if (sector.initial_res_premium !== undefined && parseInt(sector.initial_res_premium, 10) !== 0) {
            tooltipLines.push(`Void Kristalle beim Start: ${sector.initial_res_premium}`);
        }

        // BEDINGUNG: Bonus-Felder für Planeten nur anzeigen, wenn sie ungleich 0 sind
        if (sector.bonus_fields !== undefined && parseInt(sector.bonus_fields, 10) !== 0) {
            tooltipLines.push(`Bonus auf Planetenfelder: ${sector.bonus_fields}`);
        }

        // 3. Alle gesammelten Zeilen mit einem echten Zeilenumbruch (\n) zu einem einzelnen String verknüpfen
        const tooltipText = tooltipLines.join('\n');


        let bottomRowHtml = '';
        if (type === 'my' && sector.local_username) {
            bottomRowHtml = `<div style="position: absolute; left: 100px; bottom: 40px; font-size: 12px; color: var(--color-cyan-bright); ">Spieler: ${sector.local_username}</div>`;
        }

        cardLink.innerHTML = `
            <div class="sector-card-content" style="position: relative; width: 100%; height: 100%; padding: 0;">
                <span style="position: absolute; left: 10px; top: 15px; width: 25px; height: 27px; cursor: help;" title="${tooltipText}"></span>
                <span style="position: absolute; left: 40px; top: 15px; width: 140px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 18px; font-weight: bold;" title="${sector.name}">
                    ${sector.name}
                </span> 
                <span style="position: absolute; left: 150px; top: 18px; font-size: 12px; color: var(--color-text-placeholder);" title="Sektor-Alter in Tagen">${ageDays} Tage</span>
                <span class="sector-status ${sector.status === 'online' ? 'status-online' : 'status-maintenance'}" style="position: absolute; right: 20px; top: 17px;">
                    ${sector.status === 'online' ? 'online' : 'offline'}
                </span>
                
                <span class="sector-online-count" style="position: absolute; left: 40px; top: 54px; font-size: 13px; color: var(--color-text-placeholder);">Online: ${sector.online_players}/${sector.current_players}</span>
                <span class="sector-planets-count" style="position: absolute; left: 170px; top: 54px; font-size: 13px; color: var(--color-text-placeholder);">Planeten: ${sector.planets_count}</span>
                ${bottomRowHtml}
            </div>
        `;
        cardLink.onclick = (e) => {
            e.preventDefault();

            if (type === 'my') {
                console.log(`Betrete bekannten Sektor: ${sector.name}`);
                // todo für später, hier muss dann variable der link stehen oder man müsste ihn aus der datenbank auslesen
                window.open('https://dev.void-genesis.de', '_blank');
                
            } else {
                console.log(`Starte Onboarding für Sektor: ${sector.name} (ID: ${sector.id})`);

                selectedSectorId = sector.id;

                const sectorBrowserLayer = document.getElementById('sector-browser-layer');
                if (sectorBrowserLayer) {
                    sectorBrowserLayer.style.opacity = 0.05;
                    sectorBrowserLayer.style.pointerEvents = 'none';
                }

                const onboardingHtmlLayer = document.getElementById('sector-onboarding-layer');
                if (onboardingHtmlLayer) onboardingHtmlLayer.style.display = 'flex';
                
                if (onboardingPixiContainer) onboardingPixiContainer.visible = true;

                const localUsernameInput = document.getElementById('local-username');
                if (localUsernameInput) {
                    const userDataStr = sessionStorage.getItem('void_user') || localStorage.getItem('void_user');
                    if (userDataStr) {
                        try {
                            const userData = JSON.parse(userDataStr);
                            if (userData.username) {
                                localUsernameInput.value = userData.username;
                            }
                        } catch (err) {
                            console.error("Fehler beim Auslesen der User-Daten für das Onboarding:", err);
                        }
                    }
                }
            }
        };
        
        listContainer.appendChild(cardLink);

        const isMobilePortrait = window.innerWidth <= 800 && window.innerHeight > window.innerWidth;
        const columns = isMobilePortrait ? 2 : 4;
        const cardWidth = 270;
        const cardHeight = 90;
        const gapX = 25; 
        const gapY = 20; 

        const listContainerDOM = document.getElementById('sector-list-container');
        const containerClientWidth = listContainerDOM ? listContainerDOM.clientWidth : (isMobilePortrait ? 650 : 1240);

        const gridBlockWidth = (columns * cardWidth) + ((columns - 1) * gapX);

        const startX = (containerClientWidth - gridBlockWidth) / 2;
        const startY = 100; // 80px Top-Bar-Offset + 20px Padding oben

        const col = index % columns;
        const row = Math.floor(index / columns);

        const posX = startX + col * (cardWidth + gapX);
        const posY = startY + row * (cardHeight + gapY);

        const cardRefs = createSectorCardPixi(globalSheet, sectorPixiContainer, posX, posY);

        activePixiCardsMap.set(sector.id, cardRefs);

        if (sector.status !== 'online') {
            cardRefs.bgSprite.tint = 0x3a0b0b; 
            cardRefs.frameSprite.alpha = 0.4;
        }

        cardLink.addEventListener('mouseenter', () => {
            cardRefs.frameSprite.alpha = 1.0;
            cardRefs.bgSprite.alpha = 0.8;
            cardRefs.iconDetails.tint = 0x00f0ff; 
            cardRefs.iconDetails.scale.set(0.09); 
            cardRefs.iconDetails.rotation = 0.2; 
            cardRefs.iconPlayers.tint = 0xffffff;
            cardRefs.iconPlanets.tint = 0xffffff;
        });

        cardLink.addEventListener('mouseleave', () => {
            cardRefs.frameSprite.alpha = 0.8;
            cardRefs.bgSprite.alpha = 0.6;
            cardRefs.iconDetails.tint = 0xaaaaaa;
            cardRefs.iconDetails.scale.set(0.08);
            cardRefs.iconDetails.rotation = 0;
            cardRefs.iconPlayers.tint = 0xaaaaaa;
            cardRefs.iconPlanets.tint = 0xaaaaaa;
        });        
    });
}

async function checkAuthOnStartup() {
    const refreshToken = localStorage.getItem('void_refresh_token') || sessionStorage.getItem('void_refresh_token');
    if (!refreshToken) { return }

    try {
        const result = await refreshAccessTokenUser(refreshToken);
        
        if (result.ok && result.data.accessToken) {
            sessionStorage.setItem('void_access_token', result.data.accessToken);
            if (result.data.user) sessionStorage.setItem('void_user', JSON.stringify(result.data.user));
            transitionToLobby();
        } else {
            sessionStorage.removeItem('void_access_token');
            sessionStorage.removeItem('void_refresh_token');
            localStorage.removeItem('void_refresh_token');
            sessionStorage.removeItem('void_user');
        }
    } catch (error) {
        console.error("Netzwerkfehler beim Auto-Login:", error);
    }
}

initDropdowns(() => {
    const userField = document.getElementById('username');
    if (userField) userField.placeholder = formState.isLoginMode ? t('ph_username_login') : t('ph_username_reg');

    const emailField = document.getElementById('email');
    if (emailField) emailField.placeholder = t('ph_email');

    const passField = document.getElementById('password');
    if (passField) passField.placeholder = formState.isOtpMode || formState.isResetPasswordMode ? t('ph_otp') : t('ph_password');
});

const activePixiCardsMap = new Map();

/**
 * Startet das automatische Short Polling für die Sektordaten.
 * Die Schlöeife läuft lautlos im Hintergrund, solange der Spieler in der lobby ist.
 */
function startSectorPolling() {
    if (sectorPollingInterval) {
        clearInterval(sectorPollingInterval)
    }

    sectorPollingInterval = setInterval(async () => {
        if (!lobbyPixiContainer || !lobbyPixiContainer.visible) {
            return;
        }

        console.log("[Polling] Starte lautlos API-Abruf f+r Sektor-Updates...");
        await refreshSectorDataSilent();
    }, 30000);
}

/**
 * Stoppt das Sektor-Polling und bereinigt Referenzen.
 * Wird beim Logount oder bei Verbindungsfehlern aufgerufen.
 */
function stopSectorPolling() {
    if (sectorPollingInterval) {
        clearInterval(sectorPollingInterval);
        sectorPollingInterval = null;
        console.log("[Polling] Sektor-Polling erfolgreich gestoppt.");
    }
    activePixiCardsMap.clear();
}

/**
 * Holt die aktuellen Sektordaten lautlos vom Server und aktualisiert 
 * die bestehenden UI-Elemente, ohne das Grid oder Canvas neu aufzubauen.
 */
async function refreshSectorDataSilent() {
    const token = sessionStorage.getItem('void_access_token') || localStorage.getItem('void_access_token');
    if (!token) {
        stopSectorPolling();
        return;
    }

    try {
        const result = await fetchSectorsList();
        if (!result.ok || !result.data.success) {
            console.error("[Polling] Fehler beim lautlosen Abruf:", result.data.error);
            return;
        }

        const data = result.data;
        
        // --- ALLE SEKTOREN ZUSAMMENFASSEN ---
        // Es ist uns völlig egal, ob ein Sektor unter 'mySectors' oder 'newSectors' läuft.
        // Wir werfen beide Arrays mit dem Spread-Operator (...) in eine einzige Liste.
        const allSectors = [
            ...(data.mySectors || []),
            ...(data.newSectors || [])
        ];

        // Wir übergeben einfach die komplette Liste an die Update-Funktion.
        // Diese sucht sich dann selbstständig die Karten aus dem HTML, die gerade da sind.
        updateLiveStatus(allSectors, 'all');

    } catch (error) {
        console.error("[Polling] Netzwerkfehler während des Pollings:", error);
    }
}

/**
 * Iteriert durch die bestehenden DOM-Elemente und Pixi-Sprites,
 * um ausschließlich Status, Spielerzahlen und Planeten-Counts zu aktualisieren.
 * @param {Array} sectors - Das aktualisierte Sektoren-Array aus dem API-Response
 * @param {string} type - 'my' oder 'new'
 */
function updateLiveStatus(sectors, type) {
    sectors.forEach((sector) => {
        // Findet die HTML-Karte über das Sektor-ID-Attribut
        const cardLink = document.querySelector(`.sector-card-link[data-sector-id="${sector.id}"]`);
        
        if (cardLink) {
            // 1. HTML-Status Text & Klasse aktualisieren (Online / Offline)
            const statusEl = cardLink.querySelector('.sector-status');
            if (statusEl) {
                statusEl.textContent = sector.status === 'online' ? 'online' : 'offline';
                statusEl.className = `sector-status ${sector.status === 'online' ? 'status-online' : 'status-maintenance'}`;
            }

            /// 2. HTML-Spielerzahlen über die eindeutige Klasse aktualisieren
            const midRowEl = cardLink.querySelector('.sector-online-count');
            if (midRowEl) {
                // Das DOM übernimmt die echten Live-Werte für Online und Gesamt
                midRowEl.textContent = `Online: ${sector.online_players}/${sector.current_players}`;
            }

            // 3. HTML-Planetenanzahl über die neue, eindeutige Klasse aktualisieren
            const planetsEl = cardLink.querySelector('.sector-planets-count');
            if (planetsEl) {
                planetsEl.textContent = `Planeten: ${sector.planets_count}`;
            }
        }

        // 4. PixiJS Texturen und Tints über die Map-Referenz manipulieren
        const cardRefs = activePixiCardsMap.get(sector.id);
        if (cardRefs) {
            if (sector.status === 'online') {
                // Standard Sci-Fi Blau-Dunkel für den Hintergrund
                cardRefs.bgSprite.tint = 0x0b192c;
                // Rahmen wieder voll sichtbar schalten, wenn er aus der Wartung kommt
                cardRefs.frameSprite.alpha = sector.status === 'online' ? 0.8 : 0.4;
            } else {
                // Bei Offline-Status färben wir das Pixi-Feld düster Rot ein
                cardRefs.bgSprite.tint = 0x3a0b0b; 
                cardRefs.frameSprite.alpha = 0.4; 
            }
        }
    });
}

const btnGenderMale = document.getElementById('btn-gender-male');
const btnGenderFemale = document.getElementById('btn-gender-female');
const btnSubmitOnboarding = document.getElementById('btn-submit-onboarding');
const onboardingForm = document.getElementById('onboarding-form');
const btnCancelOnboarding = document.getElementById('btn-cancel-onboarding');

if (btnCancelOnboarding) {
    btnCancelOnboarding.addEventListener('click', (e) => {
        e.preventDefault();
        
        // 1. Sektor-Browser HTML wieder voll sichtbar machen
        const sectorBrowserLayer = document.getElementById('sector-browser-layer');
        if (sectorBrowserLayer) {
            sectorBrowserLayer.style.opacity = '1.0';
            sectorBrowserLayer.style.pointerEvents = 'auto'; // Klicks wieder erlauben
        }

        // 2. HTML-Layer des Modals ausblenden
        const onboardingHtmlLayer = document.getElementById('sector-onboarding-layer');
        if (onboardingHtmlLayer) onboardingHtmlLayer.style.display = 'none';
        
        // 3. PixiJS-Layer ausblenden
        if (onboardingPixiContainer) onboardingPixiContainer.visible = false;
        
        // 4. Formular zurücksetzen (damit alte Eingaben verschwinden)
        const onboardingForm = document.getElementById('onboarding-form');
        if (onboardingForm) onboardingForm.reset();
        
        // Optional: Hier auch noch die visuelle 'active' Klasse von deinen 
        // Geschlechter-Buttons entfernen, falls nötig.
    });
}

// --- Hilfsfunktion: Hover-Effekte synchronisieren ---
// Genau wie beim Login übertragen wir den Mauszeiger vom unsichtbaren HTML auf PixiJS
function syncHover(htmlElement, pixiRef, defaultTint, hoverTint = LOGIN_COLORS.TAB_HOVER) {
    if (!htmlElement || !pixiRef) return;
    
    htmlElement.addEventListener('mouseenter', () => {
        // Wenn der Button gerade "aktiv" ist (z.B. gewähltes Geschlecht), ignorieren wir den Hover
        if (!htmlElement.classList.contains('active')) {
            pixiRef.fill.tint = hoverTint;
            pixiRef.fill.alpha = 0.8;
        }
    });

    htmlElement.addEventListener('mouseleave', () => {
        if (!htmlElement.classList.contains('active')) {
            pixiRef.fill.tint = defaultTint;
            pixiRef.fill.alpha = 0.6; // Zurück zur Standard-Transparenz
        }
    });
}

// Hover-Effekte auf die Buttons anwenden (falls onboardingPixiRefs schon existiert)
// Wir prüfen hier sicherheitshalber ab, da die Refs asynchron generiert werden
const applyHoverEffects = setInterval(() => {
    if (onboardingPixiRefs) {
        clearInterval(applyHoverEffects); // Sobald geladen, Interval stoppen
        
        // Geschlechter-Buttons (Standard-Farbe ist Inactive, Hover ist Weiß)
        syncHover(btnGenderMale, onboardingPixiRefs.btnMale, LOGIN_COLORS.TAB_INACTIVE);
        syncHover(btnGenderFemale, onboardingPixiRefs.btnFemale, LOGIN_COLORS.TAB_INACTIVE);
        
        // Aktions-Buttons (Standard-Farbe ist Default-Grün)
        syncHover(btnCancelOnboarding, onboardingPixiRefs.btnCancel, LOGIN_COLORS.BTN_DEFAULT, LOGIN_COLORS.BTN_HOVER);
        syncHover(btnSubmitOnboarding, onboardingPixiRefs.btnJoin, LOGIN_COLORS.BTN_DEFAULT, LOGIN_COLORS.BTN_HOVER);
    }
}, 100);

// --- Geschlecht Umschalten (Toggle-Logik) ---
if (btnGenderMale && btnGenderFemale) {
    btnGenderMale.addEventListener('click', (e) => {
        e.preventDefault();
        selectedOnboardingGender = 'male';
        
        // HTML Klassen updaten (für Text-Farbe)
        btnGenderMale.classList.add('active');
        btnGenderFemale.classList.remove('active');
        
        // PixiJS Farben updaten
        if (onboardingPixiRefs) {
            onboardingPixiRefs.btnMale.fill.tint = LOGIN_COLORS.TAB_ACTIVE;
            onboardingPixiRefs.btnMale.fill.alpha = 0.6;
            
            onboardingPixiRefs.btnFemale.fill.tint = LOGIN_COLORS.TAB_INACTIVE;
            onboardingPixiRefs.btnFemale.fill.alpha = 0.4;
        }
    });

    btnGenderFemale.addEventListener('click', (e) => {
        e.preventDefault();
        selectedOnboardingGender = 'female';
        
        // HTML Klassen updaten
        btnGenderFemale.classList.add('active');
        btnGenderMale.classList.remove('active');
        
        // PixiJS Farben updaten
        if (onboardingPixiRefs) {
            onboardingPixiRefs.btnFemale.fill.tint = LOGIN_COLORS.TAB_ACTIVE;
            onboardingPixiRefs.btnFemale.fill.alpha = 0.6;
            
            onboardingPixiRefs.btnMale.fill.tint = LOGIN_COLORS.TAB_INACTIVE;
            onboardingPixiRefs.btnMale.fill.alpha = 0.4;
        }
    });
}

// --- Formular Absenden (Beitreten) ---
if (onboardingForm) {
    onboardingForm.addEventListener('submit', async (e) => {
        e.preventDefault(); // Verhindert das Neuladen der Seite
        
        if (!selectedSectorId) return;

        const localUsername = document.getElementById('local-username').value;
        const msgBox = document.getElementById('onboarding-msg-box');

        msgBox.textContent = '...';
        msgBox.style.color = 'var(--color-text-main)';

        const token = sessionStorage.getItem('void_access_token') || localStorage.getItem('void_access_token');
        
        try {

            const result = await joinSectorUser(token, selectedSectorId, localUsername, selectedOnboardingGender);

            if (!result.ok) {
                msgBox.style.color = 'var(--color-error)';
                msgBox.textContent = t(result.data.error) || t('ERR_INTERNAL_SERVER');
                return;
            }

            msgBox.style.color = 'var(--color-green-bright)';
            msgBox.textContent = t(result.data.message);

            setTimeout(() => {
                if (btnCancelOnboarding) btnCancelOnboarding.click();
                
                loadAndRenderSectorBrowser();
                window.open('https://dev.void-genesis.de', '_blank');
            }, 1500);

        } catch (error) {
            msgBox.style.color = 'var(--color-error)';
            msgBox.textContent = t('ERR_INTERNAL_SERVER');
        }
    });
}
initGame();