import { Sequelize, QueryInterface, QueryTypes, Op } from 'sequelize';
import { throwDeprecation } from 'process';
import Bcrypt from "bcrypt";
import _ from 'lodash';
interface universalIdentifier {
  id: number
}
const date = new Date()

export default {
  up: async (queryInterface: QueryInterface) => {
    const transaction = await queryInterface.sequelize.transaction();
    try {
      const rounds = process.env.HASH_ROUNDS ? +process.env.HASH_ROUNDS : 5;
      const defaultPassword = Bcrypt.hashSync(process.env.DEFAULT_PASSWORD || 'password', rounds);
      let defaultAccount = await queryInterface.sequelize.query(`select id from accounts order by id ASC limit 1`, { type: QueryTypes.SELECT }) as universalIdentifier[];;
      const superAdminData = [
        {
          account_id: defaultAccount[0].id,
          username: process.env.SUPERADMIN_USERNAME || 'superadmin',
          email: process.env.SUPERADMIN_EMAIL || 'superadmin@admin.com',
          country_code: process.env.SUPERADMIN_COUNTRY_CODE || '+91',
          mobile: process.env.SUPERADMIN_MOBILE || '9999999999',
          password: defaultPassword,
          created_at: date,
          updated_at: date,
          status: 1,
          userProfile: {
            name: process.env.SUPERADMIN_NAME || 'Super Administrator'
          },
          userSetting: {
            two_factor_authentication: false,
          }
        }
      ];
      const adminData = [
        {
          account_id: defaultAccount[0].id,
          username: process.env.ADMIN_USERNAME || 'admin',
          email: process.env.ADMIN_EMAIL || 'admin@admin.com',
          country_code: process.env.ADMIN_COUNTRY_CODE || '+91',
          mobile: process.env.ADMIN_MOBILE || '9999999998',
          password: defaultPassword,
          created_at: date,
          updated_at: date,
          status: 1,
          userProfile: {
            name: process.env.ADMIN_NAME || 'Administrator'
          },
          userSetting: {
            two_factor_authentication: false,
          }
        }
      ];
      let initializedState = await queryInterface.sequelize.query(`select id from users order by id ASC limit 1`, { type: QueryTypes.SELECT });
      if (initializedState.length == 0 || initializedState.length > 0) {

        let offset = 0;
        let superAdminRole = await queryInterface.sequelize.query(`select id from roles where code='superadmin' limit 1`, { type: QueryTypes.SELECT }) as universalIdentifier[];
        let adminRole = await queryInterface.sequelize.query(`select id from roles where code='admin' limit 1`, { type: QueryTypes.SELECT }) as universalIdentifier[];
        let instructorRole = await queryInterface.sequelize.query(`select id from roles where code='instructor' limit 1`, { type: QueryTypes.SELECT }) as universalIdentifier[];
        for (let userData of superAdminData) {
          let userDetails = _.pick(userData, ['account_id', 'username', 'email', 'status', 'country_code', 'mobile', 'password', 'created_at', 'updated_at']);
          await queryInterface.bulkInsert('users', [userDetails], { transaction: transaction });
          let user = await queryInterface.sequelize.query(`select id from users order by id ASC limit ${offset},1`, { type: QueryTypes.SELECT, transaction: transaction }) as universalIdentifier[];
          if (user.length && user[0].id) {
            let userProfile = { ...userData.userProfile, ...{ user_id: user[0].id, created_at: date, updated_at: date } }
            let userSetting = { ...userData.userSetting, ...{ user_id: user[0].id, created_at: date, updated_at: date } }
            let userRoles = [
              { account_id: defaultAccount[0].id, user_id: user[0].id, role_id: adminRole[0].id, created_at: date, updated_at: date },
              { account_id: defaultAccount[0].id, user_id: user[0].id, role_id: superAdminRole[0].id, created_at: date, updated_at: date }
            ]
            let userAccounts = { account_id: defaultAccount[0].id, user_id: user[0].id, is_default: true, created_at: date, updated_at: date }
            await queryInterface.bulkInsert('user_profile', [userProfile], { transaction: transaction });
            await queryInterface.bulkInsert('user_setting', [userSetting], { transaction: transaction });
            await queryInterface.bulkInsert('user_roles', userRoles, { transaction: transaction });
            await queryInterface.bulkInsert('user_accounts', [userAccounts], { transaction: transaction });
          }
          offset++;
        }
        for (let userData of adminData) {
          let userDetails = _.pick(userData, ['account_id', 'username', 'email', 'status', 'country_code', 'mobile', 'password', 'created_at', 'updated_at']);
          await queryInterface.bulkInsert('users', [userDetails], { transaction: transaction });
          let user = await queryInterface.sequelize.query(`select id from users order by id ASC limit ${offset},1`, { type: QueryTypes.SELECT, transaction: transaction }) as universalIdentifier[];
          if (user.length && user[0].id) {
            let userProfile = { ...userData.userProfile, ...{ user_id: user[0].id, created_at: date, updated_at: date } }
            let userSetting = { ...userData.userSetting, ...{ user_id: user[0].id, created_at: date, updated_at: date } }
            let userRoles = [
              { account_id: defaultAccount[0].id, user_id: user[0].id, role_id: adminRole[0].id, created_at: date, updated_at: date },
            ]
            let userAccounts = { account_id: defaultAccount[0].id, user_id: user[0].id, is_default: true, created_at: date, updated_at: date }
            await queryInterface.bulkInsert('user_profile', [userProfile], { transaction: transaction });
            await queryInterface.bulkInsert('user_setting', [userSetting], { transaction: transaction });
            await queryInterface.bulkInsert('user_roles', userRoles, { transaction: transaction });
            await queryInterface.bulkInsert('user_accounts', [userAccounts], { transaction: transaction });
          }
          offset++;
        }
        await transaction.commit();
      } else {
        await transaction.rollback();
        console.log("system already initialized")
      }
    } catch (err) {
      await transaction.rollback();
    }
  },
  down: async (queryInterface: QueryInterface) => {
    await queryInterface.bulkDelete('users', { id: { [Op.gt]: 0 } });
  },
};
