package com.xxfc.platform.order.contant.enumerate;

import com.xxfc.platform.order.entity.OrderReceivedStatisticsBase;
import com.xxfc.platform.order.entity.OrderRentVehicleReceivedStatistics;
import com.xxfc.platform.order.pojo.vo.OrderReceivedStatisticsVo;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author libin
 * @version 1.0
 * @description
 * @data 2019/11/11 10:36
 */
public enum OrderRentVehicleReceivedStatisticsSignEnum{
     RENT_VEHICLE_TOTAL_AMOUNT("ba_rvta","租车订单总额"){
         @Override
         Map<String, List<OrderReceivedStatisticsVo>> wrapToMap(Map<Object, List<OrderReceivedStatisticsBase>> orderMap) {
             Map<String, List<OrderReceivedStatisticsVo>> resultMap = new HashMap<>();
             List<OrderReceivedStatisticsVo> orderReceivedStatisticsVos = new ArrayList<>();
             orderMap.forEach((K,V)->{
                 List<OrderRentVehicleReceivedStatistics> orderRentVehicleReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                 BigDecimal totalAmount = orderRentVehicleReceivedStatisticsList.stream().map(x -> x.getTotalAmount()).reduce(BigDecimal.ZERO, (x, y) -> x.add(y));
                 OrderRentVehicleReceivedStatistics orderReceivedStatistics = orderRentVehicleReceivedStatisticsList.get(0);
                 OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics,totalAmount,null);
                 orderReceivedStatisticsVos.add(receivedStatisticsVo);
             });
             resultMap.put(getSign(),orderReceivedStatisticsVos);
             return resultMap;
         }
     },
     RENT_VEHICLE_TOTAL_QUANTITY("bb_rvtq","租车订单量") {
         @Override
         Map<String, List<OrderReceivedStatisticsVo>> wrapToMap(Map<Object, List<OrderReceivedStatisticsBase>> orderMap) {
             Map<String, List<OrderReceivedStatisticsVo>> resultMap = new HashMap<>();
             List<OrderReceivedStatisticsVo> orderReceivedStatisticsVos = new ArrayList<>();
             orderMap.forEach((K,V)->{
                 List<OrderRentVehicleReceivedStatistics> orderRentVehicleReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                 Integer totalQuantity = orderRentVehicleReceivedStatisticsList.stream().map(x -> x.getTotalQuantity()).reduce(0, (x, y) -> x+y);
                 OrderRentVehicleReceivedStatistics orderReceivedStatistics = orderRentVehicleReceivedStatisticsList.get(0);
                 OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics,null,totalQuantity);
                 orderReceivedStatisticsVos.add(receivedStatisticsVo);
             });
             resultMap.put(getSign(),orderReceivedStatisticsVos);
             return resultMap;
         }
     },
     RENT_VEHICLE_AVG_QUANTITY("bc_rvavgq","租车订单arpu") {
         @Override
         Map<String, List<OrderReceivedStatisticsVo>> wrapToMap(Map<Object, List<OrderReceivedStatisticsBase>> orderMap) {
             Map<String, List<OrderReceivedStatisticsVo>> resultMap = new HashMap<>();
             AtomicReference<Integer> divisorAtomicReference = new AtomicReference<>();
             List<OrderReceivedStatisticsVo> orderReceivedStatisticsVos = new ArrayList<>();
             orderMap.forEach((K,V)->{
                 List<OrderRentVehicleReceivedStatistics> orderRentVehicleReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                 Integer divisor = divisorAtomicReference.get();
                 if (Objects.isNull(divisor)){
                     divisor = orderRentVehicleReceivedStatisticsList.get(0).getDivisor();
                     divisorAtomicReference.set(divisor);
                 }
                 Integer avgQuantity = orderRentVehicleReceivedStatisticsList.stream().map(x -> x.getTotalQuantity()).reduce(0, (x, y) -> x+y)/divisor;
                 OrderRentVehicleReceivedStatistics orderReceivedStatistics = orderRentVehicleReceivedStatisticsList.get(0);
                 OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics,null,avgQuantity);
                 orderReceivedStatisticsVos.add(receivedStatisticsVo);
             });
             resultMap.put(getSign(),orderReceivedStatisticsVos);
             return resultMap;
         }
     },
    RENT_VEHICLE_AVG_AMOUNT("bd_rvavga","租车金额arpu") {
        @Override
        Map<String, List<OrderReceivedStatisticsVo>> wrapToMap(Map<Object, List<OrderReceivedStatisticsBase>> orderMap) {
            Map<String, List<OrderReceivedStatisticsVo>> resultMap = new HashMap<>();
            AtomicReference<Integer> divisorAtomicReference = new AtomicReference<>();
            List<OrderReceivedStatisticsVo> orderReceivedStatisticsVos = new ArrayList<>();
            orderMap.forEach((K,V)->{
                List<OrderRentVehicleReceivedStatistics> orderRentVehicleReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                Integer divisor = divisorAtomicReference.get();
                if (Objects.isNull(divisor)){
                    divisor = orderRentVehicleReceivedStatisticsList.get(0).getDivisor();
                    divisorAtomicReference.set(divisor);
                }
                BigDecimal avgAmount = orderRentVehicleReceivedStatisticsList.stream().map(x -> x.getTotalAmount()).reduce(BigDecimal.ZERO,BigDecimal::add).divide(new BigDecimal(divisor),2, RoundingMode.HALF_UP);
                OrderRentVehicleReceivedStatistics orderReceivedStatistics = orderRentVehicleReceivedStatisticsList.get(0);
                OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics,avgAmount,null);
                orderReceivedStatisticsVos.add(receivedStatisticsVo);
            });
            resultMap.put(getSign(),orderReceivedStatisticsVos);
            return resultMap;
        }
    };

    private String sign;
    private String desc;
    private static  Map<String,OrderRentVehicleReceivedStatisticsSignEnum> orderRentVehicleReceivedStatisticsSignEnumMap;

    static {
        orderRentVehicleReceivedStatisticsSignEnumMap = EnumSet.allOf(OrderRentVehicleReceivedStatisticsSignEnum.class).stream().collect(Collectors.toMap(OrderRentVehicleReceivedStatisticsSignEnum::getSign, Function.identity()));
    }

     OrderRentVehicleReceivedStatisticsSignEnum(String sign, String desc) {
          this.sign = sign;
          this.desc = desc;
     }
    /**
     * 统计项
     * @param orderMap
     * @return
     */
    abstract Map<String, List<OrderReceivedStatisticsVo>> wrapToMap(Map<Object,List<OrderReceivedStatisticsBase>> orderMap);

    public static Map<String, List<OrderReceivedStatisticsVo>> orderMemberstatisticsMap(Map<Object, List<OrderReceivedStatisticsBase>> orderRentVehiclestatisticsMap, List<String> signs) {
        Map<String, List<OrderReceivedStatisticsVo>> resultMap = new HashMap<>(signs.size());
        for (String sign : signs) {
            OrderRentVehicleReceivedStatisticsSignEnum orderRentVehicleReceivedStatisticsSignEnum = orderRentVehicleReceivedStatisticsSignEnumMap.get(sign);
            Map<String, List<OrderReceivedStatisticsVo>> wrapToMap = orderRentVehicleReceivedStatisticsSignEnum.wrapToMap(orderRentVehiclestatisticsMap);
            resultMap.putAll(wrapToMap);
        }
        return resultMap;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

}

