/**
 * Database Migration Runner
 * Executes SQL migrations in order
 */

const sqlite3 = require('sqlite3').verbose();
const path = require('path');
const fs = require('fs');

const dbPath = path.join(__dirname, '../data/db/image_uploader.db');
const migrationsDir = path.join(__dirname, 'migrations');

// Helper to promisify database operations
function runQuery(db, sql, params = []) {
    return new Promise((resolve, reject) => {
        db.run(sql, params, function(err) {
            if (err) reject(err);
            else resolve(this);
        });
    });
}

function getQuery(db, sql, params = []) {
    return new Promise((resolve, reject) => {
        db.get(sql, params, (err, row) => {
            if (err) reject(err);
            else resolve(row);
        });
    });
}

async function runMigrations() {
    console.log('🚀 Starting database migrations...\n');
    
    // Check if database exists
    if (!fs.existsSync(dbPath)) {
        console.error('❌ Database file not found:', dbPath);
        console.error('Please run the application first to initialize the database.');
        process.exit(1);
    }

    const db = new sqlite3.Database(dbPath, (err) => {
        if (err) {
            console.error('❌ Error opening database:', err.message);
            process.exit(1);
        }
    });

    try {
        // Enable foreign keys
        await runQuery(db, 'PRAGMA foreign_keys = ON');
        
        // Create migrations table if it doesn't exist
        await runQuery(db, `
            CREATE TABLE IF NOT EXISTS schema_migrations (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                migration_name TEXT UNIQUE NOT NULL,
                applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
            )
        `);
        
        // Get list of applied migrations
        const appliedMigrations = await new Promise((resolve, reject) => {
            db.all('SELECT migration_name FROM schema_migrations', [], (err, rows) => {
                if (err) reject(err);
                else resolve(rows.map(r => r.migration_name));
            });
        });
        
        console.log('📋 Applied migrations:', appliedMigrations.length > 0 ? appliedMigrations.join(', ') : 'none');
        
        // Get all migration files
        const migrationFiles = fs.readdirSync(migrationsDir)
            .filter(f => f.endsWith('.sql'))
            .sort();
        
        console.log('📁 Found migration files:', migrationFiles.length, '\n');
        
        // Run pending migrations
        for (const file of migrationFiles) {
            if (appliedMigrations.includes(file)) {
                console.log(`⏭️  Skipping ${file} (already applied)`);
                continue;
            }
            
            console.log(`🔧 Applying ${file}...`);
            
            const migrationPath = path.join(migrationsDir, file);
            const sql = fs.readFileSync(migrationPath, 'utf8');
            
            try {
                // Execute migration in a transaction
                await runQuery(db, 'BEGIN TRANSACTION');
                
                // Split by semicolon and execute each statement
                const statements = sql
                    .split(';')
                    .map(s => s.trim())
                    .filter(s => s.length > 0 && !s.startsWith('--'));
                
                for (const statement of statements) {
                    await runQuery(db, statement);
                }
                
                // Record migration
                await runQuery(db, 
                    'INSERT INTO schema_migrations (migration_name) VALUES (?)',
                    [file]
                );
                
                await runQuery(db, 'COMMIT');
                console.log(`✅ Successfully applied ${file}\n`);
                
            } catch (error) {
                await runQuery(db, 'ROLLBACK');
                console.error(`❌ Error applying ${file}:`, error.message);
                throw error;
            }
        }
        
        console.log('\n✨ All migrations completed successfully!');
        
    } catch (error) {
        console.error('\n💥 Migration failed:', error);
        process.exit(1);
    } finally {
        db.close();
    }
}

// Run if executed directly
if (require.main === module) {
    runMigrations().catch(error => {
        console.error('Fatal error:', error);
        process.exit(1);
    });
}

module.exports = { runMigrations };
