'use strict';

/**
 * Migration to add optimized composite index for device allocation queries
 *
 * This index significantly improves the performance of findAndLockFreeDevice
 * by creating a partial index that covers all the columns used in the WHERE clause:
 * - platform
 * - type (real/emulated)
 * - is_busy
 * - is_active
 * - is_flagged
 * - usage (for ORDER BY)
 *
 * The partial index condition (WHERE is_busy = false AND is_active = true AND is_flagged = false)
 * means the index only includes "available" devices, making it much smaller and faster.
 */

// Helper function to safely add an index if it doesn't exist
async function addIndexIfNotExists(queryInterface, tableName, fields, options) {
  try {
    const tableExists = await queryInterface.tableExists(tableName);
    if (!tableExists) {
      return;
    }

    const indexes = await queryInterface.showIndex(tableName);
    const indexName = options.name || `idx_${tableName}_${fields.join('_')}`;
    const indexExists = indexes.some(idx => idx.name === indexName);

    if (!indexExists) {
      await queryInterface.addIndex(tableName, fields, options);
      console.log(`✓ Created index: ${indexName}`);
    } else {
      console.log(`ℹ Index already exists: ${indexName}`);
    }
  } catch (error) {
    if (
      error.message &&
      (error.message.includes('already exists') ||
        error.message.includes('duplicate key value') ||
        (error.message.includes('relation') && error.message.includes('already exists')))
    ) {
      console.log(`ℹ Index already exists (caught): ${options.name}`);
      return;
    }
    throw error;
  }
}

// Helper function to safely remove an index if it exists
async function removeIndexIfExists(queryInterface, tableName, indexName) {
  try {
    const tableExists = await queryInterface.tableExists(tableName);
    if (!tableExists) {
      return;
    }

    const indexes = await queryInterface.showIndex(tableName);
    const indexExists = indexes.some(idx => idx.name === indexName);

    if (indexExists) {
      await queryInterface.removeIndex(tableName, indexName);
      console.log(`✓ Removed index: ${indexName}`);
    } else {
      console.log(`ℹ Index does not exist: ${indexName}`);
    }
  } catch (error) {
    // Ignore if index doesn't exist
    console.log(`ℹ Could not remove index ${indexName}:`, error.message);
  }
}

module.exports = {
  async up(queryInterface, Sequelize) {
    console.log('Adding optimized device allocation index...');

    // Add optimized composite index with partial index condition
    // This index is specifically designed for the device allocation query in findAndLockFreeDevice
    await queryInterface.sequelize.query(`
      CREATE INDEX IF NOT EXISTS idx_devices_allocation_optimized
      ON devices (platform, type, usage)
      WHERE is_busy = false 
        AND is_active = true 
        AND is_flagged = false
    `);

    console.log('✓ Created partial index: idx_devices_allocation_optimized');

    // Note: We keep the existing idx_devices_platform_busy_active index for backward compatibility
    // and for queries that don't filter by type or is_flagged
  },

  async down(queryInterface, Sequelize) {
    console.log('Removing optimized device allocation index...');

    await removeIndexIfExists(queryInterface, 'devices', 'idx_devices_allocation_optimized');

    console.log('✓ Migration rolled back successfully');
  },
};
