'use strict';

// Helper function to safely create a table if it doesn't exist
async function createTableIfNotExists(queryInterface, tableName, tableDefinition) {
  const tableExists = await queryInterface.tableExists(tableName);
  if (!tableExists) {
    await queryInterface.createTable(tableName, tableDefinition);
  }
}

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

    // Check if index already exists
    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);
    }
  } catch (error) {
    // If index already exists, ignore the 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;
    }
    // For other errors, try to add the index anyway (might be a different issue)
    // If it fails, the error will be more informative
    try {
      await queryInterface.addIndex(tableName, fields, options);
    } catch (addError) {
      // If it's still an "already exists" error, ignore it
      if (
        addError.message &&
        (addError.message.includes('already exists') ||
          addError.message.includes('duplicate key value') ||
          (addError.message.includes('relation') && addError.message.includes('already exists')))
      ) {
        return;
      }
      throw addError;
    }
  }
}

module.exports = {
  async up(queryInterface, Sequelize) {
    await this.createOrganisationsTable(queryInterface, Sequelize);
    await this.createRolesTable(queryInterface, Sequelize);
    await this.createUsersTable(queryInterface, Sequelize);
    await this.createTeamsTable(queryInterface, Sequelize);
    await this.createTeamUsersTable(queryInterface, Sequelize);
    await this.createNodesTable(queryInterface, Sequelize);
    await this.createNodeConnectionsTable(queryInterface, Sequelize);
    await this.createDevicesTable(queryInterface, Sequelize);
    await this.createTeamDevicesTable(queryInterface, Sequelize);
    await this.createBuildsTable(queryInterface, Sequelize);
    await this.createSessionsTable(queryInterface, Sequelize);
    await this.createWebRtcConnectionsTable(queryInterface, Sequelize);
    await this.createUploadedAppsTable(queryInterface, Sequelize);
  },

  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('uploaded_apps');
    await queryInterface.dropTable('webrtc_connections');
    await queryInterface.dropTable('sessions');
    await queryInterface.dropTable('builds');
    await queryInterface.dropTable('team_devices');
    await queryInterface.dropTable('devices');
    await queryInterface.dropTable('node_connections');
    await queryInterface.dropTable('nodes');
    await queryInterface.dropTable('team_users');
    await queryInterface.dropTable('teams');
    await queryInterface.dropTable('users');
    await queryInterface.dropTable('roles');
    await queryInterface.dropTable('organizations');
  },

  async createBuildsTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'builds', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      organization_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'organizations',
          key: 'id',
        },
      },
      created_by: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'users',
          key: 'id',
        },
      },
      name: {
        type: Sequelize.STRING,
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for builds table
    await addIndexIfNotExists(queryInterface, 'builds', ['organization_id'], {
      name: 'idx_builds_organization_id',
    });
    await addIndexIfNotExists(queryInterface, 'builds', ['created_by'], {
      name: 'idx_builds_created_by',
    });
    await addIndexIfNotExists(queryInterface, 'builds', ['created_at'], {
      name: 'idx_builds_created_at',
    });
  },

  async createSessionsTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'sessions', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      session_id: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true,
        comment: 'The actual Appium session ID from the node',
      },
      session_type: {
        type: Sequelize.STRING,
        allowNull: false,
        comment: 'Type of session: automation or manual',
      },
      build_id: {
        type: Sequelize.UUID,
        allowNull: true,
        references: {
          model: 'builds',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
        comment: 'Only for automation sessions, can be null for manual sessions',
      },
      node_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'nodes',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      device_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'devices',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      created_by: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'users',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
        comment: 'User who created this session',
      },
      name: {
        type: Sequelize.STRING,
        allowNull: true,
      },
      status: {
        type: Sequelize.STRING,
        allowNull: false,
        defaultValue: 'running',
        comment: 'running, completed, failed, interrupted, timeout, node_disconnected',
      },
      requested_capabilities: {
        type: Sequelize.TEXT,
        allowNull: false,
        comment: 'Requested capabilities in JSON format',
      },
      session_capabilities: {
        type: Sequelize.TEXT,
        allowNull: false,
        comment: 'Actual session capabilities in JSON format',
      },
      video_recording: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Path or URL to video recording',
      },
      device_logs: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Path or URL to device logs',
      },
      app_profiling: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'App profiling data (mainly for automation)',
      },
      screenshots: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'JSON array of screenshot URLs',
      },
      start_time: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      end_time: {
        type: Sequelize.DATE,
        allowNull: true,
      },
      last_activity_at: {
        type: Sequelize.DATE,
        allowNull: false,
        defaultValue: Sequelize.NOW,
        comment: 'Last activity timestamp - updated on every WebDriver command',
      },
      remarks: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      failure_reason: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Reason why session failed or was interrupted',
      },
      metadata: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Additional session metadata in JSON format',
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for sessions table
    await addIndexIfNotExists(queryInterface, 'sessions', ['session_id'], {
      name: 'idx_sessions_session_id',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['device_id'], {
      name: 'idx_sessions_device_id',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['node_id'], {
      name: 'idx_sessions_node_id',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['session_type'], {
      name: 'idx_sessions_session_type',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['status'], {
      name: 'idx_sessions_status',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['created_by'], {
      name: 'idx_sessions_created_by',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['last_activity_at'], {
      name: 'idx_sessions_last_activity_at',
    });
    await addIndexIfNotExists(queryInterface, 'sessions', ['start_time'], {
      name: 'idx_sessions_start_time',
    });
    // Composite index for common query: find running sessions by type
    await addIndexIfNotExists(queryInterface, 'sessions', ['status', 'session_type'], {
      name: 'idx_sessions_status_type',
    });
  },

  async createWebRtcConnectionsTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'webrtc_connections', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      session_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'sessions',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
        comment: 'Manual session this WebRTC connection belongs to',
      },
      user_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'users',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
        comment: 'User viewing the device',
      },
      connection_state: {
        type: Sequelize.STRING,
        allowNull: false,
        defaultValue: 'new',
        comment: 'new, connecting, connected, disconnected, failed, closed',
      },
      offer_sdp: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'SDP offer from browser - stores codecs, ICE info, media capabilities',
      },
      answer_sdp: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'SDP answer from node - stores accepted codecs and connection info',
      },
      last_heartbeat_at: {
        type: Sequelize.DATE,
        allowNull: false,
        defaultValue: Sequelize.NOW,
        comment: 'Last heartbeat from browser - used for timeout detection',
      },
      heartbeat_timeout_seconds: {
        type: Sequelize.INTEGER,
        allowNull: false,
        defaultValue: 120,
        comment: 'How long to wait before considering connection dead (default 2 minutes)',
      },
      user_agent: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Browser user agent string',
      },
      ip_address: {
        type: Sequelize.STRING,
        allowNull: true,
        comment: 'User IP address',
      },
      browser_info: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Browser type, version, OS in JSON format',
      },
      connection_quality: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Bandwidth, latency, packet loss, frame rate in JSON format',
      },
      connected_at: {
        type: Sequelize.DATE,
        allowNull: true,
        comment: 'When WebRTC peer connection was established',
      },
      disconnected_at: {
        type: Sequelize.DATE,
        allowNull: true,
        comment: 'When connection was lost or closed',
      },
      disconnection_reason: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Why connection ended: timeout, user_closed, node_disconnected, error, etc.',
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for webrtc_connections table
    await addIndexIfNotExists(queryInterface, 'webrtc_connections', ['session_id'], {
      name: 'idx_webrtc_connections_session_id',
    });
    await addIndexIfNotExists(queryInterface, 'webrtc_connections', ['user_id'], {
      name: 'idx_webrtc_connections_user_id',
    });
    await addIndexIfNotExists(queryInterface, 'webrtc_connections', ['connection_state'], {
      name: 'idx_webrtc_connections_state',
    });
    await addIndexIfNotExists(queryInterface, 'webrtc_connections', ['last_heartbeat_at'], {
      name: 'idx_webrtc_connections_last_heartbeat',
    });
    await addIndexIfNotExists(queryInterface, 'webrtc_connections', ['created_at'], {
      name: 'idx_webrtc_connections_created_at',
    });
    // Composite index: Find active WebRTC connections for a session (critical query)
    await addIndexIfNotExists(
      queryInterface,
      'webrtc_connections',
      ['session_id', 'connection_state'],
      {
        name: 'idx_webrtc_connections_session_state',
      }
    );
    // Composite index: Find stale connections needing timeout
    await addIndexIfNotExists(
      queryInterface,
      'webrtc_connections',
      ['connection_state', 'last_heartbeat_at'],
      {
        name: 'idx_webrtc_connections_state_heartbeat',
      }
    );
  },

  async createUploadedAppsTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'uploaded_apps', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      app_name: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      path: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      platform: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      file_size: {
        type: Sequelize.STRING,
        allowNull: false,
        defaultValue: '0',
      },
      app_bundle_id: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      created_by: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'users',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for uploaded_apps table
    await addIndexIfNotExists(queryInterface, 'uploaded_apps', ['created_by'], {
      name: 'idx_uploaded_apps_created_by',
    });
    await addIndexIfNotExists(queryInterface, 'uploaded_apps', ['platform'], {
      name: 'idx_uploaded_apps_platform',
    });
    await addIndexIfNotExists(queryInterface, 'uploaded_apps', ['app_bundle_id'], {
      name: 'idx_uploaded_apps_bundle_id',
    });
    await addIndexIfNotExists(queryInterface, 'uploaded_apps', ['created_at'], {
      name: 'idx_uploaded_apps_created_at',
    });
  },

  async createUsersTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'users', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      firstname: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      organization_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'organizations',
          key: 'id',
        },
      },
      role_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'roles',
          key: 'id',
        },
      },
      lastname: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      email: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true,
      },
      password: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      is_active: {
        type: Sequelize.BOOLEAN,
        allowNull: false,
        defaultValue: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      access_key: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true,
      },
      token: {
        type: Sequelize.STRING,
        allowNull: true,
      },
      token_expires_at: {
        type: Sequelize.DATE,
        allowNull: true,
      },
    });

    // Add indexes for users table
    await addIndexIfNotExists(queryInterface, 'users', ['email'], {
      name: 'idx_users_email',
    });
    await addIndexIfNotExists(queryInterface, 'users', ['access_key'], {
      name: 'idx_users_access_key',
    });
    await addIndexIfNotExists(queryInterface, 'users', ['organization_id'], {
      name: 'idx_users_organization_id',
    });
    await addIndexIfNotExists(queryInterface, 'users', ['role_id'], {
      name: 'idx_users_role_id',
    });
    await addIndexIfNotExists(queryInterface, 'users', ['is_active'], {
      name: 'idx_users_is_active',
    });
  },

  async createTeamsTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'teams', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      organization_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'organizations',
          key: 'id',
        },
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true,
      },
      description: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for teams table
    await addIndexIfNotExists(queryInterface, 'teams', ['name'], {
      name: 'idx_teams_name',
    });
    await addIndexIfNotExists(queryInterface, 'teams', ['organization_id'], {
      name: 'idx_teams_organization_id',
    });
  },

  async createNodesTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'nodes', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      tags: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      os: {
        type: Sequelize.STRING, // windows, mac, linux
        allowNull: false,
      },
      is_online: {
        type: Sequelize.BOOLEAN,
        allowNull: false,
        defaultValue: true,
      },
      added_by: {
        type: Sequelize.UUID,
        allowNull: true,
        references: {
          model: 'users',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      current_socket_id: {
        type: Sequelize.STRING,
        allowNull: true,
        comment: 'Current WebSocket connection ID',
      },
      last_heartbeat_at: {
        type: Sequelize.DATE,
        allowNull: true,
        comment: 'Last heartbeat received from this node',
      },
      last_connected_at: {
        type: Sequelize.DATE,
        allowNull: true,
        comment: 'When the current connection was established',
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for nodes table
    await addIndexIfNotExists(queryInterface, 'nodes', ['is_online'], {
      name: 'idx_nodes_is_online',
    });
    await addIndexIfNotExists(queryInterface, 'nodes', ['os'], {
      name: 'idx_nodes_os',
    });
    await addIndexIfNotExists(queryInterface, 'nodes', ['last_heartbeat_at'], {
      name: 'idx_nodes_last_heartbeat_at',
    });
    await addIndexIfNotExists(queryInterface, 'nodes', ['current_socket_id'], {
      name: 'idx_nodes_current_socket_id',
    });
  },

  async createNodeConnectionsTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'node_connections', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      node_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'nodes',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      connection_state: {
        type: Sequelize.STRING,
        allowNull: false,
        defaultValue: 'connecting',
        comment: 'connecting, connected, disconnecting, disconnected, reconnecting',
      },
      socket_id: {
        type: Sequelize.STRING,
        allowNull: true,
        comment: 'Socket.io connection ID',
      },
      ip_address: {
        type: Sequelize.STRING,
        allowNull: true,
      },
      last_heartbeat_at: {
        type: Sequelize.DATE,
        allowNull: false,
        defaultValue: Sequelize.NOW,
      },
      connected_at: {
        type: Sequelize.DATE,
        allowNull: true,
      },
      disconnected_at: {
        type: Sequelize.DATE,
        allowNull: true,
      },
      disconnection_reason: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Reason for disconnection if known',
      },
      connection_metadata: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Additional connection metadata in JSON format',
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for node_connections table
    await addIndexIfNotExists(queryInterface, 'node_connections', ['node_id'], {
      name: 'idx_node_connections_node_id',
    });
    await addIndexIfNotExists(queryInterface, 'node_connections', ['connection_state'], {
      name: 'idx_node_connections_state',
    });
    await addIndexIfNotExists(queryInterface, 'node_connections', ['last_heartbeat_at'], {
      name: 'idx_node_connections_last_heartbeat',
    });
    await addIndexIfNotExists(queryInterface, 'node_connections', ['connected_at'], {
      name: 'idx_node_connections_connected_at',
    });
    await addIndexIfNotExists(queryInterface, 'node_connections', ['socket_id'], {
      name: 'idx_node_connections_socket_id',
    });
    // Composite index for finding active connections
    await addIndexIfNotExists(queryInterface, 'node_connections', ['node_id', 'connection_state'], {
      name: 'idx_node_connections_node_state',
    });
  },

  async createDevicesTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'devices', {
      id: {
        type: Sequelize.UUID,
        primaryKey: true,
      },
      udid: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      node_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'nodes',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      platform: {
        type: Sequelize.STRING, // android, ios, tv_os
        allowNull: false,
      },
      version: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      tags: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      type: {
        type: Sequelize.STRING, // emulated, real
        allowNull: false,
      },
      is_active: {
        type: Sequelize.BOOLEAN,
        allowNull: false,
        defaultValue: true,
      },
      is_flagged: {
        type: Sequelize.BOOLEAN,
        allowNull: false,
        defaultValue: false,
      },
      flagged_reason: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      usage: {
        type: Sequelize.INTEGER,
        allowNull: false,
        defaultValue: 0,
      },
      metadata: {
        type: Sequelize.TEXT,
        allowNull: true,
        comment: 'Additional device metadata in JSON format',
      },
      is_busy: {
        type: Sequelize.BOOLEAN,
        allowNull: false,
        defaultValue: false,
      },
      active_session_id: {
        type: Sequelize.UUID,
        allowNull: true,
        comment: 'Current active session ID - no foreign key to avoid circular dependency',
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for devices table
    await addIndexIfNotExists(queryInterface, 'devices', ['udid'], {
      name: 'idx_devices_udid',
    });
    await addIndexIfNotExists(queryInterface, 'devices', ['node_id'], {
      name: 'idx_devices_node_id',
    });
    await addIndexIfNotExists(queryInterface, 'devices', ['platform'], {
      name: 'idx_devices_platform',
    });
    await addIndexIfNotExists(queryInterface, 'devices', ['is_busy'], {
      name: 'idx_devices_is_busy',
    });
    await addIndexIfNotExists(queryInterface, 'devices', ['is_active'], {
      name: 'idx_devices_is_active',
    });
    await addIndexIfNotExists(queryInterface, 'devices', ['is_flagged'], {
      name: 'idx_devices_is_flagged',
    });
    await addIndexIfNotExists(queryInterface, 'devices', ['active_session_id'], {
      name: 'idx_devices_active_session_id',
    });
    // Composite indexes for common queries
    await addIndexIfNotExists(queryInterface, 'devices', ['platform', 'is_busy', 'is_active'], {
      name: 'idx_devices_platform_busy_active',
    });
    await addIndexIfNotExists(queryInterface, 'devices', ['node_id', 'is_active'], {
      name: 'idx_devices_node_active',
    });
  },

  async createTeamUsersTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'team_users', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      user_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'users',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      team_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'teams',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for team_users table
    await addIndexIfNotExists(queryInterface, 'team_users', ['user_id'], {
      name: 'idx_team_users_user_id',
    });
    await addIndexIfNotExists(queryInterface, 'team_users', ['team_id'], {
      name: 'idx_team_users_team_id',
    });
    // Composite unique index to prevent duplicate user-team pairs
    await addIndexIfNotExists(queryInterface, 'team_users', ['user_id', 'team_id'], {
      name: 'idx_team_users_user_team_unique',
      unique: true,
    });
  },

  async createTeamDevicesTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'team_devices', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      device_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'devices',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      team_id: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'teams',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE',
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for team_devices table
    await addIndexIfNotExists(queryInterface, 'team_devices', ['device_id'], {
      name: 'idx_team_devices_device_id',
    });
    await addIndexIfNotExists(queryInterface, 'team_devices', ['team_id'], {
      name: 'idx_team_devices_team_id',
    });
    // Composite unique index to prevent duplicate device-team pairs
    await addIndexIfNotExists(queryInterface, 'team_devices', ['device_id', 'team_id'], {
      name: 'idx_team_devices_device_team_unique',
      unique: true,
    });
  },

  async createOrganisationsTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'organizations', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true,
      },
      description: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for organizations table
    await addIndexIfNotExists(queryInterface, 'organizations', ['name'], {
      name: 'idx_organizations_name',
    });
  },

  async createRolesTable(queryInterface, Sequelize) {
    await createTableIfNotExists(queryInterface, 'roles', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      name: {
        type: Sequelize.STRING, //SUPER_ADMIN, ADMIN, USER
        allowNull: false,
        unique: true,
      },
      description: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });

    // Add indexes for roles table
    await addIndexIfNotExists(queryInterface, 'roles', ['name'], {
      name: 'idx_roles_name',
    });
  },
};
