package com.xhpc.order.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.xhpc.common.api.SmsService;
import com.xhpc.common.core.utils.SecurityUtils;
import com.xhpc.common.core.web.domain.AjaxResult;
import com.xhpc.common.data.redis.CacheOrderData;
import com.xhpc.common.data.redis.CacheRealtimeData;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.common.util.EvcsUtil;
import com.xhpc.order.domain.*;
import com.xhpc.order.mapper.XhpcRealTimeOrderMapper;
import com.xhpc.order.service.IXhpcChargeOrderService;
import com.xhpc.order.service.IXhpcHistoryOrderService;
import com.xhpc.order.service.IXhpcRealTimeOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author yuyang
 * @date 2021/8/7 15:07
 */
@Service
public class XhpcRealTimeOrderServiceImpl implements IXhpcRealTimeOrderService {

    @Autowired
    private XhpcRealTimeOrderMapper xhpcRealTimeOrderMapper;

    @Autowired
    private IXhpcChargeOrderService xhpcChargeOrderService;

    @Autowired
    private IXhpcHistoryOrderService xhpcHistoryOrderService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private SmsService smsService;


    private final ExecutorService executorService = Executors.newFixedThreadPool(20);


    private static final Logger logger = LoggerFactory.getLogger(XhpcRealTimeOrderServiceImpl.class);

    @Override
    public List<Map<String, Object>> list(String phone, String transactionNumber, Integer source, String chargingStationName, String terminalName, Long operatorId, String startTime, String endTime,Integer status,Long userId,Integer type,String affiliationOrganization,String plateNum,Integer internetId,String internetSerialNumber) {


        //获取登陆用户
        Long logUserId = SecurityUtils.getUserId();
        //桩的统计、该时段金额
        List<Map<String, Object>> list =new ArrayList<>();

        //number 3 用户类型和电话都有 1 电话 2 用户类型
        //type   1 平台 2 运营商 3流量方
        Integer  number=0;
        if(!"".equals(phone) && phone!=null && !"".equals(source) && source !=null){
            number =3;
        }else if (!"".equals(phone) && phone!=null){
            number =1;
        }else{
            number =2;
        }
        if(type ==null || userId ==null){
            return new ArrayList<>();
        }
        if(logUserId !=1) {
            Map<String, Object> landUser = xhpcHistoryOrderService.getLandUser(logUserId);
            if(landUser !=null){
                if(landUser.get("userType") !=null){
                    if("01".equals(landUser.get("userType").toString()) || "03".equals(landUser.get("userType").toString())){
                        Long logOperatorId = Long.valueOf(landUser.get("operatorId").toString());
                        //运营商看自己的场站
                        list = xhpcRealTimeOrderMapper.list(phone,transactionNumber,source,chargingStationName,terminalName,operatorId,startTime,endTime,number,status,logOperatorId,1,affiliationOrganization,plateNum,internetId,internetSerialNumber);
                    }else{
                        //查询赋值的场站
                        list = xhpcRealTimeOrderMapper.list(phone,transactionNumber,source,chargingStationName,terminalName,operatorId,startTime,endTime,number,status,logUserId,2,affiliationOrganization,plateNum,internetId,internetSerialNumber);
                    }
                }
            }
        }else{
            list = xhpcRealTimeOrderMapper.list(phone,transactionNumber,source,chargingStationName,terminalName,operatorId,startTime,endTime,number,status,logUserId,0,affiliationOrganization,plateNum,internetId,internetSerialNumber);
        }

        return list;
    }

    @Override
    public Map<String, Object> getMessage(Long realTimeOrderId) {
        return xhpcRealTimeOrderMapper.getMessage(realTimeOrderId);
    }

    @Override
    public List<Map<String, Object>> timeList(Long chargingOrderId) {
        return xhpcRealTimeOrderMapper.timeList(chargingOrderId);
    }

    @Override
    public AjaxResult timeChartList(Long chargingOrderId) {
        Map<String,Object> map =new HashMap();
        map.put("soc",xhpcRealTimeOrderMapper.timeChartSOCList(chargingOrderId));
        map.put("voltage",xhpcRealTimeOrderMapper.timeChartVoltageList(chargingOrderId));
        map.put("current",xhpcRealTimeOrderMapper.timeChartCurrentList(chargingOrderId));
        return AjaxResult.success(map);
    }

    @Override
    public int addXhpcRealTimeOrder(XhpcRealTimeOrder xhpcRealTimeOrder) {
        return xhpcRealTimeOrderMapper.addXhpcRealTimeOrder(xhpcRealTimeOrder);
    }

    @Override
    public int addSOC(XhpcChargeOrderSoc xhpcChargeOrderSoc) {
        return xhpcRealTimeOrderMapper.addSOC(xhpcChargeOrderSoc);
    }

    @Override
    public int addCurrent(XhpcChargeOrderCurrent xhpcChargeOrderCurrent) {
        return xhpcRealTimeOrderMapper.addCurrent(xhpcChargeOrderCurrent);
    }

    @Override
    public int addVoltage(XhpcChargeOrderVoltage xhpcChargeOrderVoltage) {
        return xhpcRealTimeOrderMapper.addVoltage(xhpcChargeOrderVoltage);
    }

    @Transactional
    @Override
    public AjaxResult getExamineMessage(Long realTimeOrderId) {

        //基本信息
        Map<String, Object> message = xhpcRealTimeOrderMapper.getMessage(realTimeOrderId);
        if(message ==null || message.get("chargeOrderId") ==null){
            return AjaxResult.success(new HashMap<>());
        }

        //获取开始充电时间、结束时间、计费模型、充电度数、已充金额
        XhpcChargeOrder chargeOrder = xhpcChargeOrderService.getChargingOrderId(Long.parseLong(message.get("chargeOrderId").toString()));

        //获取该订单最后一条实时数据
        Map<String, Object> cacheMap = redisService.getCacheMap("order:" + chargeOrder.getSerialNumber());
        List<CacheRealtimeData> list = (List<CacheRealtimeData>) cacheMap.get("realtimeDataList");
        CacheRealtimeData startData =new CacheRealtimeData();
        CacheRealtimeData endData =new CacheRealtimeData();

        if (list != null && list.size() > 0) {
            endData =list.get(list.size()-1);
            for (int i = 0; i <list.size() ; i++) {
                startData =list.get(i);
                if(startData.getSoc()>0){
                    break;
                }
            }
        }

        Long rateModelId = chargeOrder.getRateModelId();

        if(endData !=null && endData.getAmountCharged() !=null){

            message.put("soc",endData.getSoc());
            //最后一祯时间
            Date endTime = DateUtil.parse(endData.getCreateTime());
            Date startTime =DateUtil.parse(startData.getCreateTime());
            //充电时长
            Long tiem = (endTime.getTime() - startTime.getTime()) / 1000;
            if (tiem > 3600) {
                long hours = tiem / 3600;
                double mins = (double) ((tiem - (hours * 3600)) / 60);
                message.put("chargingTime",hours + "时" + new BigDecimal(mins).setScale(0) + "分");
                chargeOrder.setChargingTime(hours + "时" + new BigDecimal(mins).setScale(0) + "分");
            } else {
                double mins = (double) (tiem / 60);
                message.put("chargingTime",new BigDecimal(mins).setScale(0) + "分");
                chargeOrder.setChargingTime(new BigDecimal(mins).setScale(0) + "分");
            }
            BigDecimal chargingDegree = new BigDecimal(endData.getChargingDegree()).divide(new BigDecimal(10000), 2, BigDecimal.ROUND_DOWN);
            message.put("chargingDegree",chargingDegree);

            chargeOrder.setStartTime(startTime);
            chargeOrder.setEndTime(endTime);
            chargeOrder.setStartSoc(startData.getSoc().toString());
            chargeOrder.setEndSoc(endData.getSoc().toString());
            chargeOrder.setChargingTimeNumber(tiem);
            chargeOrder.setChargingDegree(chargingDegree);
            chargeOrder.setType(0);
            chargeOrder.setAmountCharged(new BigDecimal(endData.getAmountCharged()).divide(new BigDecimal(10000),2,BigDecimal.ROUND_DOWN));
        }else{
            //当没有缓存数据时，查询数据库
            XhpcRealTimeOrder startRealTimeOrder = xhpcRealTimeOrderMapper.getChargingOrderId(chargeOrder.getChargeOrderId(), 1);

            XhpcRealTimeOrder endRealTimeOrder = xhpcRealTimeOrderMapper.getChargingOrderId(chargeOrder.getChargeOrderId(), 2);

            message.put("soc",endRealTimeOrder.getSoc());
            //最后一祯时间
            Date endTime = endRealTimeOrder.getCreateTime();
            Date startTime = startRealTimeOrder.getCreateTime();

            BigDecimal chargingDegree = endRealTimeOrder.getChargingDegree();
            message.put("chargingDegree",chargingDegree);
            chargeOrder.setChargingTime(endRealTimeOrder.getChargingTime());
            message.put("chargingTime",endRealTimeOrder.getChargingTime());

            chargeOrder.setStartTime(startTime);
            chargeOrder.setEndTime(endTime);
            chargeOrder.setStartSoc(startRealTimeOrder.getSoc());
            chargeOrder.setEndSoc(endRealTimeOrder.getSoc());
            Integer chargingTimeNumber = endRealTimeOrder.getChargingTimeNumber();
            if(chargingTimeNumber>0){
                chargeOrder.setChargingTimeNumber(Long.valueOf(chargingTimeNumber*60));
            }else{
                chargeOrder.setChargingTimeNumber(0L);
            }
            chargeOrder.setChargingDegree(chargingDegree);
            chargeOrder.setType(0);
            chargeOrder.setAmountCharged(endRealTimeOrder.getAmountCharged());
        }

        Date startTime2 = chargeOrder.getStartTime();
        Date updateTime2 = chargeOrder.getEndTime();
        BigDecimal amountCharged = chargeOrder.getAmountCharged();
        //充电度数
        BigDecimal chargingDegree = chargeOrder.getChargingDegree();
        BigDecimal powerPriceTotal =new BigDecimal(0);
        //1时间没有跨天
        DateTime parse = DateUtil.parse(DateUtil.format(startTime2, "yyyy-MM-dd"), "yyyy-MM-dd");
        DateTime parse1 = DateUtil.parse(DateUtil.format(updateTime2, "yyyy-MM-dd"), "yyyy-MM-dd");
        //每分钟多少度电
        BigDecimal decimal = new BigDecimal((updateTime2.getTime() - startTime2.getTime())).divide(new BigDecimal(60000),2,BigDecimal.ROUND_DOWN);
        BigDecimal divide = chargingDegree.divide(decimal,2,BigDecimal.ROUND_DOWN);
        long betweenDay = DateUtil.between(parse,parse1, DateUnit.DAY);
        if(betweenDay==0){
            powerPriceTotal = getBigDecimal(rateModelId,DateUtil.formatTime(startTime2), DateUtil.formatTime(updateTime2), powerPriceTotal, divide);
        }else{
            //跨天
            powerPriceTotal = getBigDecimal(rateModelId, DateUtil.formatTime(startTime2), "23:59:59", powerPriceTotal, divide);
            System.out.println(">>>>>>跨天前>>>>>>>"+powerPriceTotal);
            //明天
            DateTime tomorrow = DateUtil.offsetDay(startTime2,1);
            Date startTime3 = DateUtil.beginOfDay(tomorrow);
            powerPriceTotal = getBigDecimal(rateModelId,  DateUtil.formatTime(startTime3), DateUtil.formatTime(updateTime2), powerPriceTotal, divide);
            System.out.println(">>>>>>跨天后>>>>>>>"+powerPriceTotal);
        }

        //算服务费和电费
        if(amountCharged.compareTo(powerPriceTotal)>-1){
            BigDecimal servicePriceTotal =amountCharged.subtract(powerPriceTotal);
            message.put("powerPriceTotal",powerPriceTotal);
            message.put("servicePriceTotal",servicePriceTotal);
        }else{
            message.put("powerPriceTotal",amountCharged);
            message.put("servicePriceTotal",0);
        }

        //修改充电订单
        xhpcChargeOrderService.updateXhpcChargeOrder(chargeOrder);
        return AjaxResult.success(message);
    }



    @Override
    public AjaxResult getExamine(Long chargingOrderId, BigDecimal powerPrice, BigDecimal servicePrice) {

        //电费不能为0
        if(new BigDecimal(0).compareTo(powerPrice)==1){
            return AjaxResult.error("电费为0");
        }
        //总金额
        BigDecimal money = powerPrice.add(servicePrice);
        //总服务费 servicePrice
        //总电费 powerPrice
        //剩余的电费
        BigDecimal surplusPowerPrice = powerPrice;
        //剩余的服务费
        BigDecimal surplusServicePrice = servicePrice;

        XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getChargingOrderId(chargingOrderId);
        if(xhpcChargeOrder.getStatus()==1 || xhpcChargeOrder.getStatus()==3){
            return AjaxResult.error("订单已结算，请联系技术人员解决");
        }
        xhpcChargeOrder.setStatus(3);
        xhpcChargeOrder.setAmountCharged(money);
        Long userId = xhpcChargeOrder.getUserId();
        Map<String, Object> userMessage = xhpcChargeOrderService.getUserMessage(userId);
        if (userMessage == null || userMessage.get("balance") == null) {
            //订单异常
            xhpcChargeOrder.setStatus(2);
            //异常原因
            xhpcChargeOrder.setErroRemark("用户id:" + userId + "为空");
            xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
            return AjaxResult.error("用户id:" + userId + "为空");
        }
        //生成一条历史订单
        XhpcHistoryOrder xhpcHistoryOrder = new XhpcHistoryOrder();

        xhpcHistoryOrder.setEndTime(xhpcChargeOrder.getEndTime());
        xhpcHistoryOrder.setStartSoc(xhpcChargeOrder.getStartSoc());
        xhpcHistoryOrder.setEndSoc(xhpcChargeOrder.getEndSoc());
        xhpcHistoryOrder.setTotalPower(xhpcChargeOrder.getChargingDegree().doubleValue());
        xhpcHistoryOrder.setType(2);
        addSettlement(powerPrice, servicePrice, money, surplusPowerPrice, surplusServicePrice, xhpcChargeOrder, userId, userMessage,0,null,xhpcHistoryOrder);

        return AjaxResult.success();
    }

    /**
     * 结算订单
     * @param powerPrice
     * @param servicePrice
     * @param money
     * @param surplusPowerPrice
     * @param surplusServicePrice
     * @param xhpcChargeOrder
     * @param userId
     * @param userMessage
     * @param type              0 不发短信  1发短信
     */
    @Override
    public void addSettlement(BigDecimal powerPrice, BigDecimal servicePrice, BigDecimal money, BigDecimal surplusPowerPrice, BigDecimal surplusServicePrice, XhpcChargeOrder xhpcChargeOrder, Long userId, Map<String, Object> userMessage,Integer type,String vinNormal,XhpcHistoryOrder xhpcHistoryOrder) {
        xhpcHistoryOrder.setPowerPriceTotal(powerPrice);
        xhpcHistoryOrder.setServicePriceTotal(servicePrice);
        xhpcHistoryOrder.setVinNormal(vinNormal);

        //电站活动抵扣--抵扣的总金额
        BigDecimal promotionDiscount = new BigDecimal(0);
        //实际价格-用户支付的钱
        BigDecimal actPrice =money;
        //流量方总金额抽成
        BigDecimal internetCommission =new BigDecimal(0);
        //流量方服务费抽成
        BigDecimal internetSvcCommission =new BigDecimal(0);
        //平台总金额抽成
        BigDecimal platformCommission =new BigDecimal(0);
        //平台服务费抽成
        BigDecimal platformSvcCommission =new BigDecimal(0);
        //运维总抽成
        BigDecimal operationCommission =new BigDecimal(0);
        //运维服务费抽成
        BigDecimal operationSvcCommission =new BigDecimal(0);
        //判断是C端用户还是流量端用户
        //先计算第三方优惠力度
        Integer source = xhpcChargeOrder.getSource();
        String internetSerialNumber = xhpcChargeOrder.getInternetSerialNumber();
        if(source==1 &&  internetSerialNumber!=null){
            String substring = internetSerialNumber.substring(0, 9);
            xhpcHistoryOrder.setInternetSerialNumber(xhpcChargeOrder.getInternetSerialNumber());
            Map<String, Object> operatorIdEvcs = xhpcRealTimeOrderMapper.getOperatorIdEvcs(substring);
            if(operatorIdEvcs !=null){
                //未完成
                if(operatorIdEvcs.get("operatorIdEvcs")!=null && operatorIdEvcs.get("commissionType")!=null && operatorIdEvcs.get("commissionRate")!=null){
                    BigDecimal commissionRate = new BigDecimal(operatorIdEvcs.get("commissionRate").toString()).divide(new BigDecimal(100));
                    String commissionType = operatorIdEvcs.get("commissionType").toString();
                    if(operatorIdEvcs.get("internetUserId") !=null){
                        xhpcHistoryOrder.setChargingMode(operatorIdEvcs.get("internetUserId").toString());
                    }
                    //0总金额提成 1服务费提成
                    if(new BigDecimal(0).compareTo(commissionRate)==-1){
                        if("0".equals(commissionType) || "1".equals(commissionType)){
                            //流量方的钱
                            if("0".equals(commissionType)){
                                BigDecimal decimal1 = surplusPowerPrice.multiply(commissionRate).setScale(2, BigDecimal.ROUND_DOWN);
                                BigDecimal decimal2 = surplusServicePrice.multiply(commissionRate).setScale(2, BigDecimal.ROUND_DOWN);
                                internetCommission = decimal1.add(decimal2);
                                surplusPowerPrice =surplusPowerPrice.subtract(decimal1);
                                surplusServicePrice =surplusServicePrice.subtract(decimal2);
                            }else{
                                BigDecimal decimal2 = surplusServicePrice.multiply(commissionRate).setScale(2, BigDecimal.ROUND_DOWN);
                                internetCommission = decimal2;
                                surplusServicePrice = surplusServicePrice.subtract(decimal2);
                            }
                        }
                    }
                }
            }
        }
        if ( source== 0) {
            //用户第几次充电
            int count = xhpcChargeOrderService.getCount(userId,xhpcChargeOrder.getChargeOrderId());
            if (count == 0) {
                //活动折扣
                Map<String, Object> promotion = xhpcChargeOrderService.getPromotion();
                if (promotion != null && promotion.get("state") != null && promotion.get("discount") != null) {
                    //state 1.总金额 2.电费 3.服务费   discount 折扣率
                    String state = promotion.get("state").toString();
                    BigDecimal discount =new BigDecimal(promotion.get("discount").toString()).divide(new BigDecimal(100));

                    if(discount.compareTo(new BigDecimal(0))==1){
                        if("1".equals(state) || "2".equals(state) || "3".equals(state)){
                            //折扣的钱
                            promotionDiscount=money.multiply(discount).setScale(2,BigDecimal.ROUND_DOWN);
                            //剩余的总金额
                            actPrice = money.subtract(promotionDiscount);

                            BigDecimal decimal1 = surplusPowerPrice.multiply(discount).setScale(2, BigDecimal.ROUND_DOWN);
                            BigDecimal decimal2 = surplusServicePrice.multiply(discount).setScale(2, BigDecimal.ROUND_DOWN);
                            if("1".equals(state)){
                                //总金额
                                actPrice =actPrice.subtract(decimal1.add(decimal2));
                                //折扣的钱
                                promotionDiscount = decimal1.add(decimal2);
                                surplusPowerPrice = surplusPowerPrice.subtract(decimal1);
                                surplusServicePrice= surplusServicePrice.subtract(decimal2);
                            }else if("2".equals(state)){
                                //电费
                                surplusPowerPrice=surplusPowerPrice.subtract(decimal1);
                            }else{
                                //服务费
                                surplusServicePrice =surplusServicePrice.subtract(decimal2);
                            }
                        }
                    }
                }
            }
        }
        //获取运营商
        Map<String, Object> operatorMessage = xhpcChargeOrderService.getOperatorMessage(xhpcChargeOrder.getChargingStationId());
        if(operatorMessage !=null){
            if(operatorMessage.get("operatorIdEvcs")!=null){

                if(operatorMessage.get("operatorIdEvcs") !=null && !"".equals(operatorMessage.get("operatorIdEvcs").toString())){
                    String stw = operatorMessage.get("operatorIdEvcs").toString();
                    if(stw.length()>9){
                        xhpcHistoryOrder.setOperatorIdEvcs(stw.substring(8, stw.length() - 1));
                    }
                }
            }
            if(operatorMessage.get("maintenanceCommissionRate") !=null && operatorMessage.get("commissionType") !=null && operatorMessage.get("platformCommissionRate") !=null){
                Integer commissionType = (Integer) operatorMessage.get("commissionType");
                //运维提成
                BigDecimal maintenanceCommissionRate = new BigDecimal(operatorMessage.get("maintenanceCommissionRate").toString()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN);
                //平台提成
                BigDecimal platformCommissionRate = new BigDecimal(operatorMessage.get("platformCommissionRate").toString()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN);
                //提成类型（0总金额提成 1服务费提成）
                if(commissionType==0){
                    //平台总抽成
                    BigDecimal multiply1 = surplusPowerPrice.multiply(platformCommissionRate).setScale(2,BigDecimal.ROUND_DOWN);
                    BigDecimal multiply2 = surplusServicePrice.multiply(platformCommissionRate).setScale(2,BigDecimal.ROUND_DOWN);
                    //运维总抽成
                    BigDecimal multiply3 = surplusPowerPrice.multiply(maintenanceCommissionRate).setScale(2,BigDecimal.ROUND_DOWN);
                    BigDecimal multiply4 = surplusServicePrice.multiply(maintenanceCommissionRate).setScale(2,BigDecimal.ROUND_DOWN);

                    //平台总金额抽成
                    platformCommission = multiply1.add(multiply2);
                    //剩下的钱电费和服务
                    surplusPowerPrice = surplusPowerPrice.subtract(multiply1);
                    surplusServicePrice = surplusServicePrice.subtract(multiply2);

                    //运维总金额抽成
                    operationCommission = multiply3.add(multiply4);
                    //剩下的钱电费和服务
                    surplusPowerPrice = surplusPowerPrice.subtract(multiply3);
                    surplusServicePrice = surplusServicePrice.subtract(multiply4);

                }else if(commissionType==1){
                    BigDecimal multiply1 = surplusServicePrice.multiply(platformCommissionRate).setScale(2,BigDecimal.ROUND_DOWN);
                    BigDecimal multiply2 = surplusServicePrice.multiply(maintenanceCommissionRate).setScale(2,BigDecimal.ROUND_DOWN);
                    //平台服务费抽成金额
                    platformSvcCommission=multiply1;
                    //剩下的服务费钱
                    surplusServicePrice = surplusServicePrice.subtract(multiply1);

                    //运维服务费抽成金额
                    operationCommission = multiply2;
                    //剩下的钱
                    surplusServicePrice = surplusServicePrice.subtract(multiply2);
                }
                if("微信".equals(xhpcChargeOrder.getChargingMode())){
                    xhpcHistoryOrder.setChargingMode("微信");
                }
                if("支付宝".equals(xhpcChargeOrder.getChargingMode())){
                    xhpcHistoryOrder.setChargingMode("支付宝");
                }
            }else{
                //订单异常
                xhpcChargeOrder.setStatus(2);
                //异常原因
                xhpcChargeOrder.setErroRemark("运营商数据为空");
            }
        }
        Long chargeOrderId = xhpcChargeOrder.getChargeOrderId();
        xhpcHistoryOrder.setChargeOrderId(chargeOrderId);
        xhpcHistoryOrder.setChargingStationId(xhpcChargeOrder.getChargingStationId());
        xhpcHistoryOrder.setUserId(userId);
        xhpcHistoryOrder.setTerminalId(xhpcChargeOrder.getTerminalId());
        xhpcHistoryOrder.setStartTime(xhpcChargeOrder.getStartTime());
        xhpcHistoryOrder.setStopReasonEvcs(xhpcChargeOrder.getStopReasonEvcs());//todo 从头开始设置所有evcs字段
        xhpcHistoryOrder.setChargeModelEvcs(xhpcChargeOrder.getChargeModelEvcs());
        xhpcHistoryOrder.setSerialNumber(xhpcChargeOrder.getSerialNumber());
        xhpcHistoryOrder.setRateModelId(xhpcChargeOrder.getRateModelId());
        xhpcHistoryOrder.setStartSoc(xhpcChargeOrder.getStartSoc());
        xhpcHistoryOrder.setReconciliationStatus(0);
        xhpcHistoryOrder.setSortingStatus(0);
        //订单总价---运维服务费抽成
        xhpcHistoryOrder.setTotalPrice(money.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setPromotionDiscount(promotionDiscount.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setActPrice(actPrice.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setActPowerPrice(surplusPowerPrice.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setActServicePrice(surplusServicePrice.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setInternetCommission(internetCommission.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setInternetSvcCommission(internetSvcCommission.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setPlatformCommission(platformCommission.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setPlatformSvcCommisssion(platformSvcCommission.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setOperationCommission(operationCommission.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setOperationSvcCommission(operationSvcCommission.setScale(2, BigDecimal.ROUND_DOWN));
        xhpcHistoryOrder.setStartSoc(xhpcChargeOrder.getStartSoc());
        xhpcHistoryOrder.setEndSoc(xhpcChargeOrder.getEndSoc());
        xhpcHistoryOrder.setReconciliationStatus(0);
        Date date = new Date();
        xhpcHistoryOrder.setCreateTime(date);
        xhpcHistoryOrder.setChargeModelEvcs(3);
        if(xhpcChargeOrder.getPower()!=null){
            xhpcHistoryOrder.setConnectorPowerEvcs(Double.parseDouble(xhpcChargeOrder.getPower()));
        }
        if(source==0){

            xhpcHistoryOrder.setUserNameEvcs(userMessage.get("phone").toString());
            xhpcHistoryOrder.setPhone(userMessage.get("phone").toString());
            //增加流水订单号
            if(operatorMessage!=null && operatorMessage.get("operatorId")!=null){
                String evcs = EvcsUtil.transferInternetOrderNo(xhpcChargeOrder.getSerialNumber(), operatorMessage.get("operatorId").toString());
                logger.info("》》》》evcs》》》:"+evcs);
                logger.info("》》》》evcs》》》:"+evcs);
                logger.info("》》》》evcs》》》:"+evcs);
                xhpcHistoryOrder.setEvcsOrderNo(evcs);
            }

            //扣除用户实际消费金额，添加消费记录
            Map<String, Object> user = xhpcChargeOrderService.getUserMessage(userId);
            //剩余的钱
            BigDecimal balance1 =(BigDecimal) user.get("balance");
            BigDecimal subtract = balance1.subtract(actPrice);
            int i = xhpcChargeOrderService.updateUserBalance(userId, subtract);
            if(i==0){
                //扣钱失败
                xhpcChargeOrder.setStatus(2);
                xhpcChargeOrder.setErroRemark("扣钱失败");
            }
            //添加流水
            xhpcChargeOrderService.addUserAccountStatement(userId, actPrice.negate(), subtract, xhpcChargeOrder.getChargeOrderId(), 3, date);
            try{
                Map<String, Object> xhpcChargingPile = xhpcChargeOrderService.getXhpcChargingPile(xhpcChargeOrder.getTerminalId());
                if(xhpcChargingPile !=null){
                    //发送短信
                    if(user.get("phone") !=null){
                        if("1".equals(xhpcChargingPile.get("type").toString())){
                            HashMap<String, String> paramMap = new HashMap<>();
                            paramMap.put("elec", xhpcChargeOrder.getEndSoc());
                            paramMap.put("sumMoney", actPrice.toString());
                            paramMap.put("phone", user.get("phone").toString());
                            paramMap.put("content", "【小华停止充电】尊敬的用户，你的爱车已停止充电，电量为：" + xhpcChargeOrder.getEndSoc() + "%，总费用为：" + actPrice + "元，充电费用明细，请查询小华充电小程序，谢谢。");
                            smsService.sendNotice(paramMap);
                        }else {
                            HashMap<String, String> paramMap = new HashMap<>();
                            paramMap.put("sumMoney", actPrice.toString());
                            paramMap.put("phone", user.get("phone").toString());
                            paramMap.put("content", "【小华停止充电】尊敬的用户，你的爱车已停止充电，总费用为：" + actPrice + "元，充电费用明细，请查询小华充电小程序，谢谢。");
                            smsService.sendNotice(paramMap);
                        }
                    }
                }
            }catch (Exception e){
                logger.info("<<<<<<<<<<<<<<<<发送短信失败>>>>>>>>>>>>>>>>>");
            }

        }

        xhpcHistoryOrderService.insert(xhpcHistoryOrder);

        xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
        // 另起线程处理业务上传redis数据
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                addPileEndOrder(xhpcHistoryOrder, xhpcChargeOrder, xhpcChargeOrder.getSerialNumber(),1);
            }
        });
       // redisService.deleteObject("pushOrder:"+xhpcChargeOrder.getSerialNumber());
    }

    @Override
    public void deleteRealTimeOrder(Long chargingOrderId) {
        xhpcRealTimeOrderMapper.deleteRealTimeOrder(chargingOrderId);
        xhpcRealTimeOrderMapper.deleteChargeOrderCurrent(chargingOrderId);
        xhpcRealTimeOrderMapper.deleteChargeOrderSoc(chargingOrderId);
        xhpcRealTimeOrderMapper.deleteChargeVoltage(chargingOrderId);
    }

    @Override
    public void addPileEndOrder(XhpcHistoryOrder xhpcHistoryOrder, XhpcChargeOrder xhpcChargeOrder, String orderNo,Integer type) {
        Map<String, Object> cacheMap = redisService.getCacheMap("order:" + orderNo);
        Date date = new Date();
        Long chargeOrderId = xhpcChargeOrder.getChargeOrderId();
        //删除实时数据，获取最新的实时数据
        deleteRealTimeOrder(xhpcChargeOrder.getChargeOrderId());
        //添加新的实时数据
        List<CacheRealtimeData> list = (List<CacheRealtimeData>) cacheMap.get("realtimeDataList");
        if (list != null && list.size() > 0) {
            for (CacheRealtimeData cacheRealtimeData : list) {
                addOrderTime(cacheRealtimeData, xhpcChargeOrder, orderNo, type);
            }
        }
        //添加redis到数据库
        XhpcOrderRedisRecord xhpcOrderRedisRecord =new XhpcOrderRedisRecord();
        xhpcOrderRedisRecord.setChargeOrderId(chargeOrderId);
        xhpcOrderRedisRecord.setSerialNumber(xhpcHistoryOrder.getSerialNumber());
        xhpcOrderRedisRecord.setHistoryOrderOd(xhpcHistoryOrder.getHistoryOrderId());
        if(cacheMap.get("endSoc") !=null){
            xhpcOrderRedisRecord.setEndSoc(cacheMap.get("endSoc").toString());
        }
        if(cacheMap.get("status") !=null){
            xhpcOrderRedisRecord.setStatus(cacheMap.get("status").toString());
        }
        if(cacheMap.get("balance") !=null){
            xhpcOrderRedisRecord.setBalance(cacheMap.get("balance").toString());
        }
        if(cacheMap.get("tel") !=null){
            xhpcOrderRedisRecord.setTel(cacheMap.get("tel").toString());
        }
        if(cacheMap.get("startSoc") !=null){
            xhpcOrderRedisRecord.setStartSoc(cacheMap.get("startSoc").toString());
        }
        if(cacheMap.get("startResult") !=null){
            xhpcOrderRedisRecord.setStartResult(cacheMap.get("startResult").toString());
        }
        if(cacheMap.get("realtimeDataList") !=null){
            xhpcOrderRedisRecord.setRealtimeDataList(cacheMap.get("realtimeDataList").toString());
        }
        if(cacheMap.get("remainingTime") !=null){
            xhpcOrderRedisRecord.setRemainingTime(cacheMap.get("remainingTime").toString());
        }
        if(cacheMap.get("rateModelId") !=null){
            xhpcOrderRedisRecord.setRateModelId(cacheMap.get("rateModelId").toString());
        }
        if(cacheMap.get("lt5alerted") !=null){
            xhpcOrderRedisRecord.setLt5alerted(cacheMap.get("lt5alerted").toString());
        }
        if(cacheMap.get("orderData") !=null){
            CacheOrderData cacheOrderData = (CacheOrderData)cacheMap.get("orderData");
            xhpcOrderRedisRecord.setOrderData(cacheOrderData.toString());
        }
        xhpcOrderRedisRecord.setCreateTime(date);
        xhpcChargeOrderService.addXhpcOrderRedisRecord(xhpcOrderRedisRecord);
        //删除redis
        //redisService.deleteObject("order:"+orderNo);
        //redisService.deleteObject("order:"+orderNo+".lord");
        logger.info("<<<<<<<<<<<<<<<<订单结束回调成功>>>>>>>>>>>>>>>>>");
        logger.info("<<<<<<<<<<<<<<<<订单结束回调成功>>>>>>>>>>>>>>>>>");
        logger.info("<<<<<<<<<<<<<<<<订单结束回调成功>>>>>>>>>>>>>>>>>");
    }



    /**
     * 添加实时数据
     *
     * @param cacheRealtimeData
     * @param xhpcChargeOrder
     * @param orderNo           订单号
     * @param type              1.实时数据回调  2.结算回调
     * @return
     */
    @Override
    public Map<String, Object> addOrderTime(CacheRealtimeData cacheRealtimeData, XhpcChargeOrder xhpcChargeOrder,
                                             String orderNo, Integer type) {

        Map<String, Object> map = new HashMap<>();
        Date date = new Date();
        Long chargeOrderId = xhpcChargeOrder.getChargeOrderId();
        XhpcRealTimeOrder xhpcRealTimeOrder = new XhpcRealTimeOrder();

        xhpcRealTimeOrder.setChargingOrderId(xhpcChargeOrder.getChargeOrderId());
        xhpcRealTimeOrder.setTransactionNumber(orderNo);
        xhpcRealTimeOrder.setPileNumber(cacheRealtimeData.getPileNo());
        String gunId = cacheRealtimeData.getGunId();
        xhpcRealTimeOrder.setGunNumber(gunId);
        if("00".equals(cacheRealtimeData.getPileGunStatus())){
            xhpcRealTimeOrder.setPileGunStatus(0);
        }else if("01".equals(cacheRealtimeData.getPileGunStatus())){
            xhpcRealTimeOrder.setPileGunStatus(1);
        }else{
            xhpcRealTimeOrder.setPileGunStatus(2);
        }
        if("00".equals(cacheRealtimeData.getVehicleGunStatus())){
            xhpcRealTimeOrder.setVehicleGunStatus(0);
        }else{
            xhpcRealTimeOrder.setVehicleGunStatus(1);
        }
        BigDecimal v = new BigDecimal(cacheRealtimeData.getWorkingVoltage()).divide(new BigDecimal(10));
        BigDecimal c = new BigDecimal(cacheRealtimeData.getWorkingCurrent()).divide(new BigDecimal(10));
        BigDecimal decimal1 = v.multiply(c).setScale(2, BigDecimal.ROUND_DOWN);
        xhpcRealTimeOrder.setVoltage(v);
        xhpcRealTimeOrder.setElectricCurrent(c);
        xhpcRealTimeOrder.setGunLineTemperature(cacheRealtimeData.getGunLineTemperature());
        xhpcRealTimeOrder.setGunLineNumber(cacheRealtimeData.getGunLineNumber());
        Integer soc = cacheRealtimeData.getSoc();
        xhpcRealTimeOrder.setSoc(soc.toString());
        xhpcRealTimeOrder.setMaxTemperature(cacheRealtimeData.getMaxTemperature());
        Integer chargingTime = cacheRealtimeData.getChargingTime();
        if(chargingTime>60){
            int hours = chargingTime / 60;
            int mins = (chargingTime-(hours*60)) % 60;
            xhpcRealTimeOrder.setChargingTime(hours+"时"+mins+"分");
        }else{
            xhpcRealTimeOrder.setChargingTime(chargingTime+"分");
        }
        Integer remainingTime = cacheRealtimeData.getRemainingTime();
        if(remainingTime>60){
            int hours = remainingTime / 60;
            double mins = (remainingTime-(hours*60))/60;
            xhpcRealTimeOrder.setRemainingTime(hours+"时"+new BigDecimal(mins).setScale(0)+"分");
        }else{
            double mins = remainingTime / 60;
            xhpcRealTimeOrder.setRemainingTime(new BigDecimal(mins).setScale(0)+"分");
        }
        BigDecimal decimal = new BigDecimal(10000);
        BigDecimal divide = new BigDecimal(cacheRealtimeData.getLossChargingDegree()).divide(decimal);
        BigDecimal chargingDegree = new BigDecimal(cacheRealtimeData.getChargingDegree()).divide(decimal);
        xhpcRealTimeOrder.setChargingDegree(chargingDegree);
        xhpcRealTimeOrder.setLossChargingDegree(divide);
        BigDecimal amountCharged = new BigDecimal(cacheRealtimeData.getAmountCharged()).divide(decimal);
        xhpcRealTimeOrder.setAmountCharged(amountCharged);
        xhpcRealTimeOrder.setHardwareFault(cacheRealtimeData.getHardwareFault());
        if ("00".equals(cacheRealtimeData.getStatus())) {
            xhpcRealTimeOrder.setStatus(0);
        } else if ("01".equals(cacheRealtimeData.getStatus())) {
            xhpcRealTimeOrder.setStatus(1);
        } else if ("02".equals(cacheRealtimeData.getStatus())) {
            xhpcRealTimeOrder.setStatus(2);
        } else {
            xhpcRealTimeOrder.setStatus(3);
        }
        xhpcRealTimeOrder.setCreateTime(date);
        xhpcRealTimeOrder.setUserId(xhpcChargeOrder.getUserId());
        Long chargingStationId = xhpcChargeOrder.getChargingStationId();
        xhpcRealTimeOrder.setChargingStationId(chargingStationId);
        xhpcRealTimeOrder.setChargingTimeNumber(cacheRealtimeData.getChargingTime());
        addXhpcRealTimeOrder(xhpcRealTimeOrder);
        //实时数据存入MYsql、soc、电流、电压

        XhpcChargeOrderSoc xhpcChargeOrderSoc = new XhpcChargeOrderSoc();
        xhpcChargeOrderSoc.setChargeOrderId(chargeOrderId);
        xhpcChargeOrderSoc.setSoc(soc.toString());
        xhpcChargeOrderSoc.setCreateTime(date);
        addSOC(xhpcChargeOrderSoc);

        XhpcChargeOrderCurrent xhpcChargeOrderCurrent =new XhpcChargeOrderCurrent();
        xhpcChargeOrderCurrent.setChargeOrderId(chargeOrderId);
        xhpcChargeOrderCurrent.setCurrent(c.toString());
        xhpcChargeOrderCurrent.setCreateTime(date);
        addCurrent(xhpcChargeOrderCurrent);

        XhpcChargeOrderVoltage xhpcChargeOrderVoltage =new XhpcChargeOrderVoltage();
        xhpcChargeOrderVoltage.setChargeOrderId(chargeOrderId);
        xhpcChargeOrderVoltage.setVoltage(v.toString());
        xhpcChargeOrderVoltage.setCreateTime(date);
        addVoltage(xhpcChargeOrderVoltage);
        if(type==1){
            map.put("code", 200);
            map.put("message", "实时数据");
            map.put("userId", xhpcChargeOrder.getUserId());
            Map<String, Object> data = new HashMap<>();
            data.put("amountCharged",amountCharged);
            data.put("gunNumber",gunId);
            data.put("chargingOrderId",chargeOrderId);
            data.put("chargingTimeNumber",cacheRealtimeData.getChargingTime());
            data.put("soc",soc);
            data.put("chargingTime",xhpcRealTimeOrder.getChargingTime());
            data.put("electricCurrent",c);
            data.put("voltage", v);
            data.put("power", decimal1.divide(new BigDecimal(1000),2,BigDecimal.ROUND_DOWN));
            data.put("chargingDegree", chargingDegree);
            data.put("remainingTime",xhpcRealTimeOrder.getRemainingTime());
            data.put("serialNumber",orderNo.substring(0,16));
            data.put("parkingInstructions","充电完成请尽快离场,超时车位占用费10元/小时");
            //获取桩直流还是交流
            Map<String, Object> xhpcChargingPile = xhpcChargeOrderService.getXhpcChargingPile(xhpcChargeOrder.getTerminalId());
            if(xhpcChargingPile !=null){
                data.put("type", xhpcChargingPile.get("type").toString());
            }else{
                data.put("type", 1);
            }
            map.put("data", data);
        }
        return map;
    }

    private BigDecimal getBigDecimal(Long rateModelId, String startTime, String updateTime, BigDecimal powerPriceTotal, BigDecimal divide) {
        List<Map<String, Object>> reatTimeList = xhpcHistoryOrderService.getReatTimeList(startTime,updateTime, rateModelId);
        for (int i = 0; i <reatTimeList.size() ; i++) {
            int size = reatTimeList.size();
            Map<String, Object> map = reatTimeList.get(i);
            String startTime1 = map.get("startTime").toString();
            String endTime1 = map.get("endTime").toString();
            BigDecimal powerFee =new BigDecimal(map.get("powerFee").toString());
            if("00:00:00".equals(endTime1)){
                endTime1="23:59:59";
            }
            //获取费率
            if(size==1){
                powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime,updateTime,divide,powerFee));
            }else{
               if(i==0){
                   powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime,endTime1,divide,powerFee));
               } else if(i<size-1){
                    powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime1,endTime1,divide,powerFee));
               }else{
                    powerPriceTotal = powerPriceTotal.add(getRateTimeList(startTime1,updateTime,divide,powerFee));
               }
            }
        }
        return powerPriceTotal;
    }

    private BigDecimal getRateTimeList(String startTime, String endTime, BigDecimal degree, BigDecimal powerPrice) {
        System.out.println("startTime>>"+startTime);
        System.out.println("endTime>>"+endTime);
        long time = DateUtil.parse(endTime).getTime();
        long time1= DateUtil.parse(startTime).getTime();
        BigDecimal multiply = new BigDecimal(time-time1).divide(new BigDecimal(60000),2, BigDecimal.ROUND_DOWN).multiply(degree).setScale(2,BigDecimal.ROUND_DOWN);
        BigDecimal bigDecimal = multiply.multiply(powerPrice).setScale(2, BigDecimal.ROUND_DOWN);
        System.out.println("bigDecimal>>"+bigDecimal);
        return  bigDecimal;
    }

}
