

var crypto = require('crypto');

module.exports = {

    cryptoUtils: {

        password: 'EsupportL@chef@2020',
        iterations: 100000, // Augmenté pour plus de sécurité
        salt: new Buffer.from('de331012de331012', 'hex'),

        // Option pour forcer l'utilisation de l'ancien algorithme DES
        forceLegacyDES: process.env.FORCE_LEGACY_DES === 'true',

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

            // Étendre la clé pour avoir assez de données pour AES-256 + IV (48 bytes total)
            var extendedKey = crypto.createHash("sha512").update(key).digest(); // 64 bytes
            return extendedKey;
        },

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

        getKeyIV: function (password, salt, iterations) {
            var key = this.KDF(password, salt, iterations);
            var keybuf = key.slice(0, 32); // 32 bytes pour AES-256
            var ivbuf = key.slice(32, 48); // 16 bytes pour IV
            return [keybuf, ivbuf];
        },

        // Ancienne méthode pour DES
        getKeyIV_LEGACY: function (password, salt, iterations) {
            var key = this.KDF_LEGACY(password, salt, iterations);
            var keybuf = new Buffer.from(key, 'binary').slice(0, 8); // 8 bytes pour DES
            var ivbuf = new Buffer.from(key, 'binary').slice(8, 16); // 8 bytes pour IV
            return [keybuf, ivbuf];
        },

        native_encrypt: function (payload, password, salt, iterations, cb) {
            try {
                if (this.forceLegacyDES) {
                    // Utiliser l'ancien algorithme DES
                    var kiv = this.getKeyIV_LEGACY(password, salt, 20); // Anciennes iterations
                    var cipher = crypto.createCipheriv('des', kiv[0], kiv[1]);
                    var encrypted = [];
                    encrypted.push(cipher.update(payload, 'utf-8', 'hex'));
                    encrypted.push(cipher.final('hex'));
                    return cb(undefined, new Buffer.from(encrypted.join(''), 'hex').toString('base64'));
                } else {
                    // Utiliser le nouvel algorithme AES
                    var kiv = this.getKeyIV(password, salt, iterations);
                    var cipher = crypto.createCipheriv('aes-256-cbc', kiv[0], kiv[1]); // Changé de 'des' à 'aes-256-cbc'
                    var encrypted = [];
                    encrypted.push(cipher.update(payload, 'utf-8', 'hex'));
                    encrypted.push(cipher.final('hex'));
                    return cb(undefined, new Buffer.from(encrypted.join(''), 'hex').toString('base64'));
                }
            } catch (error) {
                return cb(error);
            }
        },

        encrypt: function (payload, cb) {
            this.native_encrypt(payload, this.password, this.salt, this.iterations, cb)
        },

        decrypt: function (payload, cb) {
            this.native_decrypt(payload, this.password, this.salt, this.iterations, cb)
        },

        native_decrypt: function (payload, password, salt, iterations, cb) {
            try {
                var encryptedBuffer = new Buffer.from(payload, 'base64');

                if (this.forceLegacyDES) {
                    // Utiliser l'ancien algorithme DES
                    var kiv = this.getKeyIV_LEGACY(password, salt, 20); // Anciennes iterations
                    var decipher = crypto.createDecipheriv('des', kiv[0], kiv[1]);
                    var decrypted = [];
                    decrypted.push(decipher.update(encryptedBuffer));
                    decrypted.push(decipher.final('utf8'));
                    return cb(undefined, decrypted.join(''));
                } else {
                    // Utiliser le nouvel algorithme AES
                    var kiv = this.getKeyIV(password, salt, iterations);
                    var decipher = crypto.createDecipheriv('aes-256-cbc', kiv[0], kiv[1]); // Changé de 'des' à 'aes-256-cbc'
                    var decrypted = [];
                    decrypted.push(decipher.update(encryptedBuffer));
                    decrypted.push(decipher.final('utf8')); // Spécifié l'encodage
                    return cb(undefined, decrypted.join(''));
                }
            } catch (error) {
                return cb(error);
            }
        },

        // Méthode de migration pour les anciens mots de passe DES
        migrateFromDES: function (oldEncryptedPassword, cb) {
            try {
                // Essayer de déchiffrer avec l'ancien algorithme DES
                var encryptedBuffer = new Buffer.from(oldEncryptedPassword, 'base64');
                var kiv = this.getKeyIV_LEGACY(this.password, this.salt, 20); // Anciennes iterations
                var decipher = crypto.createDecipheriv('des', kiv[0], kiv[1]);
                var decrypted = [];
                decrypted.push(decipher.update(encryptedBuffer));
                decrypted.push(decipher.final('utf8'));
                var plainPassword = decrypted.join('');

                // Re-chiffrer avec le nouvel algorithme AES
                this.encrypt(plainPassword, (err, newEncryptedPassword) => {
                    if (err) return cb(err);
                    cb(undefined, newEncryptedPassword);
                });
            } catch (error) {
                return cb(error);
            }
        }
    }
}