package fcb.project.manager.base.utils;

import com.alibaba.fastjson.JSON;
import fdage.back.sdk.base.entity.Result;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 2 * @Author: Abner
 * 3 * @Date: 2021/1/18 9:11
 * 4
 */
@Service
@Log4j2
public class FcbUtils {


    @Autowired
    private RedisTemplate redisTemplate;


    public  Result<Object> getFcbSign(Map<String , Object> params
            , String fcbClientSecret , String fcbClientCode){

        if(CollectionUtils.isEmpty(params)){
            return Result.failure("入参不能为空");
        }
        long timeStamp = Instant.now().getEpochSecond();
        Instant stepOneStart = Instant.now();
        String redisKey = JSON.toJSONString(params);
        if(redisTemplate.hasKey(redisKey)){
            log.info("缓存中存在，直接返回");
            String redisMapStr = (String) redisTemplate.opsForValue().get(redisKey);
            if(StringUtils.isNotBlank(redisMapStr)){
                Map<String , Object> resultMp  = JSON.parseObject(redisMapStr , Map.class);
                return Result.success(resultMp);
            }
        }
        Instant stepOneEnd = Instant.now();
        long stepOneDuration = Duration.between(stepOneStart , stepOneEnd).toMillis();
        log.info("步骤1耗时:{}" , stepOneDuration);
        Instant stepTwoStart = Instant.now();
        Map<String , Object> totalParam = new HashMap<>();
        for (Map.Entry entry : params.entrySet()) {
            //1、先剔除value值为null的键值对
            if(null  != entry.getValue()){
                //这里需要转成小写
               totalParam.put(entry.getKey().toString().toLowerCase() , entry.getValue());
            }
        }
        //2、新增房车宝的client_secret作为噪点
        totalParam.put("client_secret" , fcbClientSecret);
        totalParam.put("client_code" , fcbClientCode);
        totalParam.put("req_time" , timeStamp);
//        params = DataUtils.sortMapByKey(params);
        Collection<String> keyset= totalParam.keySet();
        List<String> list=new ArrayList<String>(keyset);
        Collections.sort(list);
        Instant stepTwoEnd = Instant.now();
        long stepTwoDuration = Duration.between(stepTwoStart , stepTwoEnd).toMillis();
        log.info("步骤2耗时:{}" , stepTwoDuration);

        Instant stepThreeStart = Instant.now();
        StringBuilder stringBuilder = new StringBuilder();
        /*for ( Map.Entry entry : params.entrySet()) {
            stringBuilder.append(entry.getValue());
        }*/
        for (String str: list) {
            stringBuilder.append(String.valueOf(totalParam.get(str)));
        }
        //3、生成MD5密文，然后转成小写字母
        String md5EncryptionStr = DataUtils.md5Encryption(stringBuilder.toString());
        Map<String , Object> resultMap = new HashMap<>();
        resultMap.put("authcode" , md5EncryptionStr);
        resultMap.put("timeStamp" , timeStamp);
        //缓存3min
        redisTemplate.opsForValue().set(redisKey , JSON.toJSONString(resultMap) , 180 , TimeUnit.SECONDS);
        Instant stepThreeEnd = Instant.now();
        long stepThreeDuration = Duration.between(stepThreeStart , stepThreeEnd).toMillis();
        log.info("步骤3耗时:{}" , stepThreeDuration);
        return Result.success(resultMap);

    }
}
