package com.xhpc.evcs.notification;

import com.xhpc.common.data.redis.CacheOrderData;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.evcs.domain.AuthSecretToken;
import com.xhpc.evcs.domain.EtDisputeOrder;
import com.xhpc.evcs.domain.XhpcRate;
import com.xhpc.evcs.dto.ChargeOrder;
import com.xhpc.evcs.dto.CheckChargeOrderRequestData;
import com.xhpc.evcs.dto.CheckChargeOrderResponseData;
import com.xhpc.evcs.dto.CommonRequest;
import com.xhpc.evcs.jpa.AuthSecretTokenRepository;
import com.xhpc.evcs.jpa.EtDisputeOrdersRepository;
import com.xhpc.evcs.jpa.XhpcRateRepository;
import com.xhpc.evcs.utils.JSONUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;
import static com.xhpc.evcs.domain.AuthSecretToken.SECRET_TOKEN_TYPE_OUT;

/**
 * 推送所有充电结束后的订单进行对账
 *
 * @author WH
 * @date 2021/11/8 10:06
 * @since version-1.0
 */
public class CheckChargeOrders extends CoreDispatcher {

    @Resource
    private RedisService redisService;
    @Resource
    private XhpcRateRepository xhpcRateRepository;
    @Resource
    private AuthSecretTokenRepository authSecretTokenRepository;
    @Resource
    private EtDisputeOrdersRepository etDisputeOrdersRepository;

    public void checkChargeOrder() throws Exception {

        //获取Redis中的所有订单的状态数据
        Collection<String> pushOrders = REDIS.keys("pushOrder:*");

        for (String pushOrderKey : pushOrders) {
            Map<String, Object> pushOrder = REDIS.getCacheMap(pushOrderKey);
            Boolean isStopNotified = (Boolean) pushOrder.get("isStopNotified");
            if (isStopNotified != null && isStopNotified) {
                continue;
            }
            String orderNo = pushOrderKey.substring(10);
            Map<String, Object> order = REDIS.getCacheMap("order:" + orderNo);
            String operatorId3rdpty = (String) pushOrder.get("operatorId3rdpty");
            if (operatorId3rdpty == null) {
                continue;
            }
            AuthSecretToken authSecretTokenOut =
                    authSecretTokenRepository.findByOperatorId3irdptyAndSecretTokenType(operatorId3rdpty,
                            SECRET_TOKEN_TYPE_OUT).orElse(null);
            if (authSecretTokenOut == null) {
                continue;
            }
            CommonRequest<CheckChargeOrderRequestData> commonRequest = new CommonRequest<>();
            //封装数据的实体类
            CheckChargeOrderRequestData checkChargeOrder = new CheckChargeOrderRequestData();
            //判断是否是结束了的充电订单
            if (isStopNotified) {
                //订单对账流水号（内部对应的第三方充电订单号）
                CacheOrderData orderData = (CacheOrderData) order.get("orderData");
                String internetSerialNumber = (String) pushOrder.get("internetSerialNumber");
                checkChargeOrder.setCheckOrderSeq(internetSerialNumber);
                //充电订单号（内部对应的第三方充电订单号）
                ChargeOrder chargeOrder = new ChargeOrder();
                chargeOrder.setStartChargeSeq(internetSerialNumber);

                if (orderData != null) {
                    //使用指定包装类封装数据
                    //账单开始时间
                    checkChargeOrder.setStartTime(orderData.getStartTime());
                    //账单结束时间
                    checkChargeOrder.setEndTime(orderData.getEndTime());
                    //订单数量
                    checkChargeOrder.setOrderCount(1);
                    //总电量
                    checkChargeOrder.setTotalOrderPower(Double.parseDouble(orderData.getTotalPowerQuantity().toString()) / 10000);
                    //累计充电量
                    chargeOrder.setTotalPower(Double.parseDouble(orderData.getTotalPowerQuantity().toString()) / 10000);
                    //总金额
                    Map<String, Double> map = getTotalElecMoneyAndTotalServiceMoney(orderNo);
                    Double totalPowerPrice = map.get("totalPowerPrice");
                    Double totalServicePrice = map.get("totalServicePrice");
                    Double sumMoney = totalPowerPrice + totalServicePrice;
                    checkChargeOrder.setTotalOrderMoney(sumMoney);
                    //累计总金额
                    chargeOrder.setTotalMoney(sumMoney);
                    List<ChargeOrder> orderList = new ArrayList<>();
                    orderList.add(chargeOrder);
                    checkChargeOrder.setChargeOrders(orderList);
                    //将其转换为json
                    String jsonData = JSONUtil.toJSONString(checkChargeOrder);
                    commonRequest.setData(jsonData);

                    //推送并处理推送结果
                    String result = ok(commonRequest, "/check_charge_orders", authSecretTokenOut);
                    CheckChargeOrderResponseData checkChargeOrderResponseData = JSONUtil.readParams(result,
                            CheckChargeOrderResponseData.class); //todo check NPE
                    if (checkChargeOrderResponseData.getDisputeOrders() == null) {
                        //没有争议订单
                        REDIS.deleteObject(pushOrderKey);
                    }
                    //将争议订单放入数据库
                    EtDisputeOrder etDisputeOrder = JSONUtil.copyProperties(result, EtDisputeOrder.class);
                    etDisputeOrder = etDisputeOrdersRepository.save(etDisputeOrder);
                    if (etDisputeOrder.getId() != null) {
                        REDIS.deleteObject(pushOrderKey);
                    }
                }
            }
        }
    }

    private Map<String, Double> getTotalElecMoneyAndTotalServiceMoney(String orderNo) {

        //获取结算后的订单
        Map<String, Object> cacheMap = redisService.getCacheMap("order:" + orderNo);
        CacheOrderData cacheOrderData = (CacheOrderData) cacheMap.get("orderData");
        //总金额
        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);
        //费率计费模型
        Long rateModelId = (Long) cacheMap.get("rateModelId");
        List<XhpcRate> rateModelList = xhpcRateRepository.findByRateModelId(rateModelId);
        for (XhpcRate xhpcRate : rateModelList) {
            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_HALF_UP);
        //总服务费
        BigDecimal servicePrice = money.subtract(powerPrice);

        HashMap<String, Double> data = new HashMap<>(7);
        data.put("totalPowerPrice", servicePrice.doubleValue());
        data.put("totalServicePrice", servicePrice.doubleValue());

        return data;
    }

}
