const fs = require("fs");
const path = require("path");

/**
 * Check for pending database migrations
 *
 * Compares migration files in the filesystem against the SequelizeMeta table
 * to determine which migrations have not yet been executed.
 *
 * @param {Sequelize} sequelize - Sequelize instance
 * @returns {Promise<string[]>} Array of pending migration filenames
 */
async function checkPendingMigrations(sequelize) {
  const migrationsPath = path.resolve(__dirname, "..", "migrations");

  // Get all migration files from filesystem
  const migrationFiles = fs
    .readdirSync(migrationsPath)
    .filter((file) => file.endsWith(".js"))
    .sort();

  // Check if SequelizeMeta table exists
  const [results] = await sequelize.query(`
    SELECT EXISTS (
      SELECT FROM information_schema.tables
      WHERE table_schema = 'public'
      AND table_name = 'SequelizeMeta'
    ) as exists
  `);

  if (!results[0].exists) {
    // No migrations have ever been run
    return migrationFiles;
  }

  // Get executed migrations from SequelizeMeta
  const [executedMigrations] = await sequelize.query(
    'SELECT name FROM "SequelizeMeta" ORDER BY name'
  );

  const executedSet = new Set(executedMigrations.map((row) => row.name));

  // Find migrations that haven't been executed
  const pendingMigrations = migrationFiles.filter(
    (file) => !executedSet.has(file)
  );

  return pendingMigrations;
}

/**
 * Get migration status summary
 *
 * @param {Sequelize} sequelize - Sequelize instance
 * @returns {Promise<{executed: string[], pending: string[]}>} Migration status
 */
async function getMigrationStatus(sequelize) {
  const migrationsPath = path.resolve(__dirname, "..", "migrations");

  const migrationFiles = fs
    .readdirSync(migrationsPath)
    .filter((file) => file.endsWith(".js"))
    .sort();

  // Check if SequelizeMeta table exists
  const [results] = await sequelize.query(`
    SELECT EXISTS (
      SELECT FROM information_schema.tables
      WHERE table_schema = 'public'
      AND table_name = 'SequelizeMeta'
    ) as exists
  `);

  if (!results[0].exists) {
    return {
      executed: [],
      pending: migrationFiles,
    };
  }

  const [executedMigrations] = await sequelize.query(
    'SELECT name FROM "SequelizeMeta" ORDER BY name'
  );

  const executedSet = new Set(executedMigrations.map((row) => row.name));

  return {
    executed: migrationFiles.filter((file) => executedSet.has(file)),
    pending: migrationFiles.filter((file) => !executedSet.has(file)),
  };
}

module.exports = {
  checkPendingMigrations,
  getMigrationStatus,
};
