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

import com.xxfc.platform.order.entity.OrderReceivedStatisticsBase;
import com.xxfc.platform.order.entity.OrderTourReceivedStatistics;
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 OrderTourReceivedStatisticsSignEnum {
    TOUR_TOTAL_AMOUNT("ca_tta", "旅游订单总额") {
        @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<OrderTourReceivedStatistics> orderTourReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                BigDecimal totalAmount = orderTourReceivedStatisticsList.stream().map(x -> x.getTotalAmount()).reduce(BigDecimal.ZERO, (x, y) -> x.add(y));
                OrderTourReceivedStatistics orderReceivedStatistics = orderTourReceivedStatisticsList.get(0);
                OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics, totalAmount, null);
                orderReceivedStatisticsVos.add(receivedStatisticsVo);
            });
            resultMap.put(getSign(), orderReceivedStatisticsVos);
            return resultMap;
        }
    },
    TOUR_TOTAL_QUANTITY("cb_ttq", "旅游订单量") {
        @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<OrderTourReceivedStatistics> orderTourReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                Integer totalQuantity = orderTourReceivedStatisticsList.stream().map(x -> x.getTotalQuantity()).reduce(0, (x, y) -> x + y);
                OrderTourReceivedStatistics orderReceivedStatistics = orderTourReceivedStatisticsList.get(0);
                OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics, null, totalQuantity);
                orderReceivedStatisticsVos.add(receivedStatisticsVo);
            });
            resultMap.put(getSign(), orderReceivedStatisticsVos);
            return resultMap;
        }
    },
    TOUR_AVG_QUANTITY("cd_tavgq", "旅游订单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<OrderTourReceivedStatistics> orderTourReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                Integer divisor = divisorAtomicReference.get();
                if (Objects.isNull(divisor)){
                     divisor = orderTourReceivedStatisticsList.get(0).getDivisor();
                    divisorAtomicReference.set(divisor);
                }
                Integer avgQuantity = orderTourReceivedStatisticsList.stream().map(x -> x.getTotalQuantity()).reduce(0, (x, y) -> x + y) / divisor;
                OrderTourReceivedStatistics orderReceivedStatistics = orderTourReceivedStatisticsList.get(0);
                OrderReceivedStatisticsVo receivedStatisticsVo = ReceivedStatisticsEnum.createOrderReceivedStatistics(orderReceivedStatistics, null, avgQuantity);
                orderReceivedStatisticsVos.add(receivedStatisticsVo);
            });
            resultMap.put(getSign(), orderReceivedStatisticsVos);
            return resultMap;
        }
    },
    TOUR_AVG_AMOUNT("ce_tavga", "旅游金额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<OrderTourReceivedStatistics> orderTourReceivedStatisticsList = ReceivedStatisticsEnum.convertToTargetBean(V);
                Integer divisor = divisorAtomicReference.get();
                if (Objects.isNull(divisor)){
                    divisor = orderTourReceivedStatisticsList.get(0).getDivisor();
                    divisorAtomicReference.set(divisor);
                }
                BigDecimal avgAmount = orderTourReceivedStatisticsList.stream().map(x -> x.getTotalAmount()).reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal(divisor),2, RoundingMode.HALF_UP);
                OrderTourReceivedStatistics orderReceivedStatistics = orderTourReceivedStatisticsList.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, OrderTourReceivedStatisticsSignEnum> orderTourReceivedStatisticsSignEnumMap;

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

    OrderTourReceivedStatisticsSignEnum(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>> orderTourstatisticsMap, List<String> signs) {
        Map<String, List<OrderReceivedStatisticsVo>> resultMap = new HashMap<>(signs.size());
        for (String sign : signs) {
            OrderTourReceivedStatisticsSignEnum orderTourReceivedStatisticsSignEnum = orderTourReceivedStatisticsSignEnumMap.get(sign);
            Map<String, List<OrderReceivedStatisticsVo>> wrapToMap = orderTourReceivedStatisticsSignEnum.wrapToMap(orderTourstatisticsMap);
            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;
    }
}
