package com.cusc.nirvana.user.rnr.fp.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cusc.nirvana.common.result.Response;
import com.cusc.nirvana.user.rnr.fp.dto.*;
import com.cusc.nirvana.user.rnr.fp.service.IT1UploadService;
import com.cusc.nirvana.user.rnr.fp.util.*;
import com.cusc.nirvana.user.rnr.mg.client.MgRnrRelationClient;
import com.cusc.nirvana.user.rnr.mg.dto.*;
import com.cusc.nirvana.user.util.CuscStringUtils;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

import static com.alibaba.nacos.client.utils.EnvUtil.LOGGER;

@Service
@Slf4j
public class ChinaUnicomT1UploadServiceImpl extends VehicleT1UploadServiceImpl {

    @Value("${t1.chinaUnicom.url:}")
    private String dateUrl;

    @Value("${t1.chinaUnicom.platformID:}")
    //由OneLink车联卡实名平台为各个车 企分配的标识
    private String platformID = "xxxx";

    @Value("${t1.chinaUnicom.code:}")
    //工信部下发的车企编码,道路机动 车辆生产 企业编码
    private String code = "xxxx";

    @Value("${t1.chinaUnicom.t1UserInfoKey:}")
    //开户信息的加密密钥由 OneLink 平台生成后，自动发送到指定邮箱。
    private String t1UserInfoKey = "7faf0abf9e6c4aa0aa04eeccf3110e37";

    @Autowired
    @Qualifier("noBalanceRestTemplateRnrFp")
    RestTemplate noBalanceRestTemplateRnrFp;

    public String encrypt(T1UserInfoDTO ret) {
        return RnrDataSm4Util.encryptEcbPadding(t1UserInfoKey,
                JSON.toJSONString(ret),
                true, null);
    }

    public File encryptZipFile(String zipFileName, String folderPath){
        byte[] byteArr = ZipUtils.readByteFromFile(zipFileName);
        byte[] encodeByteArr = RnrDataSm4Util.encryptEcbPaddingBytes(t1UserInfoKey, byteArr, true);
        return CuscFileUtils.byte2File(encodeByteArr, folderPath + ".bin");
    }

    private final T1AuthDTO getAuth(){
        final T1AuthDTO t1AuthDTO = new T1AuthDTO();
        t1AuthDTO.setPlatformID(platformID);

        //平台标识+密码的SM3值，密码由 OneLink车联卡实名平台分配
        String signNature = platformID + t1UserInfoKey;
        t1AuthDTO.setSignNature(RnrDataSM3Utils.encode(signNature));
        return t1AuthDTO;
    }

    public T1CommonResponseDTO uploadT1UserInfo(T1UserInfoReqDTO userInfo) {
        long startTime = System.currentTimeMillis();
        userInfo.setAuth(getAuth());
        String url = dateUrl + "/data/upload/userInfo";
        String requestStrTmp = JSON.toJSONString(userInfo);
        JSONObject jsonObject=JSON.parseObject(requestStrTmp);
        final String requestStr = jsonObject.toJSONString();
        log.info("uploadUserInfo url: {},request: {}", url, requestStr);

        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        ResponseEntity<String> entity =
                noBalanceRestTemplateRnrFp.exchange(url, HttpMethod.POST, new HttpEntity<>(requestStr, requestHeaders),
                        String.class);
        log.info("uploadUserInfo url: {},response: {},cost: {} ms", url, entity.getBody(),
                System.currentTimeMillis() - startTime);
        T1CommonResponseDTO result = JSON.parseObject(entity.getBody(), T1CommonResponseDTO.class);
        return result;
    }


    public T1CommonResponseDTO uploadT1File(T1FileReqDTO file) {
        long startTime = System.currentTimeMillis();
        String url = dateUrl + "/file/upload/rnr";
        log.info("uploadT1File url: {},request: {}", url, JSON.toJSONString(file));
        FileSystemResource fileSystemResource = new FileSystemResource(file.getEncryptFile());
        // headers参数
        HttpHeaders requestHeaders = new HttpHeaders();
        // body体参数
        MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
        // 设置header是文件上传
        requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
        // 参数设置文件
        requestBody.add("RequestID", file.getRequestID());
        requestBody.add("Code", file.getCode());
        requestBody.add("EncryptFile", fileSystemResource);
        requestBody.add("FileMd5", Md5CaculateUtil.getFileMD5(file.getEncryptFile()));
        requestBody.add("ServiceProvider", file.getServiceProvider());
        // 封装所有参数
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(requestBody, requestHeaders);
        ResponseEntity<String> entity =
                noBalanceRestTemplateRnrFp.exchange(url, HttpMethod.POST, requestEntity, String.class);
        log.info("uploadT1File url: {},response: {},cost: {} ms", url, entity.getBody(),
                System.currentTimeMillis() - startTime);
        T1CommonResponseDTO result = JSON.parseObject(entity.getBody(), T1CommonResponseDTO.class);
        return result;
    }

    public T1CommonResponseDTO uploadT1VehicleInfo(T1VehicleInfoReqDTO vehicleInfoReqDTO, String vin) {
        ///data/upload/vehicleInfo 地址需要确认下
        String url = dateUrl + "/data/upload/vehicleInfo";

        final String vehicleInfo = getVehicleInfo(vin);
        //加密
        final String encryptCarInfo = encryptCarInfo(vehicleInfo);
        vehicleInfoReqDTO.setEncryptCarInfo(encryptCarInfo);

        long startTime = System.currentTimeMillis();
        vehicleInfoReqDTO.setAuth(getAuth());
        String requestStrTmp = JSON.toJSONString(vehicleInfoReqDTO);
        JSONObject jsonObject = JSON.parseObject(requestStrTmp);
        final String requestStr = jsonObject.toJSONString();
        log.info("uploadT1VehicleInfo url: {},request: {}", url, requestStr);

        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        ResponseEntity<String> entity =
                noBalanceRestTemplateRnrFp.exchange(url, HttpMethod.POST, new HttpEntity<>(requestStr, requestHeaders),
                        String.class);
        log.info("uploadT1VehicleInfo url: {},response: {},cost: {} ms", url, entity.getBody(),
                System.currentTimeMillis() - startTime);
        T1CommonResponseDTO result = JSON.parseObject(entity.getBody(), T1CommonResponseDTO.class);
        return result;
    }

    public String getCode() {
        return code;
    }

    public String getT1UserInfoKey() {
        return t1UserInfoKey;
    }

    public String getPlatformID() {
        return platformID;
    }
}
