import mysql from 'mysql2';
import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
import config from './config.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Create database connection
const connection = mysql.createConnection(config.connection);

// Ensure migrations table exists
function ensureMigrationsTable() {
  const createTableQuery = `
    CREATE TABLE IF NOT EXISTS ${config.tableName} (
      id INT AUTO_INCREMENT PRIMARY KEY,
      name VARCHAR(255) NOT NULL,
      executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )
  `;
  
  return new Promise((resolve, reject) => {
    connection.execute(createTableQuery, (err) => {
      if (err) reject(err);
      else resolve();
    });
  });
}

// Get list of already executed migrations
function getExecutedMigrations() {
  const query = `SELECT name FROM ${config.tableName} ORDER BY executed_at`;
  
  return new Promise((resolve, reject) => {
    connection.execute(query, (err, results) => {
      if (err) reject(err);
      else resolve(results.map(row => row.name));
    });
  });
}

// Execute a migration file
function executeMigration(migrationName, sqlContent) {
  return new Promise((resolve, reject) => {
    connection.execute(sqlContent, (err) => {
      if (err) reject(err);
      else {
        // Log the execution in migrations table
        const logQuery = `INSERT INTO ${config.tableName} (name) VALUES (?)`;
        connection.execute(logQuery, [migrationName], (logErr) => {
          if (logErr) reject(logErr);
          else resolve();
        });
      }
    });
  });
}

// Get all migration files
async function getMigrationFiles() {
  try {
    const files = await fs.readdir(config.migrationsDir);
    return files
      .filter(file => file.endsWith('.sql'))
      .sort((a, b) => a.localeCompare(b));
  } catch (err) {
    if (err.code === 'ENOENT') {
      // Directory doesn't exist, create it
      await fs.mkdir(config.migrationsDir, { recursive: true });
      return [];
    }
    throw err;
  }
}

// Run migrations
async function runMigrations() {
  try {
    await ensureMigrationsTable();
    const executed = await getExecutedMigrations();
    const allMigrations = await getMigrationFiles();
    
    const pending = allMigrations.filter(name => !executed.includes(name));
    
    if (pending.length === 0) {
      console.log('No pending migrations');
      return;
    }
    
    console.log(`Running ${pending.length} migrations...`);
    
    for (const migrationName of pending) {
      console.log(`Executing ${migrationName}`);
      const filePath = path.join(config.migrationsDir, migrationName);
      const sqlContent = await fs.readFile(filePath, 'utf8');
      await executeMigration(migrationName, sqlContent);
    }
    
    console.log('All migrations executed successfully');
  } catch (err) {
    console.error('Error running migrations:', err);
    throw err;
  } finally {
    connection.end();
  }
}

// Run the migrations
if (process.argv.includes('--run')) {
  runMigrations().catch(console.error);
}

export { runMigrations };