package com.ruoyi.ibs.qxhy.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.ibs.qxhy.config.QxhyProperties;
import com.ruoyi.ibs.qxhy.domain.dto.QxhyTokenResponseDTO;
import com.ruoyi.ibs.qxhy.domain.entity.QxhyDept;
import com.ruoyi.ibs.qxhy.mapper.QxhyDeptMapper;
import com.ruoyi.ibs.qxhy.service.QxhyLoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @Author 吴凯程
 * @Date 2025/1/13
 **/
@Service
@Slf4j
public class QxhyLoginServiceImpl implements QxhyLoginService {
    @Resource
    private QxhyDeptMapper qxhyDeptMapper;

    @Resource
    private QxhyProperties qxhyProperties;

    @Resource
    private RedisCache redisCache;

    private final String qxhyTokenRedisKey = "QXHY_LOGIN_TOKEN_";


    /**
     * @return
     */
    @Override
    public String getLoginToken( String deptCode) {
        LambdaQueryWrapper<QxhyDept> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(QxhyDept::getDeptCode, deptCode);
        if (qxhyDeptMapper.selectCount(lambdaQueryWrapper) < 1) {
            throw new ServiceException("暂无权限使用启信慧眼服务");
        }
        String redisKey = qxhyTokenRedisKey + deptCode;
        if (redisCache.hasKey(redisKey)) {
            return redisCache.getCacheObject(redisKey);
        }

        String key = "C1571C4F7BED4211";
        String iv = "29DCD116A4B34A86";
        String API_CREATE_USER = qxhyProperties.getUrl() + "/authTokenApi/fetch_token?tenant=%s&sig=%s";
        String tenant = "zjrcuxljd";
        QxhyTokenResponseDTO resObj;
        try {
            // 获得一个加密规则 SecretKeySpec
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
            // 获得加密算法实例对象 Cipher
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            // 获得一个 IvParameterSpec
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            // 根据参数初始化算法
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

            long data = new Date().getTime() / 1000; // 当前时间戳
            String sData = Long.toString(data);

            String content = tenant + "+" + deptCode + "+" + sData;
            // 执行加密并返回经 BASE64 处助理之后的密文
            String sig = Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes()));
            // 将sig进行转义，请勿重复转义
//            sig = URLEncoder.encode(sig, "UTF-8");
            sig = sig.replace("+", "%2B");
            String URL = String.format(API_CREATE_USER, tenant, sig);
            RestTemplate restTemplate = new RestTemplate();
            resObj = restTemplate.getForObject(URL, QxhyTokenResponseDTO.class);
        } catch (Exception e) {
            throw new ServiceException("获取启信慧眼Token失败");
        }
        if (!resObj.getStatus().equals(200)) {
            throw new ServiceException("获取启信慧眼Token失败");
        }
        redisCache.setCacheObject(redisKey, resObj.getToken(), 2, TimeUnit.HOURS);
        return resObj.getToken();
    }

    /**
     * @param
     * @return
     */
    @Override
    public String getUrlToken(String deptCode) {
        log.info("获取urlToken " + deptCode);
        LambdaQueryWrapper<QxhyDept> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(QxhyDept::getDeptCode, deptCode);
        if (qxhyDeptMapper.selectCount(lambdaQueryWrapper) < 1) {
            throw new ServiceException("暂无权限使用启信慧眼服务");
        }
        String redisKey = qxhyTokenRedisKey + deptCode;
        String loginToken;
        if (redisCache.hasKey(redisKey)) {
            log.info("从redis获取urlToken " + redisKey + " ---|--- " + redisKey);
            loginToken =  redisCache.getCacheObject(redisKey);
        }else{
            String key = "C1571C4F7BED4211";
            String iv = "29DCD116A4B34A86";
            String API_CREATE_USER = qxhyProperties.getUrl() + "/authTokenApi/fetch_token?tenant=%s&sig=%s";
            String tenant = "zjrcuxljd";
            QxhyTokenResponseDTO resObj;
            try {
                // 获得一个加密规则 SecretKeySpec
                SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
                // 获得加密算法实例对象 Cipher
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                // 获得一个 IvParameterSpec
                IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
                // 根据参数初始化算法
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

                long data = new Date().getTime() / 1000; // 当前时间戳
                String sData = Long.toString(data);

                String content = tenant + "+" + deptCode + "+" + sData;
                // 执行加密并返回经 BASE64 处助理之后的密文
                String sig = Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes()));
                // 将sig进行转义，请勿重复转义
//            sig = URLEncoder.encode(sig, "UTF-8");
                sig = sig.replace("+", "%2B");
                String URL = String.format(API_CREATE_USER, tenant, sig);
                RestTemplate restTemplate = new RestTemplate();
                resObj = restTemplate.getForObject(URL, QxhyTokenResponseDTO.class);
            } catch (Exception e) {
                throw new ServiceException("获取启信慧眼Token失败");
            }
            if (!resObj.getStatus().equals(200)) {
                throw new ServiceException("获取启信慧眼Token失败");
            }
            redisCache.setCacheObject(redisKey, resObj.getToken(), 2, TimeUnit.HOURS);
            loginToken =  resObj.getToken();
            log.info("从接口获取urlToken " + redisKey + " ---|--- " + redisKey);
//            redisCache.setCacheObject(redisKey,loginToken, 2, TimeUnit.HOURS);
        }
        String THIRD_LOGIN = qxhyProperties.getUrl() + "/third-login?tenant=%s&token=%s";
        String tenant = "zjrcuxljd";
        String URL = String.format(THIRD_LOGIN, tenant, loginToken);
        RestTemplate restTemplate = new RestTemplate();
        String resObject = restTemplate.getForObject(URL, String.class);
        String[] split = resObject.split("token=");
        if (split.length != 2) {
            throw new ServiceException("获取urlToken失败");
        }
        return split[1];
    }

    /**
     * @return
     */
    @Override
    public String getRPAUrl() {
        String deptCode = "965000";
        log.info("获取urlToken " + deptCode);
        LambdaQueryWrapper<QxhyDept> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(QxhyDept::getDeptCode, deptCode);
        if (qxhyDeptMapper.selectCount(lambdaQueryWrapper) < 1) {
            throw new ServiceException("暂无权限使用启信慧眼服务");
        }
        String redisKey = qxhyTokenRedisKey + deptCode;
        String loginToken;
        if (redisCache.hasKey(redisKey)) {
            log.info("从redis获取urlToken " + redisKey + " ---|--- " + redisKey);
            loginToken = redisCache.getCacheObject(redisKey);
        } else {
            String key = "C1571C4F7BED4211";
            String iv = "29DCD116A4B34A86";
            String API_CREATE_USER = qxhyProperties.getUrl() + "/authTokenApi/fetch_token?tenant=%s&sig=%s";
            String tenant = "zjrcuxljd";
            QxhyTokenResponseDTO resObj;
            try {
                // 获得一个加密规则 SecretKeySpec
                SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
                // 获得加密算法实例对象 Cipher
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                // 获得一个 IvParameterSpec
                IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
                // 根据参数初始化算法
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

                long data = new Date().getTime() / 1000; // 当前时间戳
                String sData = Long.toString(data);

                String content = tenant + "+" + deptCode + "+" + sData;
                // 执行加密并返回经 BASE64 处助理之后的密文
                String sig = Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes()));
                // 将sig进行转义，请勿重复转义
//            sig = URLEncoder.encode(sig, "UTF-8");
                sig = sig.replace("+", "%2B");
                String URL = String.format(API_CREATE_USER, tenant, sig);
                RestTemplate restTemplate = new RestTemplate();
                resObj = restTemplate.getForObject(URL, QxhyTokenResponseDTO.class);
            } catch (Exception e) {
                throw new ServiceException("获取启信慧眼Token失败");
            }
            if (!resObj.getStatus().equals(200)) {
                throw new ServiceException("获取启信慧眼Token失败");
            }
            redisCache.setCacheObject(redisKey, resObj.getToken(), 2, TimeUnit.HOURS);
            loginToken = resObj.getToken();
            log.info("从接口获取urlToken " + redisKey + " ---|--- " + redisKey);
//            redisCache.setCacheObject(redisKey,loginToken, 2, TimeUnit.HOURS);
        }
        String THIRD_LOGIN = qxhyProperties.getUrl() + "/third-login?tenant=%s&token=%s&returnUrl=/search/advanced";
        String tenant = "zjrcuxljd";
        String URL = String.format(THIRD_LOGIN, tenant, loginToken);
        RestTemplate restTemplate = new RestTemplate();
        String resObject = restTemplate.getForObject(URL, String.class);
        String[] split = resObject.split(" to ");
        if (split.length != 2) {
            throw new ServiceException("获取urlToken失败");
        }
        return qxhyProperties.getUrl() + "/ent" + split[1];
    }
}
