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

// ==============================================================================
// Void-Genesis - Datenbank Initialisierungs-Skript
// Führt alle nötigen CREATE TABLE Befehle aus, falls die Tabellen nicht existieren.
// ==============================================================================

const createTablesQuery = `

-- ------------------------------------------------------------------------------
-- DROP TABLES
-- WICHTIG: Die Reihenfolge beim Löschen ist entscheidend!
-- Tabellen mit Fremdschlüsseln (Foreign Keys) müssen zuerst gelöscht werden.
-- ------------------------------------------------------------------------------
DROP TABLE IF EXISTS lobby_accounts_titles;
DROP TABLE IF EXISTS refresh_tokens;
DROP TABLE IF EXISTS auth_otps;
DROP TABLE IF EXISTS lobby_accounts_sectors; -- Zuerst die Brückentabelle löschen
DROP TABLE IF EXISTS sectors;                -- Dann die Sektoren-Tabelle
DROP TABLE IF EXISTS lobby_accounts;         -- Zuletzt die Haupt-Nutzer-Tabelle

-- ------------------------------------------------------------------------------
-- TABLE: lobby_accounts
-- Basis-Nutzerdaten für das gesamte Void-Genesis Universum.
-- ------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS lobby_accounts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    is_email_verified BOOLEAN DEFAULT false,
    res_premium INT DEFAULT 0,
    is_admin BOOLEAN DEFAULT false,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ------------------------------------------------------------------------------
-- TABLE: lobby_accounts_titles (GLOBAL FREIGESCHALTETE TITEL)
-- Speichert, welche Titel ein Spieler global für sein gesamtes Konto freigeschaltet hat.
-- ------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS lobby_accounts_titles (
    lobby_account_id UUID REFERENCES lobby_accounts(id) ON DELETE CASCADE,
    title_id INT NOT NULL,
    unlocked_at TIMESTAMPTZ DEFAULT NOW(),
    PRIMARY KEY (lobby_account_id, title_id)
);

-- ------------------------------------------------------------------------------
-- TABLE: sectors
-- Beinhaltet die globalen Metadaten zu allen verfügbaren Spiel-Sektoren.
-- Hier definieren wir, welche Server existieren und welche Eigenschaften sie haben.
-- ------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS sectors (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(50) UNIQUE NOT NULL,
    status VARCHAR(20) DEFAULT 'offline',
    api_url VARCHAR(255),
    is_registration_open BOOLEAN DEFAULT true,
    current_players INT DEFAULT 0,
    online_players INT DEFAULT 0,  
    planets_count INT DEFAULT 0,   
    max_galaxies INT DEFAULT 5,
    speed_economy INT DEFAULT 1,
    research_speed INT DEFAULT 1,
    fleet_speed_hostile INT DEFAULT 1,
    fleet_speed_peaceful INT DEFAULT 1,
    fleet_speed_friendly INT DEFAULT 1,
    fuel_consumption_factor NUMERIC(5,2) DEFAULT 1.00,
    fleet_to_debris_percentage  INT DEFAULT 30,
    defense_to_debris_percentage INT DEFAULT 0,
    fuel_included_in_debris BOOLEAN DEFAULT false,
    initial_res_premium INT DEFAULT 0,
    bonus_fields INT DEFAULT 0,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ------------------------------------------------------------------------------
-- TABLE: lobby_accounts_sectors (Brückentabelle)
-- Verknüpft einen Lobby-Account mit einem Sektor.
-- Existiert hier ein Eintrag, bedeutet das: Der Nutzer hat in diesem Sektor einen Spielstand.
-- ------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS lobby_accounts_sectors (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    lobby_account_id UUID REFERENCES lobby_accounts(id) ON DELETE CASCADE,
    sector_id UUID REFERENCES sectors(id) ON DELETE CASCADE,
    local_username VARCHAR(50) NOT NULL,
    gender VARCHAR(20) NOT NULL,
    res_premium INT DEFAULT 0,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(lobby_account_id, sector_id),
    UNIQUE(sector_id, local_username)
);

-- ------------------------------------------------------------------------------
-- TABLE: auth_otps
-- Speichert temporäre 6-stellige Codes für Registrierung oder Passwort-Reset.
-- ------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS auth_otps (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    account_id UUID REFERENCES lobby_accounts(id) ON DELETE CASCADE,
    otp_code VARCHAR(6) NOT NULL,
    type VARCHAR(20) NOT NULL,
    expires_at TIMESTAMPTZ NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- ------------------------------------------------------------------------------
-- TABLE: refresh_tokens
-- Speichert langlebige Tokens für die "Angemeldet bleiben"-Funktion.
-- ------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS refresh_tokens (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    account_id UUID REFERENCES lobby_accounts(id) ON DELETE CASCADE,
    token VARCHAR(500) UNIQUE NOT NULL,
    expires_at TIMESTAMPTZ NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- ------------------------------------------------------------------------------
-- TRIGGER: Auto-update 'updated_at' timestamp
-- Diese Funktion setzt das 'updated_at' Feld bei jeder Änderung auf die aktuelle Zeit.
-- ------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ language 'plpgsql';

-- Wir wenden den Trigger nur an, wenn er noch nicht existiert.
DO $$ 
BEGIN
  -- Trigger für lobby_accounts
  IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_lobby_accounts_modtime') THEN
    CREATE TRIGGER update_lobby_accounts_modtime
        BEFORE UPDATE ON lobby_accounts
        FOR EACH ROW
        EXECUTE FUNCTION update_modified_column();
  END IF;
  
  -- Trigger für sectors
  IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_sectors_modtime') THEN
    CREATE TRIGGER update_sectors_modtime
        BEFORE UPDATE ON sectors
        FOR EACH ROW
        EXECUTE FUNCTION update_modified_column();
  END IF;

  -- Trigger für lobby_accounts_sectors (WICHTIG für unsere "Zuletzt gespielt" Funktion)
  IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_lobby_accounts_sectors_modtime') THEN
    CREATE TRIGGER update_lobby_accounts_sectors_modtime
        BEFORE UPDATE ON lobby_accounts_sectors
        FOR EACH ROW
        EXECUTE FUNCTION update_modified_column();
  END IF;
END $$;
`;

// ==============================================================================
// Ausführungs-Logik
// ==============================================================================
async function initDatabase() {
    console.log('⏳ Starte Datenbank-Initialisierung...');
    
    // Wir holen uns eine Verbindung aus dem Pool
    const client = await pool.connect();

    try {
        // Wir senden den kompletten SQL-String für die Tabellenstruktur an die Datenbank
        await client.query(createTablesQuery);
        console.log('✅ Tabellen wurden erfolgreich erstellt (oder existierten bereits).');
        
        // --------------------------------------------------------------------------
        // SEEDING: Admin- & Test-Accounts einfegen
        // --------------------------------------------------------------------------
        console.log('🌱 Starte das Seeding der Core-Lobby-Accounts...');
        
        // FÜGE HIER DEINEN GEMERKTEN HASH EIN:
        const sharedPasswordHash = '$argon2id$v=19$m=65536,t=3,p=4$Iy65NQOkCUkJOJZL2HPyEQ$XygOJe9egEtfg0B2o3QRnlxQKbT1MwIy4vKOQntDIkY'; 

        // Wir nutzen ON CONFLICT (username) DO NOTHING, um doppelte Inserts zu verhindern
        await client.query(`
            INSERT INTO lobby_accounts (username, email, password_hash, is_email_verified, is_admin, res_premium)
            VALUES ($1, $2, $3, true, true, 50000000)
            ON CONFLICT (username) DO NOTHING
        `, ['Novacell', 'info@void-genesis.de', sharedPasswordHash]);
        
        console.log('👑 Admin-Account "Novacell" wurde verifiziert und geladen (Premium: 50.000.000).');

        const testAccountPromises = [];
        for (let i = 1; i <= 10; i++) {
            const username = `Test${i}`;
            const email = `info+${i}@void-genesis.de`;
            
            await client.query(`
                INSERT INTO lobby_accounts (username, email, password_hash, is_email_verified, is_admin, res_premium)
                VALUES ($1, $2, $3, true, false, 10000)
                ON CONFLICT (username) DO NOTHING
            `, [username, email, sharedPasswordHash]);
        }
        
        // Alle Test-Accounts parallel in die DB jagen
        await Promise.all(testAccountPromises);
        console.log('👥 10 Test-Accounts (TestPlayer1 bis TestPlayer10) erfolgreich angelegt.');

        // --------------------------------------------------------------------------
        // SEEDING: Sektoren (unverändert aus deinem Original-Skript)
        // --------------------------------------------------------------------------
        const sectorCheck = await client.query('SELECT count(*) FROM sectors');
        if (parseInt(sectorCheck.rows[0].count) === 0) {
            console.log('🌱 Füge Test-Sektoren sequenziell ein...');
            
            const greekAlphabet = [
                'Development', 'Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 
                'Eta', 'Theta', 'Iota', 'Kappa', 'Lambda', 'Mu', 
                'Nu', 'Xi', 'Omicron', 'Pi', 'Rho', 'Sigma', 
                'Tau', 'Upsilon', 'Phi', 'Chi', 'Psi', 'Omega'
            ];

            for (let index = 0; index < greekAlphabet.length; index++) {
                const name = greekAlphabet[index];
                const speed = (index % 4) + 1; 
                const apiUrl = name === 'Development' 
                    ? 'http://sector-backend:3000' 
                    : `http://sector-api-${name.toLowerCase()}:3000`;
                
                await client.query(`
                    INSERT INTO sectors (name, status, api_url) 
                    VALUES ($1, 'offline', $2)
                `, [name, apiUrl]);
            }
            console.log('✅ 25 Sektoren ohne Parallelitäts-Konflikte eingefügt.');
        }
        
        console.log('🎉 Lobby-Datenbank-Initialisierung vollständig und sauber abgeschlossen!');
        
    } catch (error) {
        console.error('❌ Fehler beim Erstellen oder Befüllen der Lobby-Tabellen:', error);
    } finally {
        // Verbindung freigeben und Prozess sauber beenden
        client.release();
        process.exit();
    }
}

// Skript direkt aufrufen
initDatabase();