import pool from '../db.js';

/**
 * Ruft die Sektorlisten für einen bestimmten Account ab.
 * Unterteilt das Ergebnis in bereits beigetretene Sektoren ("Meine Sektoren")
 * und noch verfügbare Sektoren ("Neue Sektoren").
 * 
 * @param {string} accountId - Die UUID des aktuell eingeloggten Spielers
 * 
 * @returns {Promise<Object>} - Ein Objekt mit den Arrays 'mySectors' und 'newSectors'
 */
export const getSectorsList = async (accountId) => {
    const client = await pool.connect();
    try {
        // WURDE ERWEITERT: Wir selektieren nun die echten Cache-Werte (online_players, planets_count)
        // sowie Konfigurationswerte (initial_res_premium, fleet_speed_hostile) und das Erstelldatum (created_at).
        const mySectorsResult = await client.query(`
            SELECT
                s.id, s.name, s.status, s.is_registration_open, 
                s.online_players, s.current_players, s.planets_count, s.created_at, 
                s.speed_economy, s.research_speed, s.max_galaxies,
                s.fleet_speed_hostile, s.fleet_speed_peaceful, s.fleet_speed_friendly,
                s.fuel_consumption_factor, s.fleet_to_debris_percentage,
                s.defense_to_debris_percentage, s.fuel_included_in_debris,
                s.initial_res_premium, s.bonus_fields,
                las.local_username, las.gender,
                las.created_at as joined_at,
                las.updated_at as last_played
            FROM sectors s
            JOIN lobby_accounts_sectors las ON s.id = las.sector_id
            WHERE las.lobby_account_id = $1
            ORDER BY las.updated_at DESC
        `, [accountId]);

        const newSectorsResult = await client.query(`
            SELECT
                id, name, status, is_registration_open, 
                online_players, current_players, planets_count, created_at, 
                speed_economy, research_speed, max_galaxies,
                fleet_speed_hostile, fleet_speed_peaceful, fleet_speed_friendly,
                fuel_consumption_factor, fleet_to_debris_percentage,
                defense_to_debris_percentage, fuel_included_in_debris,
                initial_res_premium, bonus_fields
            FROM sectors
            WHERE id NOT IN (
                SELECT sector_id
                FROM lobby_accounts_sectors
                WHERE lobby_account_id = $1
            )
            -- Wir zeigen bei den "Neuen Sektoren" nur die an, 
            -- bei denen die Registrierung noch nicht serverseitig geschlossen wurde.
            AND is_registration_open = true
            ORDER BY created_at ASC
        `, [accountId]);

        // ALTE LOGIK ENTFERNT: Wir brauchen kein mapSectorData mit Math.random() mehr!
        // Wir geben die echten Datenbank-Ergebnisse direkt ans Frontend weiter.
        return {
            mySectors: mySectorsResult.rows,
            newSectors: newSectorsResult.rows
        };

    } catch (error) {
        console.error('[SectorService] Fehler beim Auslesen der Sektordaten:', error);
        throw error;
    } finally {
        client.release();
    }
};

/**
 * Trägt einen Spieler in einen neuen Sektor ein.
 * Komuniziert zuest mit dem Ziel-Sektor und speichert den Psielstand in der lobby erst,
 * wenn des Sektor-Backend den Account erfolgreich akzeptiert hat.
 *
 * @param {string} accountId - Die UUID des Nutzers
 * @param {string} sectorId - Die UUID des Sektors
 * @param {string} localUsername - Der Commander-Name für diesen Sektor
 * @param {string} gender - Das gewählte Geschlecht ('male' oder 'female')
 * 
 * @returns {boolean} - true bei Erfolg
 */
export const joinSector = async (accountId, sectorId, localUsername, gender) => {
    const client = await pool.connect();

    try {
        const sectorQuery = await client.query(
            'SELECT name, api_url, status FROM sectors WHERE id = $1',
            [sectorId]
        );

        if (sectorQuery.rows.length === 0) {
            const customErr = new Error('Sector not found');
            customErr.code = 'ERR_SECTOR_NOT_FOUND';
            throw customErr;
        }

        const sector = sectorQuery.rows[0];

        if (sector.status !== 'online') {
            const customErr = new Error('Sector is offline or under maintenance');
            customErr.code = 'ERR_SECTOR_OFFLINE';
            throw customErr;
        }

        // Ziel-Endpunkt des Sektors: POST /api/internal/accounts
        const sectorInternalUrl = `${sector.api_url}/api/internal/accounts`;

        console.log(`[Lobby-to-Server] Sende Registierung für '${localUsername}' an Sektor '${sector.name}' (${sectorInternalUrl})...`);

        const response = await fetch(sectorInternalUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                lobby_uuid: accountId,
                username: localUsername,
                gender: gender
            })
        });

        if (!response.ok) {
            const errorData = await response.json().catch(() => ({}));
            console.error(`[Lobby-to-Server] Sektor meldet Fehler (Status ${response.status}):`, errorData);

            if (response.status == 409) {
                const customErr = new Error(errorData.error || 'Conflict in Sector');
                customErr.code = errorData.error || 'ERR_LOCAL_USERNAME_TAKEN';
                throw customErr;
            }

            const customErr = new Error('Sector communication failed');
            customErr.code = 'ERR_SECTOR_CONNECTION_FAILED';
            throw customErr;
        }

        const sectorResultData = await response.json();
        console.log(`[Lobby-to-Server] ✅ Sektor-Account erfolgreich angelegt! Local-UUID: ${sectorResultData.account?.local_uuid}`);
        

        // Wir versuchen, den Datensatz direkt einzufügen.
        await client.query(`
            INSERT INTO lobby_accounts_sectors (lobby_account_id, sector_id, local_username, gender)
            VALUES ($1, $2, $3, $4)
        `, [accountId, sectorId, localUsername, gender]);

        return true;

    } catch (error) {
        // Fehlercode 23505 = Postgres "unique_violation"
        if (error.code === '23505') {
            
            if (error.constraint === 'lobby_accounts_sectors_lobby_account_id_sector_id_key') {
                const customErr = new Error('Already in sector');
                customErr.code = 'ERR_ALREADY_IN_SECTOR';
                throw customErr;
            }
            
            if (error.constraint === 'lobby_accounts_sectors_sector_id_local_username_key') {
                const customErr = new Error('Local username taken');
                customErr.code = 'ERR_LOCAL_USERNAME_TAKEN';
                throw customErr;
            }
        }

        throw error;

    } finally {
        client.release();
    }
};