import { sequelize } from './sequelize.js';

/**
 * Bereinigt doppelte Constraints und Indexe in der Datenbank
 * Dies sollte nur einmal ausgeführt werden, um bestehende Probleme zu beheben
 */
async function cleanupDatabaseConstraints() {
    try {
        console.log('🧹 Starte Bereinigung der Datenbank-Constraints...');

        // 1. Spezielle Bereinigung für community.user Tabelle
        console.log('🔍 Spezielle Bereinigung für community.user Tabelle...');
        await cleanupUserTableConstraints();

        // 2. Doppelte UNIQUE Constraints entfernen
        console.log('🔍 Suche nach doppelten UNIQUE Constraints...');
        
        const duplicateUniqueConstraints = await sequelize.query(`
            SELECT 
                tc.table_schema,
                tc.table_name,
                kcu.column_name,
                COUNT(*) as constraint_count,
                array_agg(tc.constraint_name) as constraint_names
            FROM information_schema.table_constraints tc
            JOIN information_schema.key_column_usage kcu 
                ON tc.constraint_name = kcu.constraint_name
            WHERE tc.constraint_type = 'UNIQUE'
            AND tc.table_schema IN ('match3', 'community', 'falukant_data', 'falukant_type', 'falukant_predefine', 'falukant_log', 'chat', 'forum', 'logs', 'type', 'service')
            GROUP BY tc.table_schema, tc.table_name, kcu.column_name
            HAVING COUNT(*) > 1
            ORDER BY tc.table_name, kcu.column_name;
        `, { type: sequelize.QueryTypes.SELECT });

        console.log(`📊 Gefunden: ${duplicateUniqueConstraints.length} Spalten mit doppelten UNIQUE Constraints`);

        // Entferne doppelte UNIQUE Constraints
        for (const duplicate of duplicateUniqueConstraints) {
            console.log(`🗑️  Entferne doppelte UNIQUE Constraints für ${duplicate.table_schema}.${duplicate.table_name}.${duplicate.column_name}`);
            
            // Behalte den ersten Constraint, entferne die anderen
            const constraintNames = duplicate.constraint_names;
            for (let i = 1; i < constraintNames.length; i++) {
                const constraintName = constraintNames[i];
                try {
                    await sequelize.query(`
                        ALTER TABLE ${duplicate.table_schema}.${duplicate.table_name} 
                        DROP CONSTRAINT IF EXISTS "${constraintName}"
                    `);
                    console.log(`  ✅ Entfernt: ${constraintName}`);
                } catch (error) {
                    console.log(`  ⚠️  Konnte nicht entfernen: ${constraintName} - ${error.message}`);
                }
            }
        }

        // 3. Entferne alle Constraints mit numerischen Suffixen
        console.log('🔍 Entferne alle Constraints mit numerischen Suffixen...');
        await removeNumericalSuffixConstraints();

        // 4. Doppelte CHECK Constraints entfernen (korrigierte Abfrage)
        console.log('🔍 Suche nach doppelten CHECK Constraints...');
        
        try {
            const duplicateCheckConstraints = await sequelize.query(`
                SELECT 
                    ttc.table_schema,
                    ttc.table_name,
                    tc.constraint_name,
                    tc.check_clause
                FROM information_schema.check_constraints tc
                JOIN information_schema.table_constraints ttc 
                    ON tc.constraint_name = ttc.constraint_name
                WHERE ttc.table_schema IN ('match3', 'community', 'falukant_data', 'falukant_type', 'falukant_predefine', 'falukant_log', 'chat', 'forum', 'logs', 'type', 'service')
                ORDER BY ttc.table_name, tc.constraint_name;
            `, { type: sequelize.QueryTypes.SELECT });

            console.log(`📊 Gefunden: ${duplicateCheckConstraints.length} CHECK Constraints`);
        } catch (error) {
            console.log(`⚠️  Konnte CHECK Constraints nicht abfragen: ${error.message}`);
        }

        // 5. Doppelte Foreign Key Constraints entfernen
        console.log('🔍 Suche nach doppelten Foreign Key Constraints...');
        
        const duplicateFKs = await sequelize.query(`
            SELECT 
                tc.constraint_name,
                tc.table_name,
                tc.table_schema,
                kcu.column_name,
                ccu.table_name AS foreign_table_name,
                ccu.column_name AS foreign_column_name
            FROM information_schema.table_constraints tc
            JOIN information_schema.key_column_usage kcu 
                ON tc.constraint_name = kcu.constraint_name
            JOIN information_schema.constraint_column_usage ccu 
                ON ccu.constraint_name = tc.constraint_name
            WHERE tc.constraint_type = 'FOREIGN KEY'
            AND tc.table_schema IN ('match3', 'community', 'falukant_data', 'falukant_type', 'falukant_predefine', 'falukant_log', 'chat', 'forum', 'logs', 'type', 'service')
            ORDER BY tc.table_name, tc.constraint_name;
        `, { type: sequelize.QueryTypes.SELECT });

        console.log(`📊 Gefunden: ${duplicateFKs.length} Foreign Key Constraints`);

        // 6. Doppelte Indexe entfernen
        console.log('🔍 Suche nach doppelten Indexen...');
        
        const duplicateIndexes = await sequelize.query(`
            SELECT 
                schemaname,
                tablename,
                indexname,
                indexdef
            FROM pg_indexes
            WHERE schemaname IN ('match3', 'community', 'falukant_data', 'falukant_type', 'falukant_predefine', 'falukant_log', 'chat', 'forum', 'logs', 'type', 'service')
            AND indexname LIKE '%_index_%'
            ORDER BY tablename, indexname;
        `, { type: sequelize.QueryTypes.SELECT });

        console.log(`📊 Gefunden: ${duplicateIndexes.length} potenziell doppelte Indexe`);

        // 7. Spezifische Match3-Constraints prüfen
        console.log('🔍 Prüfe Match3-spezifische Constraints...');
        
        const match3Constraints = await sequelize.query(`
            SELECT 
                constraint_name,
                table_name,
                constraint_type
            FROM information_schema.table_constraints
            WHERE table_schema = 'match3'
            ORDER BY table_name, constraint_type;
        `, { type: sequelize.QueryTypes.SELECT });

        console.log(`📊 Match3 Constraints: ${match3Constraints.length} gefunden`);
        match3Constraints.forEach(constraint => {
            console.log(`  - ${constraint.table_name}: ${constraint.constraint_type} (${constraint.constraint_name})`);
        });

        // 8. Spezifische Chat-Constraints prüfen (da das Problem dort auftritt)
        console.log('🔍 Prüfe Chat-spezifische Constraints...');
        
        try {
            const chatConstraints = await sequelize.query(`
                SELECT 
                    tc.constraint_name,
                    tc.table_name,
                    tc.constraint_type,
                    kcu.column_name
                FROM information_schema.table_constraints tc
                LEFT JOIN information_schema.key_column_usage kcu 
                    ON tc.constraint_name = kcu.constraint_name
                WHERE tc.table_schema = 'chat'
                ORDER BY tc.table_name, tc.constraint_type, kcu.column_name;
            `, { type: sequelize.QueryTypes.SELECT });

            console.log(`📊 Chat Constraints: ${chatConstraints.length} gefunden`);
            chatConstraints.forEach(constraint => {
                console.log(`  - ${constraint.table_name}: ${constraint.constraint_type} (${constraint.constraint_name}) auf Spalte: ${constraint.column_name}`);
            });
        } catch (error) {
            console.log(`⚠️  Konnte Chat Constraints nicht abfragen: ${error.message}`);
        }

        // 9. Spezifische Überprüfung der chat.rights Tabelle
        console.log('🔍 Spezielle Überprüfung der chat.rights Tabelle...');
        
        try {
            const rightsConstraints = await sequelize.query(`
                SELECT 
                    tc.constraint_name,
                    tc.constraint_type,
                    kcu.column_name
                FROM information_schema.table_constraints tc
                LEFT JOIN information_schema.key_column_usage kcu 
                    ON tc.constraint_name = kcu.constraint_name
                WHERE tc.table_schema = 'chat' 
                AND tc.table_name = 'rights'
                ORDER BY tc.constraint_type, kcu.column_name;
            `, { type: sequelize.QueryTypes.SELECT });

            console.log(`📊 Chat Rights Constraints: ${rightsConstraints.length} gefunden`);
            rightsConstraints.forEach(constraint => {
                console.log(`  - ${constraint.constraint_type} (${constraint.constraint_name}) auf Spalte: ${constraint.column_name}`);
            });

            // Entferne alle doppelten UNIQUE Constraints auf der tr-Spalte
            const trUniqueConstraints = rightsConstraints.filter(c => 
                c.constraint_type === 'UNIQUE' && c.column_name === 'tr'
            );
            
            if (trUniqueConstraints.length > 1) {
                console.log(`🗑️  Entferne ${trUniqueConstraints.length - 1} doppelte UNIQUE Constraints auf chat.rights.tr`);
                
                // Behalte den ersten, entferne die anderen
                for (let i = 1; i < trUniqueConstraints.length; i++) {
                    const constraintName = trUniqueConstraints[i].constraint_name;
                    try {
                        await sequelize.query(`
                            ALTER TABLE chat.rights 
                            DROP CONSTRAINT IF EXISTS "${constraintName}"
                        `);
                        console.log(`  ✅ Entfernt: ${constraintName}`);
                    } catch (error) {
                        console.log(`  ⚠️  Konnte nicht entfernen: ${constraintName} - ${error.message}`);
                    }
                }
            }
        } catch (error) {
            console.log(`⚠️  Konnte chat.rights Constraints nicht abfragen: ${error.message}`);
        }

        // 10. Empfehlungen ausgeben
        console.log('\n💡 Empfehlungen:');
        console.log('1. Überprüfe die oben gelisteten Constraints auf Duplikate');
        console.log('2. Verwende updateSchema() nur bei expliziten Schema-Änderungen');
        console.log('3. Normale syncModels() läuft jetzt ohne alter: true');
        console.log('4. Bei Problemen: Manuelle Bereinigung der doppelten Constraints');

        console.log('✅ Datenbank-Constraint-Bereinigung abgeschlossen');

    } catch (error) {
        console.error('❌ Fehler bei der Constraint-Bereinigung:', error);
        throw error;
    }
}

/**
 * Spezielle Bereinigung für die community.user Tabelle
 * Entfernt alle Constraints mit numerischen Suffixen
 */
async function cleanupUserTableConstraints() {
    try {
        console.log('🔍 Bereinige community.user Tabelle...');
        
        // Finde alle Constraints der user Tabelle
        const userConstraints = await sequelize.query(`
            SELECT 
                tc.constraint_name,
                tc.constraint_type,
                kcu.column_name
            FROM information_schema.table_constraints tc
            LEFT JOIN information_schema.key_column_usage kcu 
                ON tc.constraint_name = kcu.constraint_name
            WHERE tc.table_schema = 'community' 
            AND tc.table_name = 'user'
            ORDER BY tc.constraint_type, kcu.column_name;
        `, { type: sequelize.QueryTypes.SELECT });

        console.log(`📊 Community.user Constraints gefunden: ${userConstraints.length}`);
        
        // Gruppiere Constraints nach Spalte und Typ
        const constraintsByColumn = {};
        userConstraints.forEach(constraint => {
            const key = `${constraint.constraint_type}_${constraint.column_name || 'general'}`;
            if (!constraintsByColumn[key]) {
                constraintsByColumn[key] = [];
            }
            constraintsByColumn[key].push(constraint.constraint_name);
        });

        // Entferne doppelte Constraints, behalte nur einen pro Spalte/Typ
        for (const [key, constraintNames] of Object.entries(constraintsByColumn)) {
            if (constraintNames.length > 1) {
                console.log(`🗑️  Entferne ${constraintNames.length - 1} doppelte Constraints für ${key}`);
                
                // Sortiere nach Namen, um konsistente Ergebnisse zu erhalten
                constraintNames.sort();
                
                // Behalte den ersten, entferne die anderen
                for (let i = 1; i < constraintNames.length; i++) {
                    const constraintName = constraintNames[i];
                    try {
                        await sequelize.query(`
                            ALTER TABLE community."user" 
                            DROP CONSTRAINT IF EXISTS "${constraintName}"
                        `);
                        console.log(`  ✅ Entfernt: ${constraintName}`);
                    } catch (error) {
                        console.log(`  ⚠️  Konnte nicht entfernen: ${constraintName} - ${error.message}`);
                    }
                }
            }
        }

        // Entferne alle Constraints mit numerischen Suffixen
        const numericalConstraints = userConstraints.filter(c => 
            /\d+$/.test(c.constraint_name) && 
            (c.constraint_name.includes('_key') || c.constraint_name.includes('_index'))
        );

        if (numericalConstraints.length > 0) {
            console.log(`🗑️  Entferne ${numericalConstraints.length} Constraints mit numerischen Suffixen`);
            
            for (const constraint of numericalConstraints) {
                try {
                    await sequelize.query(`
                        ALTER TABLE community."user" 
                        DROP CONSTRAINT IF EXISTS "${constraint.constraint_name}"
                    `);
                    console.log(`  ✅ Entfernt: ${constraint.constraint_name}`);
                } catch (error) {
                    console.log(`  ⚠️  Konnte nicht entfernen: ${constraint.constraint_name} - ${error.message}`);
                }
            }
        }

    } catch (error) {
        console.log(`⚠️  Konnte community.user Constraints nicht bereinigen: ${error.message}`);
    }
}

/**
 * Entfernt alle Constraints mit numerischen Suffixen aus allen Tabellen
 */
async function removeNumericalSuffixConstraints() {
    try {
        console.log('🔍 Entferne alle Constraints mit numerischen Suffixen...');
        
        // Finde alle Constraints mit numerischen Suffixen
        const numericalConstraints = await sequelize.query(`
            SELECT 
                tc.table_schema,
                tc.table_name,
                tc.constraint_name,
                tc.constraint_type
            FROM information_schema.table_constraints tc
            WHERE tc.table_schema IN ('match3', 'community', 'falukant_data', 'falukant_type', 'falukant_predefine', 'falukant_log', 'chat', 'forum', 'logs', 'type', 'service')
            AND tc.constraint_name ~ '.*\\d+$'
            AND (tc.constraint_name LIKE '%_key%' OR tc.constraint_name LIKE '%_index%')
            ORDER BY tc.table_schema, tc.table_name, tc.constraint_name;
        `, { type: sequelize.QueryTypes.SELECT });

        console.log(`📊 Gefunden: ${numericalConstraints.length} Constraints mit numerischen Suffixen`);

        if (numericalConstraints.length > 0) {
            for (const constraint of numericalConstraints) {
                try {
                    await sequelize.query(`
                        ALTER TABLE ${constraint.table_schema}.${constraint.table_name} 
                        DROP CONSTRAINT IF EXISTS "${constraint.constraint_name}"
                    `);
                    console.log(`  ✅ Entfernt: ${constraint.table_schema}.${constraint.table_name}.${constraint.constraint_name}`);
                } catch (error) {
                    console.log(`  ⚠️  Konnte nicht entfernen: ${constraint.constraint_name} - ${error.message}`);
                }
            }
        }

    } catch (error) {
        console.log(`⚠️  Konnte numerische Suffix-Constraints nicht entfernen: ${error.message}`);
    }
}

// Führe das Skript aus, wenn es direkt aufgerufen wird
if (import.meta.url === `file://${process.argv[1]}`) {
    cleanupDatabaseConstraints()
        .then(() => {
            console.log('🎯 Datenbank-Constraint-Bereinigung abgeschlossen');
            process.exit(0);
        })
        .catch((error) => {
            console.error('💥 Datenbank-Constraint-Bereinigung fehlgeschlagen:', error);
            process.exit(1);
        });
}

export default cleanupDatabaseConstraints;
