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

import com.xxfc.platform.order.entity.OrderReceivedStatistics;
import com.xxfc.platform.order.entity.OrderReceivedStatisticsBase;
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  OrderReceivedStatisticsSignEnum {
     ORDER_TOTAL_AMOUNT("aa_ota","订单总额"){
          @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<OrderReceivedStatistics> orderReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                    BigDecimal totalAmount = orderReceivedStatisticsList.stream().map(x -> x.getTotalAmount()).reduce(BigDecimal.ZERO, (x, y) -> x.add(y));
                    OrderReceivedStatistics orderReceivedStatistics = orderReceivedStatisticsList.get(0);
                    OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics,totalAmount,null);
                    orderReceivedStatisticsVos.add(receivedStatisticsVo);
               });
               resultMap.put(getSign(),orderReceivedStatisticsVos);
               return resultMap;
          }
     },
     ORDER_TOTAL_QUANTITY("ab_otq","订单量"){
          @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<OrderReceivedStatistics> orderReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                    Integer totalQuantity = orderReceivedStatisticsList.stream().map(x -> x.getTotalQuantity()).reduce(0, (x, y) -> x+y);
                    OrderReceivedStatistics orderReceivedStatistics = orderReceivedStatisticsList.get(0);
                    OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics,null,totalQuantity);
                    orderReceivedStatisticsVos.add(receivedStatisticsVo);
               });
               resultMap.put(getSign(),orderReceivedStatisticsVos);
               return resultMap;
          }
     },
     ORDER_AVG_QUANTITY("ac_oavgq","订单arpu"){
          @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<OrderReceivedStatistics> orderReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                    Integer avgQuantity = orderReceivedStatisticsList.stream().map(x -> x.getTotalQuantity()).reduce(0, (x, y) -> x+y)/V.size();
                    OrderReceivedStatistics orderReceivedStatistics = orderReceivedStatisticsList.get(0);
                    OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics,null,avgQuantity);
                    orderReceivedStatisticsVos.add(receivedStatisticsVo);
               });
               resultMap.put(getSign(),orderReceivedStatisticsVos);
               return resultMap;
          }
     },
     ORDER_AVG_AMOUNT("ad_oavga","订单金额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<OrderReceivedStatistics> orderReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                    Integer divisor = divisorAtomicReference.get();
                    if (Objects.isNull(divisor)){
                         divisor = orderReceivedStatisticsList.get(0).getDivisor();
                         divisorAtomicReference.set(divisor);
                    }
                    BigDecimal avgAmount = orderReceivedStatisticsList.stream().map(x -> x.getTotalAmount()).reduce(BigDecimal.ZERO,BigDecimal::add).divide(new BigDecimal(divisor),2, RoundingMode.HALF_UP);
                    OrderReceivedStatistics orderReceivedStatistics = orderReceivedStatisticsList.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,OrderReceivedStatisticsSignEnum> orderReceivedStatisticsSignEnumMap;

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

     OrderReceivedStatisticsSignEnum(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>> orderReceivedStatistics(Map<Object,List<OrderReceivedStatisticsBase>> orderMap,List<String> signs){
          Map<String,List<OrderReceivedStatisticsVo>> resultMap = new HashMap<>(signs.size());
          for (String sign : signs) {
               OrderReceivedStatisticsSignEnum orderReceivedStatisticsSignEnum = orderReceivedStatisticsSignEnumMap.get(sign);
               Map<String, List<OrderReceivedStatisticsVo>> wrapToMap = orderReceivedStatisticsSignEnum.wrapToMap(orderMap);
               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;
     }

}
