package com.crm.rely.backend.util;

import com.crm.rely.backend.exception.ServiceException;
import com.google.common.base.Strings;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.net.URLEncoder;
import java.security.spec.KeySpec;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.TimeZone;

/**
 * @Author: houn
 * @Date: 2020/11/23 16:22
 * @Description:
 */

public class HandShake {

    public static final String HAND_SHAKE = "HAND_SHAKE";


    public static final long HAND_SHAKE_TIME = 15 * 60 * 1000L;

    private static final String UNICODE_FORMAT = "UTF8";
    public static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
    private KeySpec myKeySpec;
    private SecretKeyFactory mySecretKeyFactory;
    private Cipher cipher;
    byte[] keyAsBytes;
    SecretKey key;

    private static final String encryptionKey = "F03yMFT!GjWFWfR=G$3L$+d@";
    private static final String baseURL = "https://site.recognia.com/cwgmarkets/serve.shtml?tkn=";

    public static final String featured_forex_page = "featured_forex";
    public static final String economic_calendar_page = "economic_calendar";
    //    private static final String userID = "testUser";        /* USER ID must be that of the user logged into your website */
    private static final String defaultLanguage = "en";   /* en (English), cs(Simplified Chinese) */

    private String language;


    public HandShake() throws Exception {
        keyAsBytes = encryptionKey.getBytes(UNICODE_FORMAT);
        myKeySpec = new DESedeKeySpec(keyAsBytes);
        mySecretKeyFactory = SecretKeyFactory.getInstance(DESEDE_ENCRYPTION_SCHEME);
        cipher = Cipher.getInstance(DESEDE_ENCRYPTION_SCHEME);
        key = mySecretKeyFactory.generateSecret(myKeySpec);
        language = defaultLanguage;
    }

    public HandShake(String language) throws Exception {
        keyAsBytes = encryptionKey.getBytes(UNICODE_FORMAT);
        myKeySpec = new DESedeKeySpec(keyAsBytes);
        mySecretKeyFactory = SecretKeyFactory.getInstance(DESEDE_ENCRYPTION_SCHEME);
        cipher = Cipher.getInstance(DESEDE_ENCRYPTION_SCHEME);
        key = mySecretKeyFactory.generateSecret(myKeySpec);
        this.language = language;
    }

    public HandShake(String encryptionKey, String language) throws Exception {
        keyAsBytes = encryptionKey.getBytes(UNICODE_FORMAT);
        myKeySpec = new DESedeKeySpec(keyAsBytes);
        mySecretKeyFactory = SecretKeyFactory.getInstance(DESEDE_ENCRYPTION_SCHEME);
        cipher = Cipher.getInstance(DESEDE_ENCRYPTION_SCHEME);
        key = mySecretKeyFactory.generateSecret(myKeySpec);
        this.language = language;
    }

    /**
     * Method To Encrypt The String
     */
    public String encrypt(String unencryptedString) {
        String encryptedString = null;
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
            byte[] encryptedText = cipher.doFinal(plainText);

            encryptedString = URLEncoder.encode(Base64.getEncoder().encodeToString(encryptedText), UNICODE_FORMAT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedString;
    }

    /**
     * Method To Create The Handshake URL
     */
    public String handShakeURL() throws ServiceException {

        return handShakeURL(language);
    }

    public String handShakeURL(String language) throws ServiceException {

        String hanShakeURL = handShakeURL(language,featured_forex_page);

        return hanShakeURL;
    }

    public String handShakeURL(String language, String page) throws ServiceException {

        final Date currentTime = new Date();
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        String userID = UUIDUtil.getUUID();
        String parameters =
                "aci=" + sdf.format(currentTime) + "&page=" + (Strings.isNullOrEmpty(page) ? featured_forex_page : page) +
                        "&usi=" + userID +
                        "&lang=" + language;

        System.out.println(sdf.format(currentTime));
        String hanShakeURL = baseURL + encrypt(parameters);

        return hanShakeURL;
    }

    /**
     * Testing
     */
    public static void main(String args[]) throws Exception {
        HandShake handshake = new HandShake();
        System.out.println(handshake.handShakeURL());
    }
}
