/***********************************************************************************************************
 * Name         : RedirectController
 * Purpose      : Controller for Redirect page. Redirects the fan to the new Preference Center
 **********************************************************************************************************/
public class RedirectController {
    public RedirectController() {
    }

    /**
     * @description Retrieves the Fan using the Encrypted Id received as a parameter in the url and
     *  generates a jwt for Fansifter to decrypt it and display the new Pref Center for that fan
     * @return  PageReference to the new Preference Center for the Fan
     */
    public PageReference redirect() {
        PageReference pageRef;
        String encryptedId = ApexPages.currentpage().getparameters().get('id');

        List<Fan__c> fans = [SELECT Id, Email__c FROM Fan__c WHERE Encrypted_Id__c = :encryptedId];

        if (!fans.isEmpty()) {
            pageRef = new PageReference(RedirectController.getUrl(fans[0].Id));
        }

        return pageRef;
    }

    /**
     * @description Generates the URL for the new Pref Center for the Fan
     * @param   Id      fanId
     * @return  String  New Pref Center URL
     */
    @AuraEnabled
    public static String getUrl(Id fanId) {
        final String PREF_CENTER_AES_KEY = ConfigUtils.getConfigString(ConfigUtils.PREF_CENTER_AES_KEY);
        final String PREF_CENTER_URL = ConfigUtils.getConfigString(ConfigUtils.PREF_CENTER_URL);
        final String PREF_CENTER_JWT_KEY = ConfigUtils.getConfigString(ConfigUtils.PREF_CENTER_JWT_KEY);

        String jsonData = '{"crmId": "' + fanId + '"}';
        Blob aesKeyBlob = EncodingUtil.base64Decode(PREF_CENTER_AES_KEY);
        Blob iv = Crypto.generateAesKey(128);
        Blob encryptedText = Crypto.encrypt('AES256', aesKeyBlob, iv, Blob.valueOf(jsonData));

        String ivHex = EncodingUtil.convertToHex(iv);
        String encryptedPayload = ivHex + EncodingUtil.base64Encode(encryptedText);
        Long longMillis = System.now().getTime();
        Integer millis = Integer.valueOf(longMillis / 1000);

        String header = '{"alg": "HS256","typ":"JWT"}';
        String payload = '{"payload": "' + encryptedPayload + '", "iat": ' + millis + '}';

        String jwt = base64URLencode(Blob.valueOf(header)) + '.' + base64URLencode(Blob.valueOf(payload));
        Blob signature = Crypto.generateMac('HMACSHA256', Blob.valueOf(jwt), Blob.valueOf(PREF_CENTER_JWT_KEY));
        return PREF_CENTER_URL + jwt + '.' + base64URLencode(signature);
    }

    /**
     * @description Encodes a Blob into base64Url
     * @param   input Blob
     * @return  PageReference to the new Preference Center for the Fan
     */
    private static String base64URLencode(Blob input) {
        return EncodingUtil.base64Encode(input).replace('+', '-').replace('/', '_').replace('=', '');
    }
}
