'use strict';

// Helper function to safely add column if it doesn't exist
async function addColumnIfNotExists(queryInterface, tableName, columnName, columnDefinition) {
  try {
    const tableDescription = await queryInterface.describeTable(tableName);
    if (!tableDescription[columnName]) {
      await queryInterface.addColumn(tableName, columnName, columnDefinition);
      console.log(`✅ Added column ${columnName} to ${tableName}`);
    }
  } catch (error) {
    console.log(`⚠️  Could not add column ${columnName} to ${tableName}:`, error.message);
  }
}

// Helper function to safely remove column if it exists
async function removeColumnIfExists(queryInterface, tableName, columnName) {
  try {
    const tableDescription = await queryInterface.describeTable(tableName);
    if (tableDescription[columnName]) {
      await queryInterface.removeColumn(tableName, columnName);
      console.log(`✅ Removed column ${columnName} from ${tableName}`);
    }
  } catch (error) {
    console.log(`⚠️  Could not remove column ${columnName} from ${tableName}:`, error.message);
  }
}

// Helper function to safely add an index if it doesn't exist
async function addIndexIfNotExists(queryInterface, tableName, fields, options) {
  try {
    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(`✅ Added index ${indexName} to ${tableName}`);
    }
  } 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')))
    ) {
      return;
    }
    console.log(`⚠️  Could not add index to ${tableName}:`, error.message);
  }
}

module.exports = {
  async up(queryInterface, Sequelize) {
    console.log('\n🚀 Starting migration to storage_assets pattern...\n');

    // =====================================================
    // SESSIONS TABLE
    // =====================================================
    console.log('📋 Updating sessions table...');

    // Add new asset FK columns
    await addColumnIfNotExists(queryInterface, 'sessions', 'video_recording_asset_id', {
      type: Sequelize.UUID,
      allowNull: true,
      references: {
        model: 'storage_assets',
        key: 'id',
      },
      onUpdate: 'CASCADE',
      onDelete: 'SET NULL',
      comment: 'Foreign key to storage_assets for video recording',
    });

    await addColumnIfNotExists(queryInterface, 'sessions', 'device_logs_asset_id', {
      type: Sequelize.UUID,
      allowNull: true,
      references: {
        model: 'storage_assets',
        key: 'id',
      },
      onUpdate: 'CASCADE',
      onDelete: 'SET NULL',
      comment: 'Foreign key to storage_assets for device logs',
    });

    await addColumnIfNotExists(queryInterface, 'sessions', 'appium_logs_asset_id', {
      type: Sequelize.UUID,
      allowNull: true,
      references: {
        model: 'storage_assets',
        key: 'id',
      },
      onUpdate: 'CASCADE',
      onDelete: 'SET NULL',
      comment: 'Foreign key to storage_assets for appium logs',
    });

    await addColumnIfNotExists(queryInterface, 'sessions', 'session_log_asset_id', {
      type: Sequelize.UUID,
      allowNull: true,
      references: {
        model: 'storage_assets',
        key: 'id',
      },
      onUpdate: 'CASCADE',
      onDelete: 'SET NULL',
      comment: 'Foreign key to storage_assets for session log JSON',
    });

    await addColumnIfNotExists(queryInterface, 'sessions', 'app_profiling_asset_id', {
      type: Sequelize.UUID,
      allowNull: true,
      references: {
        model: 'storage_assets',
        key: 'id',
      },
      onUpdate: 'CASCADE',
      onDelete: 'SET NULL',
      comment: 'Foreign key to storage_assets for app profiling data',
    });

    await addColumnIfNotExists(queryInterface, 'sessions', 'screenshot_asset_ids', {
      type: Sequelize.JSONB,
      allowNull: true,
      comment: 'JSON array of storage_asset UUIDs for screenshots',
    });

    // Add indexes for sessions
    await addIndexIfNotExists(queryInterface, 'sessions', ['video_recording_asset_id'], {
      name: 'idx_sessions_video_recording_asset_id',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['device_logs_asset_id'], {
      name: 'idx_sessions_device_logs_asset_id',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['appium_logs_asset_id'], {
      name: 'idx_sessions_appium_logs_asset_id',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['session_log_asset_id'], {
      name: 'idx_sessions_session_log_asset_id',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['app_profiling_asset_id'], {
      name: 'idx_sessions_app_profiling_asset_id',
    });

    // Remove legacy columns from sessions
    await removeColumnIfExists(queryInterface, 'sessions', 'video_recording');
    await removeColumnIfExists(queryInterface, 'sessions', 'device_logs');
    await removeColumnIfExists(queryInterface, 'sessions', 'app_profiling');
    await removeColumnIfExists(queryInterface, 'sessions', 'screenshots');

    // =====================================================
    // UPLOADED_APPS TABLE
    // =====================================================
    console.log('\n📋 Updating uploaded_apps table...');

    await addColumnIfNotExists(queryInterface, 'uploaded_apps', 'app_binary_asset_id', {
      type: Sequelize.UUID,
      allowNull: true,
      references: {
        model: 'storage_assets',
        key: 'id',
      },
      onUpdate: 'CASCADE',
      onDelete: 'SET NULL',
      comment: 'Foreign key to storage_assets for app binary file',
    });

    await addIndexIfNotExists(queryInterface, 'uploaded_apps', ['app_binary_asset_id'], {
      name: 'idx_uploaded_apps_app_binary_asset_id',
    });

    await removeColumnIfExists(queryInterface, 'uploaded_apps', 'path');

    console.log('\n✅ Migration to storage_assets pattern completed!\n');
  },

  async down(queryInterface, Sequelize) {
    console.log('\n🔄 Rolling back migration to storage_assets pattern...\n');

    // =====================================================
    // SESSIONS TABLE - ROLLBACK
    // =====================================================
    console.log('📋 Restoring sessions table...');

    // Restore legacy columns
    await addColumnIfNotExists(queryInterface, 'sessions', 'video_recording', {
      type: Sequelize.TEXT,
      allowNull: true,
      comment: 'Path or URL to video recording (LEGACY)',
    });

    await addColumnIfNotExists(queryInterface, 'sessions', 'device_logs', {
      type: Sequelize.TEXT,
      allowNull: true,
      comment: 'Path or URL to device logs (LEGACY)',
    });

    await addColumnIfNotExists(queryInterface, 'sessions', 'app_profiling', {
      type: Sequelize.TEXT,
      allowNull: true,
      comment: 'App profiling data (LEGACY)',
    });

    await addColumnIfNotExists(queryInterface, 'sessions', 'screenshots', {
      type: Sequelize.TEXT,
      allowNull: true,
      comment: 'JSON array of screenshot URLs (LEGACY)',
    });

    // Remove asset FK columns
    await removeColumnIfExists(queryInterface, 'sessions', 'screenshot_asset_ids');
    await removeColumnIfExists(queryInterface, 'sessions', 'app_profiling_asset_id');
    await removeColumnIfExists(queryInterface, 'sessions', 'session_log_asset_id');
    await removeColumnIfExists(queryInterface, 'sessions', 'appium_logs_asset_id');
    await removeColumnIfExists(queryInterface, 'sessions', 'device_logs_asset_id');
    await removeColumnIfExists(queryInterface, 'sessions', 'video_recording_asset_id');

    // =====================================================
    // UPLOADED_APPS TABLE - ROLLBACK
    // =====================================================
    console.log('\n📋 Restoring uploaded_apps table...');

    await addColumnIfNotExists(queryInterface, 'uploaded_apps', 'path', {
      type: Sequelize.STRING,
      allowNull: true,
      comment: 'File path (LEGACY)',
    });

    await removeColumnIfExists(queryInterface, 'uploaded_apps', 'app_binary_asset_id');

    console.log('\n✅ Rollback completed!\n');
  },
};
