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

import cn.hutool.core.util.PageUtil;
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.Constants;
import com.jsowell.common.core.domain.ykc.RealTimeMonitorData;
import com.jsowell.common.enums.lianlian.PayChannelEnum;
import com.jsowell.common.enums.lianlian.StationPaymentEnum;
import com.jsowell.common.enums.thirdparty.BusinessInformationExchangeEnum;
import com.jsowell.common.enums.thirdparty.ThirdPartyOperatorIdEnum;
import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum;
import com.jsowell.common.enums.ykc.OrderPayModeEnum;
import com.jsowell.common.enums.ykc.OrderStatusEnum;
import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.JWTUtils;
import com.jsowell.common.util.PageUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.*;
import com.jsowell.pile.domain.ykcCommond.StartChargingCommand;
import com.jsowell.pile.dto.*;
import com.jsowell.pile.service.*;
import com.jsowell.pile.thirdparty.CommonParamsDTO;
import com.jsowell.pile.thirdparty.EquipmentInfo;
import com.jsowell.pile.util.MerchantUtils;
import com.jsowell.pile.vo.ThirdPartySecretInfoVO;
import com.jsowell.pile.vo.base.*;
import com.jsowell.pile.vo.lianlian.AccumulativeInfoVO;
import com.jsowell.pile.vo.lianlian.PushStationFeeVO;
import com.jsowell.pile.vo.uniapp.customer.BillingPriceVO;
import com.jsowell.pile.vo.web.PileConnectorInfoVO;
import com.jsowell.pile.vo.web.PileStationVO;
import com.jsowell.thirdparty.lianlian.domain.*;
import com.jsowell.thirdparty.lianlian.vo.*;
import com.jsowell.thirdparty.platform.service.ThirdPartyPlatformService;
import com.jsowell.thirdparty.platform.common.ChargeDetail;
import com.jsowell.thirdparty.platform.common.OrderInfo;
import com.jsowell.thirdparty.platform.common.StationInfo;
import com.jsowell.thirdparty.platform.factory.ThirdPartyPlatformFactory;
import com.jsowell.thirdparty.platform.util.*;
import com.jsowell.thirdparty.service.ThirdpartySecretInfoService;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class LianLianPlatformServiceImpl implements ThirdPartyPlatformService {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    // 平台类型
    private final String thirdPlatformType = ThirdPlatformTypeEnum.LIAN_LIAN_PLATFORM.getTypeCode();

    @Autowired
    private PileMerchantInfoService pileMerchantInfoService;

    @Autowired
    private PileRemoteService pileRemoteService;

    @Autowired
    private YKCPushCommandService ykcPushCommandService;

    @Autowired
    private PileStationInfoService pileStationInfoService;

    @Autowired
    private PileBasicInfoService pileBasicInfoService;

    @Autowired
    private PileConnectorInfoService pileConnectorInfoService;

    @Autowired
    private PileBillingTemplateService pileBillingTemplateService;

    @Autowired
    private OrderBasicInfoService orderBasicInfoService;

    @Autowired
    private ThirdPartyPlatformConfigService thirdPartyPlatformConfigService;

    @Autowired
    private ThirdPartySettingInfoService thirdPartySettingInfoService;

    @Resource
    private ThirdPartyStationRelationService thirdPartyStationRelationService;

    @Autowired
    private ThirdpartySecretInfoService thirdpartySecretInfoService;

    @Override
    public void afterPropertiesSet() throws Exception {
        ThirdPartyPlatformFactory.register(thirdPlatformType, this);
    }

    @Override
    public void printServiceName() {
        System.out.println("当前类名：" + this.getClass().getSimpleName());
    }

    // @Override
    public Map<String, String> queryTokenOld(CommonParamsDTO dto) {
        String operatorId = dto.getOperatorID();
        // 通过operatorId 查出 operatorSecret
        ThirdPartyPlatformConfig platformConfig = thirdPartyPlatformConfigService.getInfoByOperatorId(operatorId);
        if (platformConfig == null) {
            return null;
        }
        String operatorSecret = platformConfig.getOperatorSecret();
        String dataSecret = platformConfig.getDataSecret();
        String dataSecretIv = platformConfig.getDataSecretIv();
        String signSecret = platformConfig.getSignSecret();
        // 使用公共方法生成token
        Map<String, String> resultMap = generateToken(operatorSecret, dataSecret, dataSecretIv, signSecret, operatorId, dto.getData());

        // 拼装

        // 加密

        return resultMap;
    }

    @Override
    public Map<String, String> queryToken(CommonParamsDTO dto) {
        AccessTokenVO vo = new AccessTokenVO();
        // 0:成功；1:失败
        int succStat = 0;
        // 0:无；1:无此对接平台；2:密钥错误； 3～99:自定义
        int failReason = 0;

        String operatorId = StringUtils.isNotBlank(dto.getOperatorID()) ? dto.getOperatorID() : dto.getPlatformID();
        // 通过operatorId 查出 operatorSecret
        ThirdPartySecretInfoVO thirdPartySecretInfoVO = thirdpartySecretInfoService.queryByOperatorId(operatorId);
        if (thirdPartySecretInfoVO == null) {
            failReason = 1;
            succStat = 1;
        } else {
            String theirOperatorSecret = thirdPartySecretInfoVO.getTheirOperatorSecret();
            String dataSecret = thirdPartySecretInfoVO.getOurDataSecret();
            String dataSecretIv = thirdPartySecretInfoVO.getOurDataSecretIv();
            // 解密data 获取参数中的OperatorSecret
            String decrypt = Cryptos.decrypt(dto.getData(), dataSecret, dataSecretIv);
            String inputOperatorSecret = null;
            if (StringUtils.isNotBlank(decrypt)) {
                inputOperatorSecret = JSON.parseObject(decrypt).getString("OperatorSecret");
            }
            // 对比密钥
            List<String> operatorSecretList = Lists.newArrayList(theirOperatorSecret, thirdPartySecretInfoVO.getOurOperatorSecret());
            if (!operatorSecretList.contains(inputOperatorSecret)) {
                failReason = 1;
                succStat = 1;
            } else {
                // 生成token
                String token = JWTUtils.createToken(operatorId, theirOperatorSecret, JWTUtils.ttlMillis);
                vo.setAccessToken(token);
                vo.setTokenAvailableTime((int) (JWTUtils.ttlMillis / 1000));
            }
        }
        // 组装返回参数
        vo.setPlatformId(operatorId);
        vo.setFailReason(failReason);
        vo.setSuccStat(succStat);

        Map<String, String> resultMap = ThirdPartyPlatformUtils.generateResultMap(vo, thirdPartySecretInfoVO);
        return resultMap;
    }

    public static void main(String[] args) {
        // 中电联平台
        String operatorId = "14405899X";
        String operatorSecret = "EOub5WNbERyOedvk";
        String dataSecret = "vj3RWNsWIxT5MC0K";
        String dataSecretIv = "jjkySnGlM3pbOUki";
        String signSecret = "NbELMbWtbHikNSlu";

        String data = "JdVMdw0JVYvouzS4WA9APlqKyQJuTuvh43lDYGaVccrvMboNTVajQdkvtLfqq3+lxlUXkokSkGSDsmxNkUT/SQ==";
        String Seq = "0029";
        String sig = "C6410BF5C7185CAE8594846E006740E1";
        String timeStamp = "2024-03-27 16:18:39";

        // 解密data 获取参数中的OperatorSecret
        try {
            String decrypt = Cryptos.decrypt(data, dataSecret, dataSecretIv);
            String inputOperatorSecret = null;
            if (StringUtils.isNotBlank(decrypt)) {
                inputOperatorSecret = JSON.parseObject(decrypt).getString("OperatorSecret");
            }
            if (!StringUtils.equals(operatorSecret, inputOperatorSecret)) {
                throw new RuntimeException("密钥不一致");
            }
        } catch (RuntimeException e) {
            throw new BusinessException("2", "密钥错误");
        }

    }

    /**
     * 查询充电站信息 query_stations_info
     * 此接口用于查询对接平台的充电站的信息
     *
     * @param dto 查询站点信息dto
     * @throws UnsupportedOperationException 未实现异常
     */
    @Override
    public Map<String, String> queryStationsInfo(QueryStationInfoDTO dto) {

        int pageNo = dto.getPageNo() == null ? 1 : dto.getPageNo();
        int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();

        PageUtils.startPage(pageNo, pageSize);
        List<ThirdPartyStationInfoVO> stationInfos = pileStationInfoService.getStationInfosByThirdParty(dto);
        if (CollectionUtils.isEmpty(stationInfos)) {
            // 未查到数据
            return null;
        }
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        PageInfo<ThirdPartyStationInfoVO> pageInfo = new PageInfo<>(stationInfos);
        List<StationInfo> resultList = new ArrayList<>();
        for (ThirdPartyStationInfoVO pileStationInfo : pageInfo.getList()) {
            StationInfo stationInfo = new StationInfo();
            String stationId = String.valueOf(pileStationInfo.getId());
            stationInfo.setStationID(stationId);
            // MerchantInfoVO merchantInfo = pileMerchantInfoService.getMerchantInfo(String.valueOf(pileStationInfo.getMerchantId()));
            stationInfo.setOperatorID(Constants.OPERATORID_LIANLIAN); // 组织机构代码
            stationInfo.setEquipmentOwnerID(String.valueOf(pileStationInfo.getMerchantId()));
            stationInfo.setStationName(pileStationInfo.getStationName());
            stationInfo.setIsAloneApply(Integer.valueOf(pileStationInfo.getAloneApply()));
            stationInfo.setIsPublicParkingLot(Integer.valueOf(pileStationInfo.getPublicParking()));
            stationInfo.setCountryCode(pileStationInfo.getCountryCode());
            stationInfo.setAreaCode(pileStationInfo.getAreaCode());
            stationInfo.setAddress(pileStationInfo.getAddress());
            stationInfo.setServiceTel(pileStationInfo.getStationTel());
            stationInfo.setStationType(Integer.valueOf(pileStationInfo.getStationType()));
            stationInfo.setParkNums(Integer.valueOf(pileStationInfo.getParkNums()));
            stationInfo.setStationLng(new BigDecimal(pileStationInfo.getStationLng()));
            stationInfo.setStationLat(new BigDecimal(pileStationInfo.getStationLat()));
            stationInfo.setConstruction(Integer.valueOf(pileStationInfo.getConstruction()));
            stationInfo.setOpenAllDay(Integer.valueOf(pileStationInfo.getOpenAllDay()));
            // stationInfo.setMinElectricityPrice(pileStationInfo); // 最低充电电费率
            // stationInfo.setElectricityFee(); // 电费 xx元/度
            // stationInfo.setServiceFee(); // 服务费 xx元/度
            stationInfo.setParkFree(Integer.valueOf(pileStationInfo.getParkFree()));
            stationInfo.setPayment(pileStationInfo.getPayment());
            stationInfo.setSupportOrder(Integer.valueOf(pileStationInfo.getSupportOrder()));
            // stationInfo.setParkFeeType(pileStationInfo); // 停车收费类型
            stationInfo.setToiletFlag(Integer.valueOf(pileStationInfo.getToiletFlag()));
            stationInfo.setStoreFlag(Integer.valueOf(pileStationInfo.getStoreFlag()));
            stationInfo.setRestaurantFlag(Integer.valueOf(pileStationInfo.getRestaurantFlag()));
            stationInfo.setLoungeFlag(Integer.valueOf(pileStationInfo.getLoungeFlag()));
            stationInfo.setCanopyFlag(Integer.valueOf(pileStationInfo.getCanopyFlag()));
            stationInfo.setPrinterFlag(Integer.valueOf(pileStationInfo.getPrinterFlag()));
            stationInfo.setBarrierFlag(Integer.valueOf(pileStationInfo.getBarrierFlag()));
            stationInfo.setParkingLockFlag(Integer.valueOf(pileStationInfo.getParkingLockFlag()));

            List<EquipmentInfo> pileList = pileBasicInfoService.getPileListForLianLian(stationId);
            if (CollectionUtils.isNotEmpty(pileList)) {
                stationInfo.setEquipmentInfos(pileList); // 充电设备信息列表
            }

            resultList.add(stationInfo);
        }
        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();
        // 加密数据
        String encryptData = Cryptos.aesEncrypt(JSON.toJSONString(map), configInfo.getDataSecret(), configInfo.getDataSecretIv());
        resultMap.put("Data", encryptData);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
        resultMap.put("Sig", resultSign);
        return resultMap;
    }

    /**
     * 设备接口状态查询 query_station_status
     *
     * @param dto 查询站点信息dto
     * @throws UnsupportedOperationException 未实现异常
     */
    @Override
    public Map<String, String> queryStationStatus(QueryStationInfoDTO dto) {
        List<String> stationIds = dto.getStationIds();
        List<StationStatusInfo> StationStatusInfos = new ArrayList<>();
        List<Object> ConnectorStatusInfos = new ArrayList<>();
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        ConnectorStatusInfo connectorStatusInfo;
        for (String stationId : stationIds) {
            StationStatusInfo stationStatusInfo = new StationStatusInfo();
            stationStatusInfo.setStationId(stationId);
            // 根据站点id查询
            List<ConnectorInfoVO> list = pileConnectorInfoService.getConnectorListForLianLian(Long.parseLong(stationId));
            for (ConnectorInfoVO connectorInfoVO : list) {

                String connectorStatus = connectorInfoVO.getConnectorStatus();
                if (StringUtils.equals(connectorStatus, PileConnectorDataBaseStatusEnum.OCCUPIED_CHARGING.getValue())) {
                    // 充电中
                    ConnectorChargeStatusInfo info = new ConnectorChargeStatusInfo();
                    OrderBasicInfo orderBasicInfo = orderBasicInfoService.queryChargingByPileConnectorCode(connectorInfoVO.getPileConnectorCode());
                    if (orderBasicInfo == null) {
                        continue;
                    }
                    List<RealTimeMonitorData> chargingRealTimeData = orderBasicInfoService.getChargingRealTimeData(orderBasicInfo.getTransactionCode());
                    if (CollectionUtils.isNotEmpty(chargingRealTimeData)) {
                        RealTimeMonitorData realTimeMonitorData = chargingRealTimeData.get(0);

                        info.setStartChargeSeq(orderBasicInfo.getOrderCode());
                        info.setConnectorID(orderBasicInfo.getPileConnectorCode());
                        info.setConnectorStatus(Integer.valueOf(connectorInfoVO.getConnectorStatus()));
                        info.setCurrentA(new BigDecimal(realTimeMonitorData.getOutputCurrent()));
                        info.setVoltageA(new BigDecimal(realTimeMonitorData.getOutputVoltage()));
                        info.setSoc(new BigDecimal(realTimeMonitorData.getSOC()));
                        info.setStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderBasicInfo.getChargeStartTime()));
                        info.setEndTime(DateUtils.getDateTime()); // 本次采样时间
                        info.setTotalPower(new BigDecimal(realTimeMonitorData.getChargingDegree())); // 累计充电量
                        // info.setElecMoney(); // 累计电费
                        // info.setSeviceMoney(); // 累计服务费
                        info.setTotalMoney(new BigDecimal(realTimeMonitorData.getChargingAmount()));

                        ConnectorStatusInfos.add(info);
                    }
                } else {
                    // 其他
                    connectorStatusInfo = new ConnectorStatusInfo();
                    connectorStatusInfo.setConnectorID(connectorInfoVO.getPileConnectorCode());
                    connectorStatusInfo.setStatus(Integer.parseInt(connectorInfoVO.getConnectorStatus()));

                    ConnectorStatusInfos.add(connectorStatusInfo);
                }
            }
            stationStatusInfo.setConnectorStatusInfos(ConnectorStatusInfos);
            StationStatusInfos.add(stationStatusInfo);
        }
        // 将 StationStatusInfos 分页
        int pageNum = 1;
        int pageSize = 10;
        List<StationStatusInfo> collect = StationStatusInfos.stream()
                .skip((pageNum - 1) * pageSize)
                .limit(pageSize)
                .collect(Collectors.toList());

        int total = StationStatusInfos.size();
        int pages = PageUtil.totalPage(total, pageSize);

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("Total", total);
        map.put("StationStatusInfos", collect);

        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        String encryptData = Cryptos.aesEncrypt(JSON.toJSONString(map), configInfo.getDataSecret(), configInfo.getDataSecretIv());
        resultMap.put("Data", encryptData);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
        resultMap.put("Sig", resultSign);
        return resultMap;
    }

    /**
     * 查询统计信息 query_station_stats
     *
     * @param dto 查询站点信息dto
     * @throws UnsupportedOperationException 未实现异常
     */
    @Override
    public Map<String, String> queryStationStats(QueryStationInfoDTO dto) {
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        // 根据站点id 查出这段时间的充电量
        List<AccumulativeInfoVO> list = orderBasicInfoService.getAccumulativeInfoForLianLian(dto);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }

        // 根据充电桩编号分组 key=充电桩编号
        Map<String, List<AccumulativeInfoVO>> pileMap = list.stream()
                .collect(Collectors.groupingBy(AccumulativeInfoVO::getPileSn));

        // 存放所有充电桩设备
        List<EquipmentStatsInfo> equipmentStatsInfoList = Lists.newArrayList();
        // 站点用电量
        BigDecimal stationElectricity = BigDecimal.ZERO;
        // 用于记录枪口用电量 在循环每个枪口的时候初始化
        BigDecimal pileElec;
        for (String pileSn : pileMap.keySet()) {
            // 该充电桩下 所有枪口的用电数据
            List<AccumulativeInfoVO> accumulativeInfoVOS = pileMap.get(pileSn);
            if (CollectionUtils.isEmpty(accumulativeInfoVOS)) {
                continue;
            }

            // 存放充电桩用电量
            pileElec = BigDecimal.ZERO;

            // key=枪口编号  value 该枪口的用电数据
            Map<String, List<AccumulativeInfoVO>> collect = accumulativeInfoVOS.stream()
                    .collect(Collectors.groupingBy(AccumulativeInfoVO::getPileConnectorCode));

            List<ConnectorStatsInfo> connectorStatsInfos = Lists.newArrayList();
            for (Map.Entry<String, List<AccumulativeInfoVO>> entry : collect.entrySet()) {
                String pileConnectorCode = entry.getKey();
                List<AccumulativeInfoVO> value = entry.getValue();
                // 枪口用电量求和
                BigDecimal connectorElec = value.stream()
                        .map(AccumulativeInfoVO::getConnectorElectricity)
                        .map(BigDecimal::new)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);

                connectorStatsInfos.add(
                        ConnectorStatsInfo.builder()
                                .connectorID(pileConnectorCode)
                                .connectorElectricity(connectorElec)
                                .build()
                );
                // 充电桩电量为枪口用电量累计
                pileElec = pileElec.add(connectorElec);
            }

            EquipmentStatsInfo build = EquipmentStatsInfo.builder()
                    .equipmentID(pileSn)
                    .equipmentElectricity(pileElec)
                    .connectorStatsInfos(connectorStatsInfos)
                    .build();
            equipmentStatsInfoList.add(build);

            // 所有充电桩用电量之和
            stationElectricity = stationElectricity.add(pileElec);
        }

        StationStatsInfo stationStatsInfo = StationStatsInfo.builder()
                .stationID(dto.getStationID())
                .startTime(dto.getStartTime())
                .endTime(dto.getEndTime())
                .stationElectricity(stationElectricity)
                .equipmentStatsInfos(equipmentStatsInfoList) // 设备列表
                .build();

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("StationStats", stationStatsInfo);

        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        String encryptData = Cryptos.aesEncrypt(JSON.toJSONString(map), configInfo.getDataSecret(), configInfo.getDataSecretIv());
        resultMap.put("Data", encryptData);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
        resultMap.put("Sig", resultSign);
        return resultMap;
    }


    /**
     * 充电站信息变化推送 notification_stationInfo
     * 新站需要推送。当站点信息发生变化时，推送新的信息通知到市级平台
     *
     * @param stationId 充电站id
     * @throws UnsupportedOperationException 未实现异常
     */
    @Override
    public String notificationStationInfo(String stationId) {
        // 通过id查询站点相关信息
        PileStationInfo pileStationInfo = pileStationInfoService.selectPileStationInfoById(Long.parseLong(stationId));
        // 通过第三方配置类型查询相关配置信息
        ThirdPartySettingInfo settingInfo = new ThirdPartySettingInfo();
        settingInfo.setType(thirdPlatformType);
        ThirdPartySettingInfo thirdPartySettingInfo = thirdPartySettingInfoService.selectSettingInfo(settingInfo);

        String operatorId = thirdPartySettingInfo.getOperatorId();
        String operatorSecret = thirdPartySettingInfo.getOperatorSecret();
        String signSecret = thirdPartySettingInfo.getSignSecret();
        String dataSecret = thirdPartySettingInfo.getDataSecret();
        String dataSecretIv = thirdPartySettingInfo.getDataSecretIv();
        String urlAddress = thirdPartySettingInfo.getUrlAddress();

        // 组装联联平台所需要的数据格式
        StationInfo info = StationInfo.builder()
                .stationID("LC" + stationId)
                .operatorID(operatorId)
                .stationName(pileStationInfo.getStationName())
                .isAloneApply(Integer.valueOf(pileStationInfo.getAloneApply()))
                .isPublicParkingLot(Integer.valueOf(pileStationInfo.getPublicParking()))
                .countryCode(pileStationInfo.getCountryCode())
                .address(pileStationInfo.getAddress())
                .serviceTel(pileStationInfo.getStationTel())
                .stationType(Integer.valueOf(pileStationInfo.getStationType()))
                .stationStatus(Integer.valueOf(pileStationInfo.getStationStatus()))
                .parkNums(Integer.valueOf(pileStationInfo.getParkNums()))
                .stationLng(new BigDecimal(pileStationInfo.getStationLng()))
                .stationLat(new BigDecimal(pileStationInfo.getStationLat()))
                .construction(Integer.valueOf(pileStationInfo.getConstruction()))
                .openAllDay(Integer.valueOf(pileStationInfo.getOpenAllDay()))
                .minElectricityPrice(new BigDecimal(Constants.ZERO))
                .electricityFee(Constants.ZERO)
                .serviceFee(Constants.ZERO)
                .parkFree(Integer.valueOf(pileStationInfo.getParkFree()))
                .supportOrder(Integer.valueOf(pileStationInfo.getSupportOrder()))
                .parkFeeType(0)
                .toiletFlag(Integer.valueOf(pileStationInfo.getToiletFlag()))
                .storeFlag(Integer.valueOf(pileStationInfo.getStoreFlag()))
                .restaurantFlag(Integer.valueOf(pileStationInfo.getRestaurantFlag()))
                .loungeFlag(Integer.valueOf(pileStationInfo.getLoungeFlag()))
                .canopyFlag(Integer.valueOf(pileStationInfo.getCanopyFlag()))
                .printerFlag(Integer.valueOf(pileStationInfo.getPrinterFlag()))
                .barrierFlag(Integer.valueOf(pileStationInfo.getBarrierFlag()))
                .parkingLockFlag(Integer.valueOf(pileStationInfo.getParkingLockFlag()))
                .build();
        String areaCode = pileStationInfo.getAreaCode();  // 330000,330200,330213
        // 根据逗号分组
        String[] split = StringUtils.split(areaCode, ",");
        // 只取最后一部分  330213
        String subAreaCode = split[split.length - 1];
        info.setAreaCode(subAreaCode);
        // 截取运营商组织机构代码(去除最后一位后的最后九位)
        String organizationCode = "";
        if (StringUtils.equals(ThirdPlatformTypeEnum.LIAN_LIAN_PLATFORM.getTypeCode(), thirdPlatformType)) {
            // 联联平台先使用自己运营商的组织机构代码
            organizationCode = Constants.OPERATORID_LIANLIAN;
            info.setEquipmentOwnerID(organizationCode);
        } else {
            MerchantInfoVO merchantInfo = pileMerchantInfoService.getMerchantInfoVO(String.valueOf(pileStationInfo.getMerchantId()));
            organizationCode = merchantInfo.getOrganizationCode();
            if (StringUtils.isNotBlank(organizationCode) && organizationCode.length() == 18) {
                String equipmentOwnerId = StringUtils.substring(organizationCode, organizationCode.length() - 10, organizationCode.length() - 1);
                info.setEquipmentOwnerID(equipmentOwnerId);
            }
        }
        if (StringUtils.equals("36", String.valueOf(pileStationInfo.getMerchantId()))) {
            // 远大
            info.setEquipmentOwnerID(Constants.OPERATORID_YUAN_DA);
        }
        if (MerchantUtils.isXiXiaoMerchant(String.valueOf(pileStationInfo.getMerchantId()))) {
            // 如果是希晓运营商，则把equipmentOwnerID换成希晓
            info.setEquipmentOwnerID(Constants.OPERATORID_XI_XIAO);
        }
        String payment = StationPaymentEnum.getPaymentByCode(pileStationInfo.getPayment());
        info.setPayment(payment);
        if (StringUtils.isNotBlank(pileStationInfo.getParkingNumber())) {
            info.setIsPublicParkingLot(1);
            info.setParkingLotNumber(pileStationInfo.getParkingNumber());
        }
        // 户号
        if (StringUtils.isNotBlank(pileStationInfo.getAccountNumber())) {
            info.setAccountNumber(pileStationInfo.getAccountNumber());
        }

        // 容量
        if (StringUtils.isNotBlank(String.valueOf(pileStationInfo.getCapacity()))) {
            info.setCapacity(pileStationInfo.getCapacity().setScale(4, BigDecimal.ROUND_HALF_UP));
        }
        List<EquipmentInfo> pileList = pileBasicInfoService.getPileListForLianLian(stationId);
        if (CollectionUtils.isNotEmpty(pileList)) {
            info.setEquipmentInfos(pileList); // 充电设备信息列表
        }

        // 调用联联平台接口
        String url = urlAddress + "notification_stationInfo";

        String jsonStr = JSON.toJSONString(info);
        JSONObject data = new JSONObject();
        data.put("StationInfo", jsonStr);

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

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

        // 新增数据库
        thirdPartyStationRelationService.insertInfo2DataBase(thirdPlatformType, stationId);
        return thirdPlatformType + "：" + result;
    }

    /**
     * 设备状态变化推送  notification_stationStatus
     * 推送充电设备接口状态信息 supervise_notification_station_status
     *
     * @param dto           枪口状态
     * @throws UnsupportedOperationException 未实现异常
     */
    @Override
    public String notificationStationStatus(PushRealTimeInfoDTO dto) {
        String thirdPartyType = dto.getThirdPartyType();
        String status = dto.getStatus();
        String pileConnectorCode = dto.getPileConnectorCode();

        // 查出该桩所属哪个站点
        String pileSn = StringUtils.substring(pileConnectorCode, 0, 14);
        PileStationVO stationVO = pileStationInfoService.getStationInfoByPileSn(pileSn);
        // 通过站点id查询相关配置信息
        ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(stationVO.getId());
        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 + BusinessInformationExchangeEnum.NOTIFICATION_STATION_STATUS.getValue();
        ConnectorStatusInfo info = ConnectorStatusInfo.builder()
                .connectorID(pileConnectorCode)
                .status(Integer.parseInt(status))
                .build();
        // 调用联联平台接口
        JSONObject json = new JSONObject();
        json.put("ConnectorStatusInfo", info);
        String jsonString = JSON.toJSONString(json);
        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
        return result;
    }

    /**
     * 设备充电中状态变化推送 notification_connector_charge_status
     *
     * @param orderCode 订单编号
     */
    @Override
    public String notificationConnectorChargeStatus(String orderCode) {
        // 通过订单号查询信息
        OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
        // 根据枪口号查询充电实时状态
        // OrderBasicInfo orderBasicInfo = orderBasicInfoService.queryChargingByPileConnectorCode(orderInfo.getPileConnectorCode());
        List<RealTimeMonitorData> list = orderBasicInfoService.getChargingRealTimeData(orderInfo.getTransactionCode());
        RealTimeMonitorData realTimeMonitorData = list.get(0);
        // 拼装联联参数
        ConnectorChargeStatusInfo info = ConnectorChargeStatusInfo.builder()
                .startChargeSeq(orderCode)
                .connectorID(orderInfo.getPileConnectorCode())
                .connectorStatus(Integer.valueOf(realTimeMonitorData.getConnectorStatus()))
                .currentA(new BigDecimal(realTimeMonitorData.getOutputCurrent()))
                .voltageA(new BigDecimal(realTimeMonitorData.getOutputVoltage()))
                .soc(new BigDecimal(realTimeMonitorData.getSOC()))
                .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderInfo.getChargeStartTime()))
                .endTime(DateUtils.getDateTime())
                .totalPower(new BigDecimal(realTimeMonitorData.getChargingDegree()))
                .elecMoney(new BigDecimal("0")) // TODO
                .seviceMoney(new BigDecimal("0")) // TODO
                .totalMoney(new BigDecimal(realTimeMonitorData.getChargingAmount()).setScale(2, BigDecimal.ROUND_HALF_UP))
                .build();

        // 通过站点id查询相关配置信息
        ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(orderInfo.getStationId());
        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_connector_charge_status";

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        JSONObject json = new JSONObject();
        json.put("ConnectorChargeStatusInfo", info);
        String jsonString = JSON.toJSONString(json);
        // 发送请求
        String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
        return result;
    }

    @Override
    public String notificationConnectorChargeStatus(String orderCode, ThirdPartySecretInfoVO secretInfoVO) {
        // 通过订单号查询信息
        OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
        // 根据枪口号查询充电实时状态
        // OrderBasicInfo orderBasicInfo = orderBasicInfoService.queryChargingByPileConnectorCode(orderInfo.getPileConnectorCode());
        List<RealTimeMonitorData> list = orderBasicInfoService.getChargingRealTimeData(orderInfo.getTransactionCode());
        RealTimeMonitorData realTimeMonitorData = list.get(0);
        // 拼装联联参数
        ConnectorChargeStatusInfo info = ConnectorChargeStatusInfo.builder()
                .startChargeSeq(orderCode)
                .connectorID(orderInfo.getPileConnectorCode())
                .connectorStatus(Integer.valueOf(realTimeMonitorData.getConnectorStatus()))
                .currentA(new BigDecimal(realTimeMonitorData.getOutputCurrent()))
                .voltageA(new BigDecimal(realTimeMonitorData.getOutputVoltage()))
                .soc(new BigDecimal(realTimeMonitorData.getSOC()))
                .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderInfo.getChargeStartTime()))
                .endTime(DateUtils.getDateTime())
                .totalPower(new BigDecimal(realTimeMonitorData.getChargingDegree()))
                .elecMoney(new BigDecimal("0")) // TODO
                .seviceMoney(new BigDecimal("0")) // TODO
                .totalMoney(new BigDecimal(realTimeMonitorData.getChargingAmount()).setScale(2, BigDecimal.ROUND_HALF_UP))
                .build();

        // 通过站点id查询相关配置信息
        // ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(orderInfo.getStationId());
        // if (relationInfo == null) {
        //     return null;
        // }
        String operatorId = secretInfoVO.getTheirOperatorId();
        String operatorSecret = secretInfoVO.getTheirOperatorSecret();
        String signSecret = secretInfoVO.getTheirSigSecret();
        String dataSecret = secretInfoVO.getTheirDataSecret();
        String dataSecretIv = secretInfoVO.getTheirDataSecretIv();
        String urlAddress = secretInfoVO.getTheirUrlPrefix();

        String url = urlAddress + "notification_connector_charge_status";

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        JSONObject json = new JSONObject();
        json.put("ConnectorChargeStatusInfo", info);
        String jsonString = JSON.toJSONString(json);
        // 发送请求
        String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
        return result;
    }

    /**
     * 订单信息推送 notification_orderInfo
     *
     * @param orderCode
     * @throws UnsupportedOperationException 未实现异常
     */
    @Override
    public String notificationChargeOrderInfo(String orderCode) {

        // 根据订单号查询出信息
        OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
        OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode);

        // 通过站点id查询相关配置信息
        ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(orderBasicInfo.getStationId());
        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";

        // 拼装成联联平台所需格式对象
        OrderInfo orderInfo = OrderInfo.builder()
                .operatorID(operatorId)
                .equipmentOwnerID(Constants.OPERATORID_LIANLIAN)
                .stationID("LC" + orderBasicInfo.getStationId())
                .equipmentID(orderBasicInfo.getPileSn())
                .connectorID(orderBasicInfo.getPileConnectorCode())
                .startChargeSeq(orderCode)
                .userChargeType(Constants.one)
                .money(new BigDecimal(String.valueOf(orderBasicInfo.getOrderAmount())).setScale(2, BigDecimal.ROUND_HALF_UP))
                .electMoney(new BigDecimal(String.valueOf(orderDetail.getTotalElectricityAmount())).setScale(2, BigDecimal.ROUND_HALF_UP))
                .serviceMoney(new BigDecimal(String.valueOf(orderDetail.getTotalServiceAmount())).setScale(2, BigDecimal.ROUND_HALF_UP))
                .elect(new BigDecimal(String.valueOf(orderDetail.getTotalUsedElectricity())).setScale(2, BigDecimal.ROUND_HALF_UP))
                .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderBasicInfo.getChargeStartTime()))
                .endTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderBasicInfo.getChargeEndTime()))
                .paymentAmount(orderBasicInfo.getPayAmount())
                // .payChannel()
                .stopReason(0)
                // .chargeDetails()
                .build();
        if (MerchantUtils.isXiXiaoMerchant(orderBasicInfo.getMerchantId())) {
            orderInfo.setEquipmentOwnerID(Constants.OPERATORID_XI_XIAO);
        }
        // 支付方式
        if (StringUtils.equals(orderBasicInfo.getPayMode(), OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) {
            // 微信支付
            orderInfo.setPayChannel(Integer.valueOf(PayChannelEnum.WEXIN_PAY.getCode()));
        } else if (StringUtils.equals(orderBasicInfo.getPayMode(), OrderPayModeEnum.PAYMENT_OF_ALIPAY.getValue())) {
            // 支付宝支付
            orderInfo.setPayChannel(Integer.valueOf(PayChannelEnum.ALI_PAY.getCode()));
        } else {
            // 其他
            orderInfo.setPayChannel(Integer.valueOf(PayChannelEnum.OTHER.getCode()));
        }
        // 订单详情
        ChargeDetail detail;

        List<BillingPriceVO> billingList = pileBillingTemplateService.queryBillingPrice(orderBasicInfo.getStationId());
        // 先将list按照 尖、峰、平、谷 时段排序
        // List<BillingPriceVO> collect = billingList.stream().sorted(Comparator.comparing(BillingPriceVO::getTimeType)).collect(Collectors.toList());
        // 再循环该list，拼装对应的充电价格、费率
        List<ChargeDetail> chargeDetails = new ArrayList<>();
        for (BillingPriceVO billingPriceVO : billingList) {
            detail = new ChargeDetail();
            if (StringUtils.equals(billingPriceVO.getTimeType(), "1")) {
                // 尖时段
                detail.setDetailStartTime(billingPriceVO.getStartTime());
                detail.setDetailEndTime(billingPriceVO.getEndTime());
                detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setDetailPower(orderDetail.getSharpUsedElectricity());
                detail.setDetailElecMoney(orderDetail.getSharpElectricityPrice());
                detail.setDetailSeviceMoney(orderDetail.getSharpServicePrice());
            } else if (StringUtils.equals(billingPriceVO.getTimeType(), "2")) {
                // 峰时段
                detail.setDetailStartTime(billingPriceVO.getStartTime());
                detail.setDetailEndTime(billingPriceVO.getEndTime());
                detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setDetailPower(orderDetail.getPeakUsedElectricity());
                detail.setDetailElecMoney(orderDetail.getPeakElectricityPrice());
                detail.setDetailSeviceMoney(orderDetail.getPeakServicePrice());
            } else if (StringUtils.equals(billingPriceVO.getTimeType(), "3")) {
                // 平时段
                detail.setDetailStartTime(billingPriceVO.getStartTime());
                detail.setDetailEndTime(billingPriceVO.getEndTime());
                detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setDetailPower(orderDetail.getFlatUsedElectricity());
                detail.setDetailElecMoney(orderDetail.getFlatElectricityPrice());
                detail.setDetailSeviceMoney(orderDetail.getFlatServicePrice());
            } else if (StringUtils.equals(billingPriceVO.getTimeType(), "4")) {
                // 谷时段
                detail.setDetailStartTime(billingPriceVO.getStartTime());
                detail.setDetailEndTime(billingPriceVO.getEndTime());
                detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setDetailPower(orderDetail.getValleyUsedElectricity());
                detail.setDetailElecMoney(orderDetail.getValleyElectricityPrice());
                detail.setDetailSeviceMoney(orderDetail.getValleyServicePrice());
            }
            chargeDetails.add(detail);
        }
        orderInfo.setChargeDetails(chargeDetails);

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        // 调用联联平台接口
        JSONObject json = new JSONObject();
        json.put("OrderInfo", orderInfo);
        String jsonString = JSON.toJSONString(json);
        String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
        return result;
    }

    @Override
    public String notificationChargeOrderInfo(String orderCode, ThirdPartySecretInfoVO secretInfoVO) {

        // 根据订单号查询出信息
        OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
        OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode);

        // 通过站点id查询相关配置信息
        // ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(orderBasicInfo.getStationId());
        // if (relationInfo == null) {
        //     return null;
        // }
        String operatorId = secretInfoVO.getTheirOperatorId();
        String operatorSecret = secretInfoVO.getTheirOperatorSecret();
        String signSecret = secretInfoVO.getTheirSigSecret();
        String dataSecret = secretInfoVO.getTheirDataSecret();
        String dataSecretIv = secretInfoVO.getTheirDataSecretIv();
        String urlAddress = secretInfoVO.getTheirUrlPrefix();

        String url = urlAddress + "notification_orderInfo";

        // 拼装成联联平台所需格式对象
        OrderInfo orderInfo = OrderInfo.builder()
                .operatorID(operatorId)
                .equipmentOwnerID(Constants.OPERATORID_LIANLIAN)
                .stationID("LC" + orderBasicInfo.getStationId())
                .equipmentID(orderBasicInfo.getPileSn())
                .connectorID(orderBasicInfo.getPileConnectorCode())
                .startChargeSeq(orderCode)
                .userChargeType(Constants.one)
                .money(new BigDecimal(String.valueOf(orderBasicInfo.getOrderAmount())).setScale(2, BigDecimal.ROUND_HALF_UP))
                .electMoney(new BigDecimal(String.valueOf(orderDetail.getTotalElectricityAmount())).setScale(2, BigDecimal.ROUND_HALF_UP))
                .serviceMoney(new BigDecimal(String.valueOf(orderDetail.getTotalServiceAmount())).setScale(2, BigDecimal.ROUND_HALF_UP))
                .elect(new BigDecimal(String.valueOf(orderDetail.getTotalUsedElectricity())).setScale(2, BigDecimal.ROUND_HALF_UP))
                .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderBasicInfo.getChargeStartTime()))
                .endTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderBasicInfo.getChargeEndTime()))
                .paymentAmount(orderBasicInfo.getPayAmount())
                // .payChannel()
                .stopReason(0)
                // .chargeDetails()
                .build();
        if (MerchantUtils.isXiXiaoMerchant(orderBasicInfo.getMerchantId())) {
            orderInfo.setEquipmentOwnerID(Constants.OPERATORID_XI_XIAO);
        }
        // 支付方式
        if (StringUtils.equals(orderBasicInfo.getPayMode(), OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) {
            // 微信支付
            orderInfo.setPayChannel(Integer.valueOf(PayChannelEnum.WEXIN_PAY.getCode()));
        } else if (StringUtils.equals(orderBasicInfo.getPayMode(), OrderPayModeEnum.PAYMENT_OF_ALIPAY.getValue())) {
            // 支付宝支付
            orderInfo.setPayChannel(Integer.valueOf(PayChannelEnum.ALI_PAY.getCode()));
        } else {
            // 其他
            orderInfo.setPayChannel(Integer.valueOf(PayChannelEnum.OTHER.getCode()));
        }
        // 订单详情
        ChargeDetail detail;

        List<BillingPriceVO> billingList = pileBillingTemplateService.queryBillingPrice(orderBasicInfo.getStationId());
        // 先将list按照 尖、峰、平、谷 时段排序
        // List<BillingPriceVO> collect = billingList.stream().sorted(Comparator.comparing(BillingPriceVO::getTimeType)).collect(Collectors.toList());
        // 再循环该list，拼装对应的充电价格、费率
        List<ChargeDetail> chargeDetails = new ArrayList<>();
        for (BillingPriceVO billingPriceVO : billingList) {
            detail = new ChargeDetail();
            if (StringUtils.equals(billingPriceVO.getTimeType(), "1")) {
                // 尖时段
                detail.setDetailStartTime(billingPriceVO.getStartTime());
                detail.setDetailEndTime(billingPriceVO.getEndTime());
                detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setDetailPower(orderDetail.getSharpUsedElectricity());
                detail.setDetailElecMoney(orderDetail.getSharpElectricityPrice());
                detail.setDetailSeviceMoney(orderDetail.getSharpServicePrice());
            } else if (StringUtils.equals(billingPriceVO.getTimeType(), "2")) {
                // 峰时段
                detail.setDetailStartTime(billingPriceVO.getStartTime());
                detail.setDetailEndTime(billingPriceVO.getEndTime());
                detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setDetailPower(orderDetail.getPeakUsedElectricity());
                detail.setDetailElecMoney(orderDetail.getPeakElectricityPrice());
                detail.setDetailSeviceMoney(orderDetail.getPeakServicePrice());
            } else if (StringUtils.equals(billingPriceVO.getTimeType(), "3")) {
                // 平时段
                detail.setDetailStartTime(billingPriceVO.getStartTime());
                detail.setDetailEndTime(billingPriceVO.getEndTime());
                detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setDetailPower(orderDetail.getFlatUsedElectricity());
                detail.setDetailElecMoney(orderDetail.getFlatElectricityPrice());
                detail.setDetailSeviceMoney(orderDetail.getFlatServicePrice());
            } else if (StringUtils.equals(billingPriceVO.getTimeType(), "4")) {
                // 谷时段
                detail.setDetailStartTime(billingPriceVO.getStartTime());
                detail.setDetailEndTime(billingPriceVO.getEndTime());
                detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
                detail.setDetailPower(orderDetail.getValleyUsedElectricity());
                detail.setDetailElecMoney(orderDetail.getValleyElectricityPrice());
                detail.setDetailSeviceMoney(orderDetail.getValleyServicePrice());
            }
            chargeDetails.add(detail);
        }
        orderInfo.setChargeDetails(chargeDetails);

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        // 调用联联平台接口
        JSONObject json = new JSONObject();
        json.put("OrderInfo", orderInfo);
        String jsonString = JSON.toJSONString(json);
        String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
        return result;
    }

    /**
     * 站点费率变化推送 notification_stationFee
     *
     * @param stationId
     * @throws UnsupportedOperationException 未实现异常
     */
    @Override
    public String notificationStationFee(String stationId) {
        PushStationFeeVO vo = new PushStationFeeVO();
        List<PushStationFeeVO.ChargeFeeDetail> chargeFeeDetailList = new ArrayList<>();
        PushStationFeeVO.ChargeFeeDetail chargeFeeDetail = null;
        // 根据站点 id 查询出正在使用的计费模板详情
        List<BillingPriceVO> billingPriceVOList = pileBillingTemplateService.queryBillingPrice(stationId);
        // 查询设备列表
        List<PileInfoVO> pileDetailVOS = pileBasicInfoService.queryPileDetailList(Lists.newArrayList(stationId));

        // 获取充电桩类型
        Set<String> equipmentTypeList = pileDetailVOS.stream()
                .map(PileInfoVO::getSpeedType)
                .collect(Collectors.toSet());
        vo.setOperatorId(Constants.OPERATORID_LIANLIAN);
        vo.setStationId("LC" + stationId);

        for (String equipmentType : equipmentTypeList) {
            for (BillingPriceVO billingPriceVO : billingPriceVOList) {
                chargeFeeDetail = new PushStationFeeVO.ChargeFeeDetail();
                chargeFeeDetail.setEquipmentType(Integer.parseInt(equipmentType));
                chargeFeeDetail.setStartTime(billingPriceVO.getStartTime());
                chargeFeeDetail.setEndTime(billingPriceVO.getEndTime());
                chargeFeeDetail.setElectricityFee(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(2, RoundingMode.DOWN));
                chargeFeeDetail.setServiceFee(new BigDecimal(billingPriceVO.getServicePrice()).setScale(2, RoundingMode.DOWN));
                chargeFeeDetailList.add(chargeFeeDetail);
            }
        }
        vo.setChargeFeeDetail(chargeFeeDetailList);

        // 通过站点id查询相关配置信息
        ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(stationId);
        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_stationFee";

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        JSONObject json = new JSONObject();
        json.put("StationFee", vo);
        String jsonString = JSON.toJSONString(json);
        // 发送请求
        String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
        return result;
    }

    @Override
    public String notificationStationFee(String stationId, ThirdPartySecretInfoVO secretInfoVO) {
        PushStationFeeVO vo = new PushStationFeeVO();
        List<PushStationFeeVO.ChargeFeeDetail> chargeFeeDetailList = new ArrayList<>();
        PushStationFeeVO.ChargeFeeDetail chargeFeeDetail = null;
        // 根据站点 id 查询出正在使用的计费模板详情
        List<BillingPriceVO> billingPriceVOList = pileBillingTemplateService.queryBillingPrice(stationId);
        // 查询设备列表
        List<PileInfoVO> pileDetailVOS = pileBasicInfoService.queryPileDetailList(Lists.newArrayList(stationId));

        // 获取充电桩类型
        Set<String> equipmentTypeList = pileDetailVOS.stream()
                .map(PileInfoVO::getSpeedType)
                .collect(Collectors.toSet());
        vo.setOperatorId(Constants.OPERATORID_LIANLIAN);
        vo.setStationId("LC" + stationId);

        for (String equipmentType : equipmentTypeList) {
            for (BillingPriceVO billingPriceVO : billingPriceVOList) {
                chargeFeeDetail = new PushStationFeeVO.ChargeFeeDetail();
                chargeFeeDetail.setEquipmentType(Integer.parseInt(equipmentType));
                chargeFeeDetail.setStartTime(billingPriceVO.getStartTime());
                chargeFeeDetail.setEndTime(billingPriceVO.getEndTime());
                chargeFeeDetail.setElectricityFee(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(2, RoundingMode.DOWN));
                chargeFeeDetail.setServiceFee(new BigDecimal(billingPriceVO.getServicePrice()).setScale(2, RoundingMode.DOWN));
                chargeFeeDetailList.add(chargeFeeDetail);
            }
        }
        vo.setChargeFeeDetail(chargeFeeDetailList);

        // 通过站点id查询相关配置信息
        // ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(stationId);
        // if (relationInfo == null) {
        //     return null;
        // }
        String operatorId = secretInfoVO.getTheirOperatorId();
        String operatorSecret = secretInfoVO.getTheirOperatorSecret();
        String signSecret = secretInfoVO.getTheirSigSecret();
        String dataSecret = secretInfoVO.getTheirDataSecret();
        String dataSecretIv = secretInfoVO.getTheirDataSecretIv();
        String urlAddress = secretInfoVO.getTheirUrlPrefix();

        String url = urlAddress + "notification_stationFee";

        // 获取令牌
        String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        JSONObject json = new JSONObject();
        json.put("StationFee", vo);
        String jsonString = JSON.toJSONString(json);
        // 发送请求
        String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
        return result;
    }

    /**
     *
     */
    @Override
    public Map<String, String> notificationOrderSettlementInfo(PushOrderSettlementDTO dto) {
        String orderCode = dto.getStartChargeSeq();
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("StartChargeSeq", orderCode);
        map.put("ConnectorID", dto.getConnectorID());
        int confirmResult = Constants.one;
        // 根据订单号查询订单信息
        OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
        OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode);
        if (orderInfo == null || orderDetail == null) {
            return null;
        }
        // 通过operatorID 查出 operatorSecret
        ThirdPartyPlatformConfig platformConfig = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (platformConfig == null) {
            return null;
        }
        // orderInfo 和 orderDetail 都不为空，再根据传过来的数据进行修改数据库信息
        confirmResult = Constants.zero;
        orderDetail.setTotalUsedElectricity(dto.getTotalPower()); // 累计充电量
        orderDetail.setTotalOrderAmount(dto.getTotalMoney()); // 累计总金额
        orderBasicInfoService.updateOrderDetail(orderDetail);
        map.put("ConfirmResult", confirmResult);

        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        String encrypt = Cryptos.encrypt(JSON.toJSONString(map), platformConfig.getDataSecret(), platformConfig.getDataSecretIv());
        resultMap.put("Data", encrypt);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, platformConfig.getSignSecret());
        resultMap.put("Sig", resultSign);
        return resultMap;
    }

    /**
     * 请求设备认证
     *
     * @param dto
     * @return
     */
    @Override
    public Map<String, String> queryEquipAuth(QueryEquipmentDTO dto) {
        Map<String, String> resultMap = Maps.newLinkedHashMap();
        EquipmentAuthVO vo = new EquipmentAuthVO();

        String equipAuthSeq = dto.getEquipAuthSeq(); // MA1X78KH5202311071202015732
        String pileConnectorCode = ThirdPartyPlatformUtils.extractConnectorID(dto.getConnectorID());
        // 先查询配置密钥相关信息
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorID());
        if (configInfo == null) {
            return null;
        }
        // 根据桩编号查询数据
        // String merchantId = StringUtils.substring(equipAuthSeq, 0, 9);
        String pileSn = StringUtils.substring(pileConnectorCode, 0, 14);
        // vo.setSuccStat(1); // 1-失败 0-成功  默认失败
        int succStat = 1;
        int failReason = 0;
        String failReasonMsg = "";
        PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(pileSn);
        if (pileBasicInfo != null) {
            // 查询当前枪口数据
            PileConnectorInfoVO connectorInfo = pileConnectorInfoService.getPileConnectorInfoByConnectorCode(pileConnectorCode);
            if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_NOT_CHARGED.getValue(), String.valueOf(connectorInfo.getStatus()))
                    || StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_CHARGING.getValue(), String.valueOf(connectorInfo.getStatus()))
                    || StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_RESERVED_LOCK.getValue(), String.valueOf(connectorInfo.getStatus()))
            ) {
                succStat = 0;
                failReason = 0;
            } else {
                succStat = 1;
                // 1- 此设备尚未插枪；
                failReason = 1;
            }
            vo.setEquipAuthSeq(equipAuthSeq);
            vo.setConnectorID(pileConnectorCode);
        } else {
            // 设备检测失败
            failReason = 2;
            failReasonMsg = "未查到该桩的数据";
        }
        vo.setSuccStat(succStat);
        vo.setFailReason(failReason); // 设备检测失败
        vo.setFailReasonMsg(failReasonMsg);
        // 加密数据
        byte[] encryptText = Cryptos.aesEncrypt(JSON.toJSONString(vo).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
     */
    public Map<String, String> queryStartCharge(QueryStartChargeDTO dto) {
        // 通过传过来的订单号和枪口号生成订单
        String pileConnectorCode = dto.getConnectorID();
        OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getStartChargeSeq());
        if (orderInfo != null) {
            // 平台已存在订单
            return null;
        }

        ThirdPartySecretInfoVO thirdPartySecretInfoVO = thirdpartySecretInfoService.queryByOperatorId(dto.getOperatorId());
        if (thirdPartySecretInfoVO == null) {
            return null;
        }

        // 生成订单
        dto.setAccountBalance(Constants.LIAN_LIAN_MAX_AMOUNT);
        Map<String, Object> map = orderBasicInfoService.generateOrderForThirdParty(dto);
        String orderCode = (String) map.get("orderCode");
        String transactionCode = (String) map.get("transactionCode");
        OrderBasicInfo orderBasicInfo = (OrderBasicInfo) map.get("orderBasicInfo");

        // 发送启机指令
        StartChargingCommand command = StartChargingCommand.builder()
                .pileSn(orderBasicInfo.getPileSn())
                .connectorCode(orderBasicInfo.getConnectorCode())
                .transactionCode(transactionCode)
                .chargeAmount(orderBasicInfo.getPayAmount())
                .logicCardNum(null)
                .physicsCardNum(null)
                .build();
        ykcPushCommandService.pushStartChargingCommand(command);

        // 拼装对应的数据并返回
        QueryStartChargeVO vo = QueryStartChargeVO.builder()
                .startChargeSeq(orderCode)
                .startChargeSeqStat(2) // 1、启动中 ；2、充电中；3、停止中；4、已结束；5、未知
                .connectorID(pileConnectorCode)
                .succStat(0)
                .failReason(0)
                .build();
        String type = ThirdPartyOperatorIdEnum.getTypeByOperatorId(dto.getOperatorId());
        if (StringUtils.equals(ThirdPlatformTypeEnum.XIN_DIAN_TU.getTypeCode(), type)) {
            // 如果是新电途平台，则将 startChargeSeqStat 改为 1-启动中
            vo.setStartChargeSeqStat(1);
        }
        // 异步推送启动充电结果  2024.01.25改为在0x33帧类型中统一回复
        // CompletableFuture.runAsync(() -> {
        //     try {
        //         Thread.sleep(200);
        //     } catch (InterruptedException e) {
        //         e.printStackTrace();
        //     }
        //     pushStartChargeResult(orderCode);
        // });

        // 加密
        // Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        // byte[] encryptText = Cryptos.aesEncrypt(JSON.toJSONString(vo).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);
        logger.info("联联平台请求启动充电 result :{}", JSON.toJSONString(vo));
        Map<String, String> resultMap = ThirdPartyPlatformUtils.generateResultMap(vo, thirdPartySecretInfoVO);
        return resultMap;

    }

    /**
     * 请求停止充电
     *
     * @param dto
     * @return
     */
    public Map<String, String> queryStopCharge(QueryStartChargeDTO dto) {
        QueryStopChargeVO vo = new QueryStopChargeVO();

        String orderCode = dto.getStartChargeSeq();

        // 根据订单号查询订单信息
        OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
        if (orderInfo == null) {
            return null;
        }
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        // 若状态为充电中，则发送停机指令
        if (StringUtils.equals(OrderStatusEnum.IN_THE_CHARGING.getValue(), orderInfo.getOrderStatus())) {
            // 充电中
            // StopChargingCommand command = StopChargingCommand.builder()
            //         .pileSn(orderInfo.getPileSn())
            //         .connectorCode(orderInfo.getConnectorCode())
            //         .build();
            // ykcPushCommandService.pushStopChargingCommand(command);
            pileRemoteService.remoteStopCharging(orderInfo.getPileSn(), orderInfo.getConnectorCode(), orderInfo.getTransactionCode());
            vo.setStartChargeSeq(orderCode);
            vo.setStartChargeSeqStat(4); // 1、启动中 ；2、充电中；3、停止中；4、已结束；5、未知
        }
        vo.setSuccStat(0);
        vo.setFailReason(0);

        String type = ThirdPartyOperatorIdEnum.getTypeByOperatorId(dto.getOperatorId());
        if (StringUtils.equals(ThirdPlatformTypeEnum.XIN_DIAN_TU.getTypeCode(), type)) {
            // 如果是新电途平台，则将 startChargeSeqStat 改为 3-停止中
            vo.setStartChargeSeqStat(3);
        }
        // 加密
        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        byte[] encryptText = Cryptos.aesEncrypt(JSON.toJSONString(vo).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
     */
    public Map<String, String> queryEquipChargeStatus(QueryEquipChargeStatusDTO dto) {
        String operatorID = dto.getOperatorID();
        String type = ThirdPartyOperatorIdEnum.getTypeByOperatorId(operatorID);
        String operatorName = ThirdPlatformTypeEnum.getTypeLabelByTypeCode(type);
        // 通过订单号查询订单信息
        OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getStartChargeSeq());
        // logger.info(operatorName + "查询订单信息 orderInfo:{}", orderInfo);
        if (orderInfo == null) {
            return null;
        }
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(operatorID);
        // logger.info(operatorName + "查询密钥信息 configInfo:{}", configInfo);
        if (configInfo == null) {
            return null;
        }
        OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderInfo.getOrderCode());
        // 通过订单号查询实时数据
        List<RealTimeMonitorData> realTimeData = orderBasicInfoService.getChargingRealTimeData(orderInfo.getTransactionCode());
        QueryChargingStatusVO vo;
        if (CollectionUtils.isEmpty(realTimeData)) {
            vo = new QueryChargingStatusVO();
        } else {
            RealTimeMonitorData data = realTimeData.get(0);
            String orderStatus = orderInfo.getOrderStatus();
            if (StringUtils.equals(orderStatus, OrderStatusEnum.IN_THE_CHARGING.getValue())) {
                // 充电中
                orderStatus = "2";
            }else if (StringUtils.equals(orderStatus, OrderStatusEnum.ORDER_COMPLETE.getValue())) {
                // 充电完成
                orderStatus = "4";
            } else {
                // 直接给 5-未知
                orderStatus = "5";
            }
            String status = data.getConnectorStatus();
            int connectorStatus = 0;
            if (StringUtils.isBlank(status)) {
                // 查询当前枪口状态
                PileConnectorInfoVO connectorInfoVO = pileConnectorInfoService.getPileConnectorInfoByConnectorCode(orderInfo.getPileConnectorCode());
                connectorStatus = connectorInfoVO.getStatus();
            }else {
                connectorStatus = Integer.parseInt(status);
            }
            BigDecimal totalElectricityAmount = orderDetail.getTotalElectricityAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalElectricityAmount();
            BigDecimal totalServiceAmount = orderDetail.getTotalServiceAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalServiceAmount();
            // 拼装联联平台数据
            vo = QueryChargingStatusVO.builder()
                    .startChargeSeq(dto.getStartChargeSeq()) // 订单号
                    .startChargeSeqStat(Integer.parseInt(orderStatus)) // 订单状态
                    .connectorID(orderInfo.getPileConnectorCode()) // 枪口编码
                    .connectorStatus(connectorStatus) // 枪口状态
                    .currentA(new BigDecimal(data.getOutputCurrent())) // 电流
                    .voltageA(new BigDecimal(data.getOutputVoltage())) // 电压
                    .soc(new BigDecimal(data.getSOC()))
                    .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderInfo.getChargeStartTime())) // 开始时间
                    .endTime(DateUtils.getDateTime()) // 本次采样时间
                    .totalPower(new BigDecimal(data.getChargingDegree()).setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计充电量
                    .elecMoney(totalElectricityAmount.setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计电费
                    .seviceMoney(totalServiceAmount.setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计服务费
                    .totalMoney(new BigDecimal(data.getChargingAmount())) // 已充金额

                    .build();
        }

        // 加密
        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        byte[] encryptText = Cryptos.aesEncrypt(JSON.toJSONString(vo).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;
    }

}
