package com.jsowell.thirdparty.nanrui.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.domain.ykc.RealTimeMonitorData;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.enums.ykc.PileStatusEnum;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.PageUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.*;
import com.jsowell.pile.domain.nanrui.NROrderInfo;
import com.jsowell.pile.dto.PushStationInfoDTO;
import com.jsowell.pile.dto.QueryConnectorListDTO;
import com.jsowell.pile.dto.QueryStationInfoDTO;
import com.jsowell.pile.dto.nanrui.NRQueryOrderDTO;
import com.jsowell.pile.dto.nanrui.PushAlarmInfoDTO;
import com.jsowell.pile.service.*;
import com.jsowell.pile.vo.base.ThirdPartyStationRelationVO;
import com.jsowell.pile.vo.nanrui.NROrderInfoVO;
import com.jsowell.pile.vo.uniapp.CurrentTimePriceDetails;
import com.jsowell.pile.vo.web.PileConnectorInfoVO;
import com.jsowell.pile.vo.web.PileModelInfoVO;
import com.jsowell.pile.vo.web.PileStationVO;
import com.jsowell.thirdparty.lianlian.dto.CommonParamsDTO;
import com.jsowell.thirdparty.lianlian.service.LianLianService;
import com.jsowell.thirdparty.lianlian.util.Cryptos;
import com.jsowell.thirdparty.lianlian.util.Encodes;
import com.jsowell.thirdparty.lianlian.util.GBSignUtils;
import com.jsowell.thirdparty.lianlian.util.HttpRequestUtil;
import com.jsowell.thirdparty.lianlian.vo.LianLianResultVO;
import com.jsowell.thirdparty.nanrui.domain.*;
import com.jsowell.thirdparty.nanrui.service.NRService;
import com.jsowell.thirdparty.nanrui.util.QEncodeUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author Lemon
 * @Date 2023/9/26 9:20
 */
@Service
public class NRServiceImpl implements NRService {

    @Autowired
    private IPileStationInfoService pileStationInfoService;

    @Autowired
    private IPileBasicInfoService pileBasicInfoService;

    @Autowired
    private IPileModelInfoService pileModelInfoService;

    @Autowired
    private IPileConnectorInfoService pileConnectorInfoService;

    @Autowired
    private IPileBillingTemplateService pileBillingTemplateService;

    @Autowired
    private IOrderBasicInfoService orderBasicInfoService;

    @Autowired
    private IThirdPartyStationRelationService thirdPartyStationRelationService;

    @Autowired
    private IThirdPartyPlatformConfigService thirdPartyPlatformConfigService;

    @Autowired
    private LianLianService lianLianService;

    @Autowired
    private RedisCache redisCache;


    /**
     * 从南瑞平台获取令牌
     * @param urlAddress
     * @param operatorId
     * @param operatorSecret
     * @param dataSecretIv
     * @param signSecret
     * @param dataSecret
     * @return
     */
    @Override
    public String getToken(String urlAddress, String operatorId, String operatorSecret,
                           String dataSecretIv, String signSecret, String dataSecret) {
        return lianLianService.getToken(urlAddress, operatorId, operatorSecret,
                dataSecretIv, signSecret, dataSecret);
    }

    @Override
    public Map<String, String> generateToken(CommonParamsDTO dto) throws UnsupportedEncodingException {
        return lianLianService.generateToken(dto);
    }

    @Override
    public Map<String, String> checkoutSign(CommonParamsDTO dto) {
        return lianLianService.checkoutSign(dto);
    }

    /**
     * 推送充电站信息
     * @param dto
     * @return
     */
    @Override
    public String pushStationInfo(PushStationInfoDTO dto) throws ParseException {
        PileStationVO stationInfoVO = pileStationInfoService.getStationInfo(String.valueOf(dto.getStationId()));
        if (stationInfoVO == null) {
            return null;
        }
        // 通过站点id查询相关配置信息
        ThirdPartyStationRelation relation = new ThirdPartyStationRelation();
        relation.setStationId(dto.getStationId());
        ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(relation);
        // ThirdPartySettingInfo settingInfo = thirdPartySettingInfoService.getInfoByStationId(dto.getStationId());
        if (relationInfo == null) {
            // 新增
            relation.setThirdPartyType(dto.getThirdPartyType());
            thirdPartyStationRelationService.insertThirdPartyStationRelation(relation);

            relationInfo = thirdPartyStationRelationService.selectRelationInfo(relation);
        }
        String operatorId = relationInfo.getOperatorId();
        String operatorSecret = relationInfo.getOperatorSecret();
        String signSecret = relationInfo.getSignSecret();
        String dataSecret = relationInfo.getDataSecret();
        String dataSecretIv = relationInfo.getDataSecretIv();
        String urlAddress = relationInfo.getUrlAddress();

        // 拼装南瑞平台所需参数
        NRStationInfo nrStationInfo = NRStationInfo.builder()
                .stationId(String.valueOf(stationInfoVO.getId()))
                .operatorID(Constants.OPERATORID_JIANG_SU)
                .equipmentOwnerID(Constants.OPERATORID_JIANG_SU)
                .stationName(stationInfoVO.getStationName())
                .countryCode(stationInfoVO.getCountryCode())
                // .areaCode()
                .address(stationInfoVO.getAddress())
                .serviceTel(stationInfoVO.getStationTel())
                .stationStatus(stationInfoVO.getStationStatus())
                .parkNums(0)
                .stationLng(new BigDecimal(stationInfoVO.getStationLng()).setScale(6, BigDecimal.ROUND_HALF_UP))
                .stationLat(new BigDecimal(stationInfoVO.getStationLat()).setScale(6, BigDecimal.ROUND_HALF_UP))
                .openForBusinessDate(DateUtils.convertDateTimeToDate(stationInfoVO.getCreateTime()))
                .openAllDay(Integer.parseInt(stationInfoVO.getOpenAllDay()))
                .busineHours(stationInfoVO.getBusinessHours())
                .minElectricityPrice(stationInfoVO.getElectricityPrice().add(stationInfoVO.getServicePrice()))
                .loungeFlag(0)
                .isAloneApply(0)
                .printerFlag(0)
                .parkFree(0)
                .isPublicParkingLot(0)
                .payment(1)
                .restaurantFlag(0)
                .barrierFlag(0)
                .serviceFee(stationInfoVO.getServicePrice())
                .parkingLockFlag(0)
                .electricityFee(stationInfoVO.getElectricityPrice())
                .storeFlag(0)
                .canopyFlag(0)
                .toiletFlag(0)
                .supportOrder(0)
                .parkFeeType(1)

                .build();
        // 站点地址
        String areaCode = stationInfoVO.getAreaCode();
        // 截取最后一组数据，例如将 320000,320500,320583 截取为 320583
        String[] split = StringUtils.split(areaCode, ",");
        String s = split[split.length - 1];
        nrStationInfo.setAreaCode(s);
        // 站点图片
        if (CollectionUtils.isNotEmpty(stationInfoVO.getPictureList())) {
            nrStationInfo.setPictures(stationInfoVO.getPictureList());
        }
        String stationType = stationInfoVO.getStationType();
        if (!StringUtils.equals("1", stationType) && !StringUtils.equals("255", stationType)) {
            // 不为1-公共并且不为255-其他，都为专用
            stationType = "2";
        }
        nrStationInfo.setStationType(Integer.parseInt(stationType));
        nrStationInfo.setConstruction(255);

        List<NREquipmentInfo> nrEquipmentInfos = getEquipmentInfo(String.valueOf(dto.getStationId()));
        nrStationInfo.setEquipmentInfos(nrEquipmentInfos);

        // 推送到平台
        String url = urlAddress + "notification_stationInfo";

        JSONObject data = new JSONObject();
        data.put("StationInfo", nrStationInfo);

        String jsonString = data.toString();
        System.out.println("jsonString : " + jsonString);

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        System.out.println(token);
        String result = HttpRequestUtil.nrSendPost(token, jsonString, url, dataSecret
                , dataSecretIv, operatorId, signSecret);

        // System.out.println(result);
        return result;
    }

    /**
     * 获取充电站信息
     * @param dto
     * @return
     */
    @Override
    public Map<String, String> query_stations_info(QueryStationInfoDTO dto) {
        List<NRStationInfo> resultList = new ArrayList<>();
        int pageNo = dto.getPageNo() == null ? 1 : dto.getPageNo();
        int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();

        PageUtils.startPage(pageNo, pageSize);
        List<PileStationInfo> stationInfos = pileStationInfoService.getStationInfosByThirdParty();
        if (CollectionUtils.isEmpty(stationInfos)) {
            // 未查到数据
            return null;
        }
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        PageInfo<PileStationInfo> pageInfo = new PageInfo<>(stationInfos);
        for (PileStationInfo pileStationInfo : pageInfo.getList()) {
            // 拼装参数
            NRStationInfo nrStationInfo = NRStationInfo.builder()
                    .stationId(String.valueOf(pileStationInfo.getId()))
                    .operatorID(Constants.OPERATORID_JIANG_SU)
                    .equipmentOwnerID(Constants.OPERATORID_JIANG_SU)
                    .stationName(pileStationInfo.getStationName())
                    .countryCode(pileStationInfo.getCountryCode())
                    .areaCode(pileStationInfo.getAreaCode())
                    .address(pileStationInfo.getAddress())
                    .serviceTel(pileStationInfo.getStationTel())
                    .stationStatus(Integer.parseInt(pileStationInfo.getStationStatus()))
                    .parkNums(0)
                    .stationLng(new BigDecimal(pileStationInfo.getStationLng()).setScale(6, BigDecimal.ROUND_HALF_UP))
                    .stationLat(new BigDecimal(pileStationInfo.getStationLat()).setScale(6, BigDecimal.ROUND_HALF_UP))
                    .openForBusinessDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, pileStationInfo.getCreateTime()))
                    .openAllDay(Integer.parseInt(pileStationInfo.getOpenAllDay()))
                    .busineHours(pileStationInfo.getBusinessHours())
                    .build();
            // 站点费率
            // 查计费模板
            CurrentTimePriceDetails currentTimePriceDetails = pileBillingTemplateService.getCurrentTimePriceDetails(String.valueOf(pileStationInfo.getId()));
            if (currentTimePriceDetails == null) {
                // 未设置计费模板
                continue;
            }
            String electricityPrice = currentTimePriceDetails.getElectricityPrice();
            electricityPrice = StringUtils.isBlank(electricityPrice) ? "0" : electricityPrice;

            String servicePrice = currentTimePriceDetails.getServicePrice();
            servicePrice = StringUtils.isBlank(servicePrice) ? "0" : servicePrice;

            BigDecimal price = new BigDecimal(electricityPrice).add(new BigDecimal(servicePrice));
            nrStationInfo.setMinElectricityPrice(price);

            // 站点图片
            if (StringUtils.isNotBlank(pileStationInfo.getPictures())) {
                nrStationInfo.setPictures(Lists.newArrayList(pileStationInfo.getPictures().split(",")));
            }
            // 站点类型
            String stationType = pileStationInfo.getStationType();
            if (!StringUtils.equals("1", stationType) && !StringUtils.equals("255", stationType)) {
                // 不为1-公共并且不为255-其他，都为专用
                stationType = "2";
            }
            nrStationInfo.setStationType(Integer.parseInt(stationType));
            nrStationInfo.setConstruction(255);

            List<NREquipmentInfo> nrEquipmentInfos = getEquipmentInfo(String.valueOf(pileStationInfo.getId()));
            nrStationInfo.setEquipmentInfos(nrEquipmentInfos);

            resultList.add(nrStationInfo);
        }
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("PageNo", pageInfo.getPageNum());
        map.put("PageCount", pageInfo.getPages());
        map.put("ItemSize", resultList.size());
        map.put("StationInfos", resultList);

        // 加密
        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        byte[] encryptText = Cryptos.aesEncrypt(JSONObject.toJSONString(map).getBytes(),
                configInfo.getDataSecret().getBytes(), configInfo.getDataSecretIv().getBytes());
        String encryptData = Encodes.encodeBase64(encryptText);

        resultMap.put("Data", encryptData);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
        resultMap.put("Sig", resultSign);

        return resultMap;
    }


    /**
     * 推送告警信息
     * @param dto
     * @return
     */
    @Override
    public String pushAlarmInfo(PushAlarmInfoDTO dto) {
        List<NRAlarmInfo> nrAlarmInfos = new ArrayList<>();

        // 通过站点id查询相关配置信息
        ThirdPartyStationRelation relation = new ThirdPartyStationRelation();
        relation.setStationId(dto.getStationId());
        ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(relation);
        if (relationInfo == null) {
            return null;
        }
        String operatorId = relationInfo.getOperatorId();
        String operatorSecret = relationInfo.getOperatorSecret();
        String signSecret = relationInfo.getSignSecret();
        String dataSecret = relationInfo.getDataSecret();
        String dataSecretIv = relationInfo.getDataSecretIv();
        String urlAddress = relationInfo.getUrlAddress();

        // 从缓存中获取故障原因
        String redisKey = CacheConstants.PILE_HARDWARE_FAULT + dto.getPileConnectorCode();
        String faultReason = redisCache.getCacheObject(redisKey);
        int status = 0;
        if (StringUtils.equals(dto.getConnectorStatus(), "01")) {
            // 故障
            status = 1;
        }
        // 封装对象
        NRAlarmInfo alarmInfo = NRAlarmInfo.builder()
                .connectorId(dto.getPileConnectorCode())
                .alertTime(DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS))
                .alertCode(120) // 120-预留
                .describe("急停按钮动作故障")
                .status(status)

                .build();
        nrAlarmInfos.add(alarmInfo);

        // 发送请求
        String url = urlAddress + "notification_alarmInfo";

        JSONObject data = new JSONObject();
        data.put("AlarmInfos", nrAlarmInfos);

        String jsonString = JSONObject.toJSONString(data);
        System.out.println("jsonString : " + jsonString);

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret,
                dataSecretIv, signSecret, dataSecret);
        String result = HttpRequestUtil.nrSendPost(token, jsonString, url, dataSecret
                , dataSecretIv, operatorId, signSecret);

        return result;
    }

    /**
     * 设备状态变化推送
     * @param realTimeMonitorData
     * @return
     */
    @Override
    public String pushPileStatus(RealTimeMonitorData realTimeMonitorData) {
        String pileConnectorCode = realTimeMonitorData.getPileSn() + realTimeMonitorData.getConnectorCode();
        String connectorStatus = realTimeMonitorData.getConnectorStatus();
        String transactionCode = realTimeMonitorData.getTransactionCode();

        // 查出该桩所属哪个站点
        String pileSn = StringUtils.substring(pileConnectorCode, 0, 14);
        PileStationVO stationVO = pileStationInfoService.getStationInfoByPileSn(pileSn);
        // 通过站点id查询相关配置信息
        ThirdPartyStationRelation relation = new ThirdPartyStationRelation();
        relation.setStationId(Long.parseLong(stationVO.getId()));
        ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(relation);
        if (relationInfo == null) {
            return null;
        }
        String operatorId = relationInfo.getOperatorId();
        String operatorSecret = relationInfo.getOperatorSecret();
        String signSecret = relationInfo.getSignSecret();
        String dataSecret = relationInfo.getDataSecret();
        String dataSecretIv = relationInfo.getDataSecretIv();
        String urlAddress = relationInfo.getUrlAddress();

        String url = urlAddress + "notification_stationStatus";

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        // 根据交易流水号查询订单信息
        OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByTransactionCode(transactionCode);
        // 封装对象
        NRConnectorStatusInfo nrConnectorStatusInfo = NRConnectorStatusInfo.builder()
                .connectorID(pileConnectorCode)
                .status(Integer.parseInt(connectorStatus))
                .currentA(new BigDecimal(realTimeMonitorData.getOutputCurrent()).intValue())
                .voltageA(new BigDecimal(realTimeMonitorData.getOutputVoltage()).intValue())
                .soc(BigDecimal.ZERO)
                .beginTime(DateUtils.formatDateTime(orderBasicInfo.getChargeStartTime()))
                .currentKwh(new BigDecimal(realTimeMonitorData.getChargingDegree()).setScale(3, BigDecimal.ROUND_HALF_UP))
                .timeStamp((int) (System.currentTimeMillis() / 1000))

                .build();
        if (StringUtils.isNotBlank(realTimeMonitorData.getSOC())) {
            nrConnectorStatusInfo.setSoc(new BigDecimal(realTimeMonitorData.getSOC()).setScale(1, BigDecimal.ROUND_HALF_UP));
        }

        // 发送请求
        JSONObject json = new JSONObject();
        json.put("ConnectorStatusInfo", nrConnectorStatusInfo);
        String jsonString = JSONObject.toJSONString(json);

        String result = HttpRequestUtil.nrSendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
        return result;
    }

    /**
     * 查询设备接口状态
     * 此接口用于批量查询设备实时状态
     * 由充电运营商方实现此接口，省、市两级监管平台调用。
     * @param dto
     * @return
     */
    @Override
    public Map<String, String> query_station_status(QueryStationInfoDTO dto) {
        List<String> stationIds = dto.getStationIds();
        List<NRStationStatusInfo> resultList = new ArrayList<>();
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        // 将 stationIdList 转换成 List<Long>
        List<Long> stationLongList = stationIds.stream()
                .map(Long::parseLong)
                .collect(Collectors.toList());

        QueryConnectorListDTO queryConnectorListDTO = QueryConnectorListDTO.builder()
                .stationIdList(stationLongList)
                .build();
        List<PileConnectorInfoVO> connectorInfoVOS = pileConnectorInfoService.getConnectorInfoListByParams(queryConnectorListDTO);
        if (CollectionUtils.isEmpty(connectorInfoVOS)) {
            return new LinkedHashMap<>();
        }
        // 根据stationId分组
        Map<String, List<PileConnectorInfoVO>> collect = connectorInfoVOS.stream()
                .collect(Collectors.groupingBy(PileConnectorInfoVO::getStationId));
        // 遍历 map
        for (Map.Entry<String, List<PileConnectorInfoVO>> entry : collect.entrySet()) {
            String stationId = entry.getKey();
            List<PileConnectorInfoVO> connectorList = entry.getValue();
            List<NRConnectorStatusInfo> connectorStatusInfoList = new ArrayList<>();

            for (PileConnectorInfoVO connectorInfoVO : connectorList) {
                NRConnectorStatusInfo nrConnectorStatusInfo = NRConnectorStatusInfo.builder()
                        .connectorID(connectorInfoVO.getPileConnectorCode())
                        .status(connectorInfoVO.getStatus())
                        .currentA(0)
                        .voltageA(0)
                        .soc(BigDecimal.ZERO)
                        .beginTime(null)
                        .currentKwh(BigDecimal.ZERO)
                        .timeStamp((int) (System.currentTimeMillis() / 1000))

                        .build();
                if (StringUtils.equals(String.valueOf(connectorInfoVO.getStatus()), "3")) {
                    // 充电中
                    nrConnectorStatusInfo.setCurrentA(connectorInfoVO.getCurrent().intValue());
                    nrConnectorStatusInfo.setVoltageA(connectorInfoVO.getVoltage().intValue());
                    nrConnectorStatusInfo.setSoc(new BigDecimal(connectorInfoVO.getSOC()));
                    String chargingTime = connectorInfoVO.getChargingTime();
                    Date beginTime = DateUtils.addMinute(new Date(), -Integer.parseInt(chargingTime));
                    nrConnectorStatusInfo.setBeginTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, beginTime));
                }
                if (StringUtils.equals(String.valueOf(connectorInfoVO.getStatus()), "255")) {
                    // 故障
                    nrConnectorStatusInfo.setStatus(255);
                }
                connectorStatusInfoList.add(nrConnectorStatusInfo);
            }
            // 封装参数
            NRStationStatusInfo stationStatusInfo = NRStationStatusInfo.builder()
                    .stationId(stationId)
                    .connectorStatusInfos(connectorStatusInfoList)
                    .build();
            resultList.add(stationStatusInfo);
        }
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("StationStatusInfos", resultList);

        // 加密
        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        byte[] encryptText = Cryptos.aesEncrypt(JSONObject.toJSONString(map).getBytes(),
                configInfo.getDataSecret().getBytes(), configInfo.getDataSecretIv().getBytes());
        String encryptData = Encodes.encodeBase64(encryptText);

        resultMap.put("Data", encryptData);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
        resultMap.put("Sig", resultSign);

        return resultMap;
    }

    /**
     * 充电电量信息推送
     * 当运营商平台完成一次充电时，将充电电量信息推送至省、市两级监管平台
     * @param orderCode
     * @return
     */
    @Override
    public String pushOrderInfo(String orderCode) {
        // 根据订单号查询订单信息
        NROrderInfoVO nrOrderInfoVO = orderBasicInfoService.getNROrderInfoByOrderCode(orderCode);
        NROrderInfo nrOrderInfo = formatNROrderInfo((nrOrderInfoVO));

        // 通过站点id查询相关配置信息
        ThirdPartyStationRelation relation = new ThirdPartyStationRelation();
        relation.setStationId(Long.parseLong(nrOrderInfoVO.getStationId()));
        ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(relation);
        if (relationInfo == null) {
            return null;
        }
        String operatorId = relationInfo.getOperatorId();
        String operatorSecret = relationInfo.getOperatorSecret();
        String signSecret = relationInfo.getSignSecret();
        String dataSecret = relationInfo.getDataSecret();
        String dataSecretIv = relationInfo.getDataSecretIv();
        String urlAddress = relationInfo.getUrlAddress();

        String url = urlAddress + "notification_orderInfo";

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        if (StringUtils.isBlank(token)) {
            return null;
        }

        // 发送请求
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("OrderInfo", nrOrderInfo);

        String jsonString = JSONObject.toJSONString(jsonObject);

        String result = HttpRequestUtil.nrSendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
        return result;
    }

    /**
     * 查询充电电量信息
     * 此接口用于批量查询时间区段内交易记录
     * @param dto
     * @return
     */
    @Override
    public Map<String, String> query_order_info(NRQueryOrderDTO dto) {
        List<NROrderInfo> resultList = new ArrayList<>();
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        List<NROrderInfoVO> nrOrderInfos = orderBasicInfoService.getNROrderInfos(dto);
        if (CollectionUtils.isEmpty(nrOrderInfos)) {
            return Maps.newLinkedHashMap();
        }
        for (NROrderInfoVO nrOrderInfoVO : nrOrderInfos) {
            NROrderInfo nrOrderInfo = formatNROrderInfo(nrOrderInfoVO);
            resultList.add(nrOrderInfo);
        }
        // 加密
        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        byte[] encryptText = Cryptos.aesEncrypt(JSONObject.toJSONString(resultList).getBytes(),
                configInfo.getDataSecret().getBytes(), configInfo.getDataSecretIv().getBytes());
        String encryptData = Encodes.encodeBase64(encryptText);

        resultMap.put("Data", encryptData);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
        resultMap.put("Sig", resultSign);

        return resultMap;
    }

    /**
     * 格式化南瑞平台订单对象
     * @param nrOrderInfoVO
     * @return
     */
    private NROrderInfo formatNROrderInfo(NROrderInfoVO nrOrderInfoVO) {
        // 将组织机构代码截取后九位
        // String organizationCode = nrOrderInfoVO.getOperatorId();
        // if (StringUtils.isBlank(organizationCode)) {
        //     return null;
        // }
        // String operatorId = StringUtils.substring(organizationCode, organizationCode.length() - 9);

        NROrderInfo nrOrderInfo = NROrderInfo.builder()
                .operatorId(Constants.OPERATORID_JIANG_SU)
                .connectorId(nrOrderInfoVO.getConnectorId())
                .startChargeSeq(nrOrderInfoVO.getStartChargeSeq())
                .userChargeType(1)
                .elect(nrOrderInfoVO.getElect())
                .cuspElect(nrOrderInfoVO.getCuspElect())
                .peakElect(nrOrderInfoVO.getPeakElect())
                .flatElect(nrOrderInfoVO.getFlatElect())
                .valleyElect(nrOrderInfoVO.getValleyElect())
                .startTime(nrOrderInfoVO.getStartTime())
                .endTime(nrOrderInfoVO.getEndTime())

                .build();
        // TODO 获取电表总起、止值
        // pileMsgRecordService.getPileFeedList()

        nrOrderInfo.setMeterValueStart(BigDecimal.ZERO);
        nrOrderInfo.setMeterValueEnd(BigDecimal.ZERO);
        return nrOrderInfo;
    }

    public static void main(String[] args) {
        String s = RandomStringUtils.randomAlphanumeric(16).toUpperCase(Locale.ROOT);
        System.out.println(s);

        // String chargingTime = "30";
        // Date beginTime = DateUtils.addMinute(new Date(), -Integer.parseInt(chargingTime));
        // String s = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, beginTime);
        // System.out.println(s);
    }

    /**
     * 获取设备信息
     * @param stationId
     * @return
     */
    private List<NREquipmentInfo> getEquipmentInfo(String stationId) {
        List<NREquipmentInfo> resultList = new ArrayList<>();
        List<PileBasicInfo> list = pileBasicInfoService.getPileListByStationId(stationId);
        if (CollectionUtils.isEmpty(list)) {
            return resultList;
        }
        // 封装成南瑞平台对象
        for (PileBasicInfo pileBasicInfo : list) {
            String pileSn = pileBasicInfo.getSn();
            // 获取桩状态
            Map<String, String> pileStatusMap = pileConnectorInfoService.getPileStatus(Lists.newArrayList(pileSn));
            String pileStatus = pileStatusMap.get(pileSn);
            if (StringUtils.equals(PileStatusEnum.ON_LINE.getValue(), pileStatus)) {
                pileStatus = "50"; // 50-正常使用
            } else if (StringUtils.equals(PileStatusEnum.OFF_LINE.getValue(), pileStatus)
                    || StringUtils.equals(PileStatusEnum.FAULT.getValue(), pileStatus)) {
                pileStatus = "6"; // 6-维护中
            }
            // 获取桩型号信息
            PileModelInfoVO modelInfo = pileModelInfoService.getPileModelInfoByPileSn(pileSn);
            if (modelInfo == null) {
                continue;
            }
            NREquipmentInfo equipmentInfo = NREquipmentInfo.builder()
                    .equipmentID(pileSn)
                    .equipmentName(pileSn)
                    .openForBusinessDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, pileBasicInfo.getCreateTime()))
                    .equipmentType(Integer.parseInt(modelInfo.getSpeedType()))
                    .equipmentStatus(Integer.parseInt(pileStatus))
                    .power(new BigDecimal(modelInfo.getRatedPower()).setScale(1, BigDecimal.ROUND_HALF_UP))

                    .vinFlag(1)
                    .equipmentPower(new BigDecimal(modelInfo.getRatedPower()).setScale(1, BigDecimal.ROUND_HALF_UP))
                    .newNationalStandard(1)
                    .constructionTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, pileBasicInfo.getProductionDate()))
                    .manufacturerID("014406554")
                    .build();
            // 获取枪口信息
            List<NRConnectorInfo> connectorInfos = getConnectorInfo(pileSn);
            equipmentInfo.setConnectorInfos(connectorInfos);

            resultList.add(equipmentInfo);
        }
        return resultList;
    }


    /**
     * 获取枪口信息
     * @param pileSn
     * @return
     */
    private List<NRConnectorInfo> getConnectorInfo(String pileSn) {
        List<NRConnectorInfo> resultList = new ArrayList<>();
        List<PileConnectorInfo> list = pileConnectorInfoService.selectPileConnectorInfoList(pileSn);
        if (CollectionUtils.isEmpty(list)) {
            return resultList;
        }
        PileModelInfoVO modelInfo = pileModelInfoService.getPileModelInfoByPileSn(pileSn);
        int connectorType = StringUtils.equals("1", modelInfo.getSpeedType()) ? 4 : 3;
        // 封装成南瑞平台对象
        for (PileConnectorInfo pileConnectorInfo : list) {
            NRConnectorInfo connectorInfo = NRConnectorInfo.builder()
                    .connectorId(pileConnectorInfo.getPileConnectorCode())
                    .connectorName(pileConnectorInfo.getPileConnectorCode())
                    .connectorType(connectorType)
                    .voltageUpperLimits(Integer.parseInt(modelInfo.getRatedVoltage()))
                    .voltageLowerLimits(Integer.parseInt(modelInfo.getRatedVoltage()))
                    .current(Integer.parseInt(modelInfo.getRatedCurrent()))
                    .power(new BigDecimal(modelInfo.getRatedPower()).setScale(1, BigDecimal.ROUND_HALF_UP))
                    .nationalStandard(2)

                    .build();
            resultList.add(connectorInfo);
        }
        return resultList;
    }
}
