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

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cusc.nirvana.user.rnr.fp.common.util.ChinaMobileSftpUtil;
import com.cusc.nirvana.user.rnr.fp.dto.*;
import com.cusc.nirvana.user.rnr.fp.util.AESUtil;
import com.cusc.nirvana.user.rnr.fp.util.RnrDataSM3Utils;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.File;

@Service
@Slf4j
public class ChinaMobileT1UploadServiceImpl extends VehicleT1UploadServiceImpl {

    @Value("${t1.chinaMobile.userInfoUrl:}")
    private String userInfoUrl;

    @Value("${t1.chinaMobile.vehicleInfoUrl:}")
    private String vehicleInfoUrl;

    @Value("${t1.chinaMobile.phoPath:}")
    private String phoPath;

    @Value("${t1.chinaMobile.phoPathByInstruction:}")
    private String phoPathByInstruction;

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

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

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

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

    @Autowired
    private ChinaMobileSftpUtil sftpUtil;

    public File encryptZipFile(String zipFileName, String folderPath) {
        try {
            return AESUtil.encryptFile(t1UserInfoKey, zipFileName, folderPath + ".bin");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("chinaMobile encryZipFile failed.", e);
        }
        return null;
    }

    /**
     * 加密用户开户信息
     *
     * @param userInfoStr * @return 需要加密的字符串内容
     */
    private final String encryptUserInfo(String userInfoStr) {
        byte[] key = AESUtil.MD5(t1UserInfoKey);
        //构建
        AES aes = SecureUtil.aes(key);
        //加密
        return aes.encryptHex(userInfoStr);
    }

    public String encrypt(T1UserInfoDTO ret) {
        return encryptUserInfo(JSON.toJSONString(ret));
    }

    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 requestStrTmp = JSON.toJSONString(userInfo);
        JSONObject jsonObject = JSON.parseObject(requestStrTmp);
        jsonObject.remove("ServiceProvider");
        final String requestStr = jsonObject.toJSONString();
        log.info("uploadUserInfo url: {},request: {}", userInfoUrl, requestStr);

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

    public T1CommonResponseDTO uploadT1File(T1FileReqDTO file) {
        if (StringUtils.isEmpty(phoPath)) {
            log.error("ChinaMobileT1UploadServiceImpl uploadT1File failure, phoPath:{}, T1FileReqDTO:{}", phoPath, file);
            return T1CommonResponseDTO.createError(file.getRequestID(), "phoPath is empty, please check nacos!!!");
        }
        final String realPath = phoPath + file.getRequestID();
        return upload(file, realPath);
    }

    public T1CommonResponseDTO uploadT1FileByInstruction(T1FileReqDTO file) {
        if (StringUtils.isEmpty(phoPathByInstruction)) {
            log.error("ChinaMobileT1UploadServiceImpl uploadT1File failure, phoPath:{}, T1FileReqDTO:{}", phoPath, file);
            return T1CommonResponseDTO.createError(file.getRequestID(), "phoPath is empty, please check nacos!!!");
        }
        final String realPath = phoPathByInstruction + file.getRequestID();
        return upload(file, realPath);
    }

    private final T1CommonResponseDTO upload(T1FileReqDTO file, String realPath) {
        long startTime = System.currentTimeMillis();
        String uploadFile = null;
        try {
            uploadFile = sftpUtil.uploadFile(file.getEncryptFile().getPath(), realPath);
        } catch (SftpException | JSchException e) {
            e.printStackTrace();
            return T1CommonResponseDTO.createError(file.getRequestID(), "upload file failed, exception cause:" + e.getMessage());
        }
        if (StringUtils.isEmpty(uploadFile)) {
            log.error("ChinaMobileT1UploadServiceImpl uploadT1File failure, phoPath:{}, T1FileReqDTO:{}, uploadFile:{}", phoPath, file, uploadFile);
            return T1CommonResponseDTO.createError(file.getRequestID(), "ChinaMobileT1UploadServiceImpl uploadFile is empty");
        }
        log.info("{} uploadFile:{} success. cost time:{} ms", this, uploadFile, System.currentTimeMillis() - startTime);
        return T1CommonResponseDTO.createSuccess(file.getRequestID());
    }

    public T1CommonResponseDTO uploadT1VehicleInfo(T1VehicleInfoReqDTO vehicleInfoReqDTO, String vin) {
        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);
        jsonObject.remove("ServiceProvider");
        final String requestStr = jsonObject.toJSONString();
        log.info("uploadT1VehicleInfo url: {},request: {}", vehicleInfoUrl, requestStr);

        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        ResponseEntity<String> entity =
                noBalanceRestTemplateRnrFp.exchange(vehicleInfoUrl, HttpMethod.POST, new HttpEntity<>(requestStr, requestHeaders),
                        String.class);
        log.info("uploadT1VehicleInfo url: {},response: {},cost: {} ms", vehicleInfoUrl, 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;
    }
}
