package com.xxfc.platform.order.biz;

import cn.hutool.core.util.ObjectUtil;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.google.common.collect.Lists;
import com.xxfc.platform.order.bo.FeeTypeBo;
import com.xxfc.platform.order.contant.enumerate.StatisticsStatusEnum;
import com.xxfc.platform.order.entity.OrderTourReceivedStatistics;
import com.xxfc.platform.order.mapper.OrderTourReceivedStatisticsMapper;
import com.xxfc.platform.order.pojo.account.OrderAccountBo;
import com.xxfc.platform.order.pojo.dto.OrderDTO;
import com.xxfc.platform.order.pojo.dto.OrderReceivedStatisticsFindDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
/**
 * @author libin
 * @version 1.0 旅游统计
 * @description
 * @data 2019/11/28 9:57
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class OrderTourReceivedStatisticsBiz extends BaseBiz<OrderTourReceivedStatisticsMapper, OrderTourReceivedStatistics> {
    private final BaseOrderBiz baseOrderBiz;
    private final OrderAccountBiz orderAccountBiz;

    public List<OrderTourReceivedStatistics> selectOrderReceivedStatisticsGroupByDate(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO) {
         return mapper.selectOrderTourReceivedStatisticsGroupByDate(orderReceivedStatisticsFindDTO);
    }
    public List<OrderTourReceivedStatistics> selectOrderReceivedStatisticsGroupByMonth(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO) {
        return mapper.selectOrderTourReceivedStatisticsGroupByMonth(orderReceivedStatisticsFindDTO);
    }
    public List<OrderTourReceivedStatistics> selectOrderReceivedStatisticsGroupByWeekOfYear(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO) {
        return mapper.selectOrderTourReceivedStatisticsGroupByWeekOfYear(orderReceivedStatisticsFindDTO);
    }

    /**
     * 订单统计批量插入旅游统计表
     * zuoyihang
     * 2019-11-12
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     */
    public List<OrderTourReceivedStatistics> orderTourInsertStatisticsNew(Date startDate, Date endDate, Map<Integer, String> companyMap) {
        List<OrderTourReceivedStatistics> orderTourReceivedStatisticsList = new ArrayList();
        List<String> stisticsActiveState = new ArrayList<>();

        //根据旅游类型 时间查询
        List<OrderDTO> orderDTOS = baseOrderBiz.selectOrdersByTypeAndTime(Arrays.asList(StatisticsStatusEnum.ORDER_TOUR_TYPE),null, startDate, endDate);
        //数据处理 状态组合 按支付状态分组 而后按组合状态
        Map<Boolean, Map<String, List<OrderDTO>>> stateGroupMap = StatisticsStatusEnum.processOrdersWithState(stisticsActiveState, orderDTOS);

        //订单账目信息
        List<OrderAccountBo> orderAccountBoList = orderAccountBiz.selectByTypeAndDate(StatisticsStatusEnum.ORDER_TOUR_TYPE, startDate, endDate);
        //账目数据整理 状态组合
        Map<String, List<OrderAccountBo>> orderMap = StatisticsStatusEnum.processOrderAccountsWithState(stisticsActiveState,orderAccountBoList);

        //已经支付订单
        Set<Map.Entry<String, List<OrderAccountBo>>> orderSet = orderMap.entrySet();
        for (Map.Entry<String, List<OrderAccountBo>> orderEntry : orderSet) {
            String orderKey = orderEntry.getKey();
            List<OrderAccountBo> orderAccountBos = orderEntry.getValue();
            //创建并设置旅游统计对象默认值
            OrderTourReceivedStatistics orderTourReceivedStatistics = StatisticsStatusEnum.wrapStatisticsObject(startDate, orderKey, companyMap, new OrderTourReceivedStatistics());
            //账目处理
            FeeTypeBo feeTypeBo = StatisticsStatusEnum.getFeeTyBoByOrderAccounts(orderAccountBos);
            //旅游订单量
            Integer totalQuantity = stateGroupMap == null ?
                    0 : stateGroupMap.get(Boolean.TRUE) == null ?
                    0 : stateGroupMap.get(Boolean.TRUE).get(orderKey) == null ?
                    0 : stateGroupMap.get(Boolean.TRUE).get(orderKey).size();
            orderTourReceivedStatistics.setTotalQuantity(totalQuantity);

            //复制对应的金额（订单支付金额、退款金额、违约金）
            BeanUtils.copyProperties(feeTypeBo,orderTourReceivedStatistics);
            orderTourReceivedStatisticsList.add(orderTourReceivedStatistics);
        }

        //未支付订单
        Map<String, List<OrderDTO>> noPayOrderRentvehicleMap = stateGroupMap == null ?
                Collections.EMPTY_MAP : stateGroupMap.get(Boolean.FALSE) == null ?
                Collections.EMPTY_MAP : stateGroupMap.get(Boolean.FALSE);
        List<OrderTourReceivedStatistics> noPayOrderTourReceivedStatisticsList = createNoPayOrderTourReceivedStatisticsListList(startDate, noPayOrderRentvehicleMap, companyMap);
        orderTourReceivedStatisticsList.addAll(noPayOrderTourReceivedStatisticsList);

        //创建剩余状态组合旅游统计对象
        List<OrderTourReceivedStatistics> otherStatisticsStateGroupList = createOtherStatisticsStateGroupList(startDate, stisticsActiveState, companyMap);
        orderTourReceivedStatisticsList.addAll(otherStatisticsStateGroupList);
        //保存
        StatisticsStatusEnum.insertReceivedStatisticsBatch(orderTourReceivedStatisticsList,mapper);

        return orderTourReceivedStatisticsList;
    }

    /**
     *创建未支付
     * @param startDate 统计的时间
     * @param noPayOrdersMap 未支付单map
     * @param companyMap 公司map
     */
    private List<OrderTourReceivedStatistics> createNoPayOrderTourReceivedStatisticsListList(Date startDate, Map<String, List<OrderDTO>> noPayOrdersMap, Map<Integer, String> companyMap) {

        List<OrderTourReceivedStatistics> orderTourReceivedStatisticsList = new ArrayList<>();
        if (noPayOrdersMap == null || noPayOrdersMap.isEmpty()) {
            return orderTourReceivedStatisticsList;
        }
        //遍历未支付单
        Set<Map.Entry<String, List<OrderDTO>>> noPayOrderSet = noPayOrdersMap.entrySet();
        for (Map.Entry<String, List<OrderDTO>> noPayOrderEntry : noPayOrderSet) {
            String noPayOrderStateGroup = noPayOrderEntry.getKey();
            List<OrderDTO> noPayOrders = noPayOrderEntry.getValue();
            //创建旅游统计对象并设置默认值
            OrderTourReceivedStatistics orderTourReceivedStatistics = StatisticsStatusEnum.wrapStatisticsObject(startDate, noPayOrderStateGroup, companyMap, new OrderTourReceivedStatistics());
            //订单总金额
            BigDecimal totalNoPayAmount = noPayOrders.stream().map(OrderDTO::getRealAmount).reduce(BigDecimal.ZERO,BigDecimal::add);
            orderTourReceivedStatistics.setTotalQuantity(noPayOrders.size());
            orderTourReceivedStatistics.setTotalAmount(totalNoPayAmount);
            orderTourReceivedStatisticsList.add(orderTourReceivedStatistics);
        }
        return orderTourReceivedStatisticsList;
    }

    /**
     * 创建剩余状态数据
     *
     * @param startDate             时间
     * @param statisticsStateGroups 状态组合 集合
     * @param companyMap            公司ids
     * @return
     */
    private List<OrderTourReceivedStatistics> createOtherStatisticsStateGroupList(Date startDate,
                                                                                  List<String> statisticsStateGroups,
                                                                                  Map<Integer, String> companyMap) {
        List<OrderTourReceivedStatistics> orderTourReceivedStatisticsList = new ArrayList<>();
        //获取剩余状态组合
        List<Integer> companyIds = Objects.isNull(companyMap) ? Collections.EMPTY_LIST : Lists.newArrayList(companyMap.keySet());
        List<String> otherStatisticsStateGroup = StatisticsStatusEnum.getOtherStatisticsStateGroup(companyIds, statisticsStateGroups);
        //创建租车统计克隆对象
        OrderTourReceivedStatistics orderTourReceivedStatistics = new OrderTourReceivedStatistics();
        //统计对象的生成
        otherStatisticsStateGroup.stream().peek(stateGroup -> {
            OrderTourReceivedStatistics orderTourReceivedStatisticsClone = StatisticsStatusEnum.wrapStatisticsObject(startDate, stateGroup, companyMap, ObjectUtil.cloneByStream(orderTourReceivedStatistics));
            orderTourReceivedStatisticsList.add(orderTourReceivedStatisticsClone);
        }).count();
        return orderTourReceivedStatisticsList;
    }
}