package com.xhpc.order.api;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.xhpc.common.api.WebSocketService;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.web.controller.BaseController;
import com.xhpc.common.data.redis.CacheOrderData;
import com.xhpc.common.data.redis.CacheRealtimeData;
import com.xhpc.common.domain.XhpcRate;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.order.domain.XhpcChargeOrder;
import com.xhpc.order.domain.XhpcHistoryOrder;
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.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;

@RestController
public class XhpcPileOrderController extends BaseController {

    @Autowired
    private RedisService redisService;

    @Autowired
    private IXhpcChargeOrderService xhpcChargeOrderService;

    @Autowired
    private IXhpcRealTimeOrderService xhpcRealTimeOrderService;

    @Autowired
    private WebSocketService webSocketService;

    @Autowired
    private IXhpcHistoryOrderService xhpcHistoryOrderService;


    private static final Logger logger = LoggerFactory.getLogger(XhpcPileOrderController.class);
    /**
     * 测试
     */
    @GetMapping("/test/chargeOrder/pileStartup")
    private R test(@RequestParam String orderNo, @RequestParam Integer status, @RequestParam String remark) {
        return null;
    }


    /**
     * 桩启动回调接口
     *
     * @param orderNo 订单号
     * @param status  1 成功 2失败
     * @param remark  备注
     * @return
     */
    @GetMapping("/chargeOrder/pileStartup")
    public R pileStartup(@RequestParam(value = "orderNo")String orderNo, @RequestParam(value = "status")Integer status,@RequestParam(value = "remark") String remark) {
        logger.info("桩启动回调接口>>>>>状态："+status+"备注++"+"remark"+"订单号"+orderNo);

        //解析订单编号
        Long userId =0L;
        Integer code =200;
        if (status == 1) {
            userId = update(0, remark, orderNo, 0);
        } else {
            code = 500;
            userId = update(-1,  remark, orderNo, 0);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        map.put("userId", userId);
        map.put("message", remark);
        JSONObject json = new JSONObject(map);
        logger.info("桩启动回调接口>>>>>json："+json.toString());
        //消息对了内容
        XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);
        if(xhpcChargeOrder.getSource()==0){
            webSocketService.getMessage(userId+"",json.toString());
        }
        return R.ok();
    }

    /**
     * 桩停止回调接口
     *
     * @param orderNo 订单号
     * @param status  1 成功 2失败 3数据中断 4恢复数据
     * @param remark  备注
     * @return
     */
    @GetMapping("/chargeOrder/pileStop")
    public R pileStop(@RequestParam(value = "orderNo")String orderNo, @RequestParam(value = "status")Integer status,@RequestParam(value = "remark") String remark) {
        logger.info("桩停止回调接口>>>>>状态："+status+"备注++"+"remark"+"订单号"+orderNo);

        //解析订单编号
        Integer code = 500;
        Long userId=0L;
        Map<String, Object> map = new HashMap<>();
        if(status == 1|| status == 2){
            userId = update(0,  remark, orderNo, 1);
            map.put("userId", userId);
        }
        XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);
        if (status == 1) {
            xhpcChargeOrder.setStatus(0);
            map.put("message", "停止充电成功");
        } else if(status==2){
            //停止充电失败
            code=300;
            map.put("message", remark);
        }else if(status==3 || status==4){
            //订单定位异常,修改充电订单状态
            if(status==3) {
                xhpcChargeOrder.setStatus(2);
                xhpcChargeOrder.setUpdateTime(new Date());
                //获取实时订单
                Map<String, Object> cacheMap = redisService.getCacheMap("order:" + orderNo);
                List<CacheRealtimeData> list = (List<CacheRealtimeData>) cacheMap.get("realtimeDataList");
                if (list != null && list.size() > 0) {
                    int number = 0;
                    if (list.size() != 1) {
                        number = list.size() - 1;
                    }
                    BigDecimal decimal = new BigDecimal(10000);
                    CacheRealtimeData cacheRealtimeData = list.get(number);
                    xhpcChargeOrder.setChargingDegree(new BigDecimal(cacheRealtimeData.getChargingDegree()).divide(decimal));
                    //充电时长
                    Long tiem = Long.valueOf(cacheRealtimeData.getChargingTime() / 1000);
                    if (tiem > 3600) {
                        long hours = tiem / 3600;
                        double mins = (double) ((tiem - (hours * 3600)) / 60);
                        xhpcChargeOrder.setChargingTime(hours + "时" + new BigDecimal(mins).setScale(0) + "分");
                    } else {
                        double mins = (double) (tiem / 60);
                        xhpcChargeOrder.setChargingTime(new BigDecimal(mins).setScale(0) + "分");
                    }
                    xhpcChargeOrder.setChargingTimeNumber(Long.valueOf(cacheRealtimeData.getChargingTime()));
                    xhpcChargeOrder.setAmountCharged(new BigDecimal(cacheRealtimeData.getAmountCharged()).divide(decimal));
                    xhpcChargeOrder.setEndSoc(""+cacheRealtimeData.getSoc());

                    CacheRealtimeData cacheRealtimeData1 = list.get(0);
                    xhpcChargeOrder.setStartSoc(""+cacheRealtimeData1.getSoc());
                }
            }else{
                if (xhpcChargeOrder.getStatus() == 1 || xhpcChargeOrder.getStatus() == 3) {
                    //不修改订单
                } else {
                    xhpcChargeOrder.setStatus(0);
                }
            }
            xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
            code = 300;
            userId =xhpcChargeOrder.getUserId();
            map.put("userId",userId);
            map.put("message", remark);
        }else{
            //修改订单，判断订单
        }
        if(xhpcChargeOrder.getSource()==0){
            map.put("code", code);
            JSONObject json = new JSONObject(map);
            //消息对了内容
            webSocketService.getMessage(userId+"",json.toString());
        }
        return R.ok();
    }

    /**
     * 桩实时数据回调接口
     * @param orderNo   订单号
     * @return
     */
    @Transactional
    @GetMapping("/chargeOrder/pileRimeOrder")
    public R pileRealtime(@RequestParam(value = "orderNo")String orderNo) {

        logger.info("桩实时数据回调接口>>>>>orderNo：" + orderNo);
        //获取实时订单
        CacheRealtimeData cacheRealtimeData = redisService.getCacheObject("order:" + orderNo + ".lord");

        XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);

        Long userId = xhpcChargeOrder.getUserId();
        try {
            Date date = new Date();
            xhpcChargeOrder.setEndTime(date);
            xhpcChargeOrder.setUpdateTime(date);
            xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
            Map<String, Object> map = xhpcRealTimeOrderService.addOrderTime(cacheRealtimeData, xhpcChargeOrder, orderNo, 1);
            if(xhpcChargeOrder.getSource()==0){
                JSONObject json = new JSONObject(map);
                //消息对了内容
                webSocketService.getMessage(userId+"",json.toString());
                logger.info("桩实时数据发送WebSocket成功>>>>>orderNo：" + orderNo);
            }

        } catch (Exception e) {
            Map<String, Object> map = new HashMap<>();
            map.put("code", 500);
            map.put("userId", xhpcChargeOrder.getUserId());
            JSONObject json = new JSONObject(map);
            if(xhpcChargeOrder.getSource()==0){
                //消息对了内容
                webSocketService.getMessage(userId+"",json.toString());
            }
            return R.fail(500,"无实时数据");
        }
        return R.ok();
    }


    /**
     * 桩订单结束回调
     */
    @Transactional
    @PostMapping("/chargeOrder/pileEndOrder")
    public R pileEndOrder(@RequestParam(value = "orderNo") String orderNo) {
        logger.info("桩订单结束回调>>>>>orderNo："+orderNo);
        try{
            //获取实时订单
            Map<String, Object> cacheMap = redisService.getCacheMap("order:"+orderNo);
            CacheOrderData cacheOrderData = (CacheOrderData)cacheMap.get("orderData");
            //获取充电订单
            XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);
            if(xhpcChargeOrder == null ){
                return R.fail(500,"无效订单号："+orderNo);
            }
            if(xhpcChargeOrder.getStatus()==1 || xhpcChargeOrder.getStatus()==3){
                logger.info("订单已结束不能重复结算>>>>>orderNo："+orderNo+">>>chargeOrderId:"+xhpcChargeOrder.getChargeOrderId());
                return R.ok();
            }
            //解析订单编号
            Date date = new Date();
            //总金额
            BigDecimal bigDecimal = new BigDecimal(10000);
            BigDecimal money = new BigDecimal(cacheOrderData.getCost()).divide(bigDecimal);
            //00: 尖费率 01: 峰费率 02: 平费率 03: 谷费率
            BigDecimal t1powerFee =new BigDecimal(0);
            BigDecimal t2powerFee =new BigDecimal(0);
            BigDecimal t3powerFee =new BigDecimal(0);
            BigDecimal t4powerFee =new BigDecimal(0);
            //费率计费模型
            List<XhpcRate> rateModelList = xhpcChargeOrderService.getRateModelId(xhpcChargeOrder.getRateModelId());
            for (XhpcRate xhpcRate:rateModelList) {
                System.out.println(">>>>>>"+xhpcRate.getRateValue());
                if("00".equals(xhpcRate.getRateValue())){
                    t1powerFee = xhpcRate.getPowerFee();
                }
                if("01".equals(xhpcRate.getRateValue())){
                    t2powerFee = xhpcRate.getPowerFee();
                }
                if("02".equals(xhpcRate.getRateValue())){
                    t3powerFee = xhpcRate.getPowerFee();
                }
                if("03".equals(xhpcRate.getRateValue())){
                    t4powerFee = xhpcRate.getPowerFee();
                }
            }
            //总电费
            BigDecimal powerPrice =new BigDecimal(0);
            Integer totalPower =0;
            if(!"0".equals(cacheOrderData.getT1PowerQuantity().toString())){
                BigDecimal multiply = new BigDecimal(cacheOrderData.getT1PowerQuantity()).divide(bigDecimal).multiply(t1powerFee);
                totalPower =totalPower+cacheOrderData.getT1PowerQuantity();
                powerPrice=powerPrice.add(multiply);
            }
            if(!"0".equals(cacheOrderData.getT2PowerQuantity().toString())){
                BigDecimal multiply = new BigDecimal(cacheOrderData.getT2PowerQuantity()).divide(bigDecimal).multiply(t2powerFee);
                totalPower =totalPower+cacheOrderData.getT2PowerQuantity();
                powerPrice=powerPrice.add(multiply);
            }
            if(!"0".equals(cacheOrderData.getT3PowerQuantity().toString())){
                BigDecimal multiply = new BigDecimal(cacheOrderData.getT3PowerQuantity()).divide(bigDecimal).multiply(t3powerFee);
                totalPower =totalPower+cacheOrderData.getT3PowerQuantity();
                powerPrice=powerPrice.add(multiply);
            }
            if(!"0".equals(cacheOrderData.getT4PowerQuantity().toString())){
                BigDecimal multiply = new BigDecimal(cacheOrderData.getT4PowerQuantity()).divide(bigDecimal).multiply(t4powerFee);
                totalPower =totalPower+cacheOrderData.getT4PowerQuantity();
                powerPrice=powerPrice.add(multiply);
            }
            powerPrice =powerPrice.setScale(2,BigDecimal.ROUND_DOWN);
            //总服务费
            BigDecimal servicePrice = money.subtract(powerPrice);
            //剩余的电费
            BigDecimal surplusPowerPrice = powerPrice;
            //剩余的服务费
            BigDecimal surplusServicePrice = servicePrice;
            int startSoc = cacheOrderData.getStartSoc();
            int endSoc = cacheOrderData.getEndSoc();

            xhpcChargeOrder.setStartSoc(startSoc + "");
            xhpcChargeOrder.setEndSoc(endSoc + "");
            int status = cacheOrderData.getStatus();
            xhpcChargeOrder.setStatus(status);

            DateTime startTime = DateUtil.parse(cacheOrderData.getStartTime());
            DateTime endTime = DateUtil.parse(cacheOrderData.getEndTime());
            xhpcChargeOrder.setStartTime(startTime);
            xhpcChargeOrder.setEndTime(endTime);
            //充电时长
            Long tiem = (endTime.getTime() - startTime.getTime()) / 1000;
            if (tiem > 3600) {
                long hours = tiem / 3600;
                double mins = (double) ((tiem - (hours * 3600)) / 60);
                xhpcChargeOrder.setChargingTime(hours + "时" + new BigDecimal(mins).setScale(0) + "分");
            } else {
                double mins = (double) (tiem / 60);
                xhpcChargeOrder.setChargingTime(new BigDecimal(mins).setScale(0) + "分");
            }
            xhpcChargeOrder.setChargingTimeNumber(tiem);
            BigDecimal divide = new BigDecimal(cacheOrderData.getTotalPowerQuantity()).divide(bigDecimal);
            xhpcChargeOrder.setChargingDegree(divide);
            xhpcChargeOrder.setAmountCharged(money);
            String stopReason = cacheOrderData.getStopReason();
            xhpcChargeOrder.setRemark(stopReason);
            xhpcChargeOrder.setUpdateTime(date);
            xhpcChargeOrder.setStatus(status);
            XhpcHistoryOrder xhpcHistoryOrder = new XhpcHistoryOrder();
            //停止原因
            try{
                if(!"".equals(stopReason) && stopReason!=null){
                    xhpcChargeOrder.setType(Integer.parseInt(stopReason));
                    if("40".equals(stopReason)){
                        xhpcHistoryOrder.setStopReasonEvcs(0);
                    }else if("42".equals(stopReason) || "43".equals(stopReason)||"44".equals(stopReason)){
                        xhpcHistoryOrder.setStopReasonEvcs(1);
                    }else if("41".equals(stopReason)){
                        xhpcHistoryOrder.setStopReasonEvcs(2);
                    }else if("48".equals(stopReason)){
                        xhpcHistoryOrder.setStopReasonEvcs(3);
                    }else{
                        xhpcHistoryOrder.setStopReasonEvcs(5);
                    }
                }
            }catch (Exception e){}
            //历史订单
            Long userId = xhpcChargeOrder.getUserId();
            //生成一条历史订单
            xhpcHistoryOrder.setStartTime(startTime);
            xhpcHistoryOrder.setEndTime(endTime);
            xhpcHistoryOrder.setPowerPriceTotal(powerPrice);
            xhpcHistoryOrder.setServicePriceTotal(servicePrice);
             xhpcHistoryOrder.setTotalPower(totalPower.doubleValue()/10000);
            xhpcHistoryOrder.setMeterValueStartEvcs(cacheOrderData.getElectricMeterStart().doubleValue());
            xhpcHistoryOrder.setMeterValueEndEvcs(cacheOrderData.getElectricMeterEnd().doubleValue());
            Map<String, Object> userMessage =new HashMap<>();
            if(xhpcChargeOrder.getSource()==0){
                userMessage = xhpcChargeOrderService.getUserMessage(userId);
                if (userMessage == null || userMessage.get("balance") == null) {
                    //订单异常
                    xhpcChargeOrder.setStatus(2);
                    //异常原因
                    xhpcChargeOrder.setErroRemark("桩异常：" + stopReason + ">>>>用户id:" + userId + "为空");
                    xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);
                    R.ok();
                }
            }else{
                Map<String, Object> pushOrder = redisService.getCacheMap("pushOrder:"+orderNo);
                xhpcHistoryOrder.setInternetSerialNumber(pushOrder.get("internetSerialNumber").toString());
                xhpcHistoryOrder.setOperatorId3rdptyEvcs((String) pushOrder.get("operatorId3rdpty"));
                xhpcChargeOrder.setOperatorId3rdptyEvcs((String) pushOrder.get("operatorId3rdpty"));
            }
            xhpcHistoryOrder.setType(1);
            //结算
            xhpcRealTimeOrderService.addSettlement(powerPrice,servicePrice,money,surplusPowerPrice,surplusServicePrice,xhpcChargeOrder,userId,userMessage,1,cacheOrderData.getVinNormal(),xhpcHistoryOrder);
            Map<String, Object> map = new HashMap<>();
            map.put("code", 500);
            map.put("userId", userId);
            JSONObject json = new JSONObject(map);
            webSocketService.getMessage(userId+"",json.toString());
        }catch (Exception e){
            e.printStackTrace();
            return R.fail(500,"添加订单回调失败");
        }
        return R.ok();
    }


    /**
     * 订单异常回调接口
     */
    @Transactional
    @PostMapping("/chargeOrder/abnormalOrder")
    public R abnormalOrder(@RequestParam(value = "orderNo") String orderNo) {
        xhpcHistoryOrderService.addXhpcChargeOrder(orderNo,1);
        //获取实时订单
       XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(orderNo);
        Long userId = xhpcChargeOrder.getUserId();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 500);
        map.put("userId", xhpcChargeOrder.getUserId());
        JSONObject json = new JSONObject(map);
        //消息对了内容
        webSocketService.getMessage(userId+"",json.toString());
        logger.info("异常桩实时数据发送WebSocket成功>>>>>orderNo：" + orderNo);
        return R.ok();
    }

    /**
     * @param status       状态
     * @param remark       备注
     * @param serialNumber 订单号
     * @param type         结束订单状态
     * @return
     */
    private Long update(Integer status, String remark, String serialNumber, Integer type) {
        logger.info("状态："+status+"备注++"+"remark"+"订单号"+serialNumber);
        XhpcChargeOrder xhpcChargeOrder = xhpcChargeOrderService.getSerialNumberMessage(serialNumber);
        Date date = new Date();
        if(status==0){
            xhpcChargeOrder.setStatus(0);
            xhpcChargeOrder.setStartTime(date);
        } else{
            xhpcChargeOrder.setStatus(-1);
            xhpcChargeOrder.setDelFlag(1);
            xhpcChargeOrder.setEndTime(date);
        }
        xhpcChargeOrder.setErroRemark(remark);

        Long userId = xhpcChargeOrder.getUserId();
        if (type == 1) {
            //充电订单  --结束soc、充电时长、充电度数
            xhpcChargeOrder.setEndTime(date);
        }
        xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder);

        return userId;
    }

//    private void rabbimt(String message) {
//        //发送消息队列
//        try {
//            // 1、获取到连接
//            Connection connection = ConnectionRabbitMQUtil.getConnection();
//            // 2、从连接中创建通道，使用通道才能完成消息相关的操作
//            Channel channel = connection.createChannel();
//            // 3、声明（创建）队列
//            channel.queueDeclare("webSocket", false, false, false, null);
//            // 4、消息内容
//            channel.basicPublish("", "webSocket", null, message.getBytes());
//            channel.close();
//            connection.close();
//        } catch (Exception e) {
//
//        }
//    }
@GetMapping(value = "/chargeOrder/pileStartUpBy3rd")
public R pileStartUpBy3rd(@RequestParam(value = "internetSerialNumber") String internetSerialNumber,
                          @RequestParam(value = "driverId", required = false) String driverId,
                          @RequestParam(value = "chargingAmt", required = false, defaultValue = "500") Integer chargingAmt,
                          @RequestParam(value = "plateNum", required = false) String plateNum,
                          @RequestParam(value = "status") Integer status,
                          @RequestParam(value = "connectorId") String connectorId) {

    return xhpcChargeOrderService.startUpBy3rd(internetSerialNumber, driverId, chargingAmt, plateNum, status, connectorId);
}

}
