// CBC , AES-128 , PKCS7


import crypto from "crypto";

const utils = (init: {
    MerchantID: string,  // 特店編號
    HashKey: string,
    HashIV: string,
}) => {
    const encrypt = (data: object) => {
        if (typeof data !== 'object') throw new Error('data must be an object')
        const jsonStr = JSON.stringify(data)
        const urlEncode = encodeURIComponent(jsonStr)
        // convert to dotnet url encode
        const urlEncodeDotNet = urlEncode.replace(/%[0-9a-f]{2}/g, (match) => {
            switch (match) {
                case '%20':
                    return '+'
                case '%2d':
                    return '-'
                case '%2e':
                    return '.'
                case '%5f':
                    return '_'
                case '%2a':
                    return '*'
                case '%28':
                    return '('
                case '%29':
                    return ')'
                case '%21':
                    return '!'
                default:
                    return match
            }
        })

        const cipher = crypto.createCipheriv('aes-128-cbc', init.HashKey, init.HashIV);
        let encrypted = cipher.update(urlEncodeDotNet, 'utf8', 'hex');
        encrypted += cipher.final('hex');
        return Buffer.from(encrypted, 'hex').toString('base64')
    }

    const decrypt = (data: string) => {
        const decipher = crypto.createDecipheriv('aes-128-cbc', init.HashKey, init.HashIV);
        let decrypted = decipher.update(data, 'base64', 'utf8');
        decrypted += decipher.final('utf8');
        return decodeURIComponent(decrypted)
    }

    return {
        encode: encrypt,
        decode: decrypt
    }
}


export default utils