let moment = require('moment');

module.exports = {
  friendlyName: 'Login',
  description: 'Login auth.',

  inputs: {
    username: {
      type: 'string',
      required: true
    },
    password: {
      type: 'string',
      required: true
    },
    email: {
      type: 'string',
    }
  },

  exits: {
    notFound: {
      description: 'User not found',
      statusCode: 404
    },
    encryptionError: {
      statusCode: 500
    },
    error: {
      description: 'Une erreur est survenue',
      statusCode: 500
    }
  },

  fn: async function ({ username, password, email }, exits) {
    let ouestDate = moment.utc(new Date()).utcOffset('+01:00');
    let date = ouestDate.format('YYYY-MM-DD');
    let heure = ouestDate.format('HH:mm:ss');
    try {
      // Encrypt password avec le nouveau format AES
      let encryptedPassword = await new Promise((resolve, reject) => {
        sails.config.cryptoUtils.encrypt(password, (err, encryptedPassword) => {
          if (err) {
            reject('encryptionError');
          } else {
            resolve(encryptedPassword);
          }
        });
      });

      if (username === '' || password === '') {
        await ActivityLogs.create({
          date,
          heure,
          username,
          action: "CONNEXION",
          status: "failed",
          errorMessage: "Champs manquants",
          device: "Web"
        });
        return exits.notFound('Veuillez renseigner tous les champs');
      }

      // 1. Recherche de l'utilisateur avec le nouveau format AES
      let user = await Utilisateurs.findOne({ 
        login: username, 
        password: encryptedPassword, 
        desactiverCompte: false 
      });

      // 2. Si l'utilisateur n'est pas trouvé, essayer avec l'ancien format DES
      if (!user) {
        try {
          console.log(`🔄 Tentative de migration automatique pour ${username}`);
          
          // Essayer de déchiffrer avec l'ancien algorithme DES
          const oldEncryptedPassword = await new Promise((resolve, reject) => {
            // Utiliser l'ancienne configuration DES
            const oldCryptoConfig = {
              password: 'EsupportL@chef@2020',
              iterations: 20,
              salt: Buffer.from('de331012de331012', 'hex'),

              KDF: function (password, salt, iterations) {
                var pwd = Buffer.from(password, 'utf-8');
                var key = Buffer.concat([pwd, salt]);
                var i;
                for (i = 0; i < iterations; i += 1) {
                  key = require('crypto').createHash("md5").update(key).digest();
                }
                return key;
              },

              getKeyIV: function (password, salt, iterations) {
                var key = this.KDF(password, salt, iterations);
                var keybuf = Buffer.from(key, 'binary').slice(0, 8);
                var ivbuf = Buffer.from(key, 'binary').slice(8, 16);
                return [keybuf, ivbuf];
              },

              encrypt: function (payload) {
                var kiv = this.getKeyIV(this.password, this.salt, this.iterations);
                var cipher = require('crypto').createCipheriv('des', kiv[0], kiv[1]);
                var encrypted = [];
                encrypted.push(cipher.update(payload, 'utf-8', 'hex'));
                encrypted.push(cipher.final('hex'));
                return Buffer.from(encrypted.join(''), 'hex').toString('base64');
              }
            };

            resolve(oldCryptoConfig.encrypt(password));
          });

          // Rechercher avec l'ancien format DES
          user = await Utilisateurs.findOne({
            login: username,
            password: oldEncryptedPassword,
            desactiverCompte: false
          });

          // Si trouvé, migrer automatiquement vers AES
          if (user) {
            console.log(`🔄 Migration automatique du mot de passe pour ${user.login} (Web)`);

            // Mettre à jour le mot de passe avec le nouveau format AES
            await Utilisateurs.updateOne({ id: user.id })
              .set({ password: encryptedPassword });

            console.log(`✅ Mot de passe migré avec succès pour ${user.login} (Web)`);
          }
        } catch (migrationError) {
          console.log(`⚠️  Erreur lors de la migration automatique (Web):`, migrationError.message);
          // Continuer sans migration automatique
        }
      }

      // 3. Vérification finale de l'utilisateur
      if (!user) {
        await ActivityLogs.create({
          date,
          heure,
          username,
          action: "CONNEXION",
          status: "failed",
          errorMessage: "Utilisateur non trouvé",
          device: "Web"
        });
        return exits.notFound('Utilisateur non trouvé');
      }

      // mise a jour mail si renseigné
      if(email){
        await Utilisateurs.updateOne({ id: user.id })
        .set({
          email: email,
        });
      }

      // Create token
      let token = await sails.helpers.jwt.sign.with({ payload: user });
      if (!token) {
        await ActivityLogs.create({
          date,
          heure,
          username,
          action: "CONNEXION",
          status: "failed",
          errorMessage: "Token non généré",
          device: "Web"
        });
        throw 'signInFailed';
      }

      await Token.create({ token_salt: token, owner: user.id }).fetch();

      // Create activity log (succès)
      await ActivityLogs.create({
        date,
        heure,
        username: user.login,
        action: "CONNEXION",
        status: "success",
        errorMessage: null,
        device: "Web"
      }).fetch();

      // Get school info
      let ecole = await Ecoles.findOne({ codeEcole: user.codeEcole });

      // Prepare response
      let auth = _.merge(user, {
        tokenSalt: token,
        ecole: ecole
      });

      return exits.success(auth);
    } catch (err) {
      sails.log.error('Erreur lors de la connexion:', err);
      await ActivityLogs.create({
        date,
        heure,
        username,
        action: "CONNEXION",
        status: "failed",
        errorMessage: (typeof err === 'string' ? err : (err && err.message) || 'Erreur inconnue'),
        device: "Web"
      });
      return exits.error('Une erreur est survenue lors de la connexion.');
    }
  }
};