import { DataTypes, Op } from 'sequelize';

export default {
  up: async (queryInterface) => {
    const transaction = await queryInterface.sequelize.transaction();

    try {
      await queryInterface.createTable('config_settings', {
        id: {
          type: DataTypes.UUID,
          defaultValue: DataTypes.UUIDV4,
          primaryKey: true
        },
        scope: {
          type: DataTypes.ENUM('SYSTEM', 'PROJECT', 'USER'),
          allowNull: false
        },
        scopeId: {
          type: DataTypes.UUID,
          allowNull: true,
          field: 'scope_id'
        },
        key: {
          type: DataTypes.STRING,
          allowNull: false
        },
        value: {
          type: DataTypes.JSONB,
          allowNull: false
        },
        isSecret: {
          type: DataTypes.BOOLEAN,
          defaultValue: false,
          field: 'is_secret'
        },
        schemaVersion: {
          type: DataTypes.INTEGER,
          defaultValue: 1,
          field: 'schema_version'
        },
        createdAt: {
          type: DataTypes.DATE,
          allowNull: false,
          defaultValue: DataTypes.NOW,
          field: 'created_at'
        },
        updatedAt: {
          type: DataTypes.DATE,
          allowNull: false,
          defaultValue: DataTypes.NOW,
          field: 'updated_at'
        }
      }, { transaction });

      // Create a unique index that handles the NULL scope_id for SYSTEM scope correctly
      // In Postgres 15+ we could use NULLS NOT DISTINCT, but for compatibility we use a partial index
      // for the NULL case and a standard unique index for the non-NULL case.

      // 1. Standard unique constraint for non-null scope_id (Project/User)
      await queryInterface.addIndex('config_settings', ['scope', 'scope_id', 'key'], {
        unique: true,
        where: {
          scope_id: { [Op.ne]: null }
        },
        name: 'config_settings_scope_scope_id_key_unique',
        transaction
      });

      // 2. Unique constraint for SYSTEM scope (where scope_id is NULL)
      await queryInterface.addIndex('config_settings', ['scope', 'key'], {
        unique: true,
        where: {
          scope_id: null
        },
        name: 'config_settings_system_scope_key_unique',
        transaction
      });

      await transaction.commit();
    } catch (err) {
      await transaction.rollback();
      throw err;
    }
  },

  down: async (queryInterface) => {
    const transaction = await queryInterface.sequelize.transaction();
    try {
      await queryInterface.dropTable('config_settings', { transaction });
      await queryInterface.sequelize.query('DROP TYPE IF EXISTS "enum_config_settings_scope";', { transaction });
      await transaction.commit();
    } catch (err) {
      await transaction.rollback();
      throw err;
    }
  }
};
