package com.xxfc.platform.order.biz;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.google.common.collect.Lists;
import com.xxfc.platform.order.bo.CompanyPerformanceBo;
import com.xxfc.platform.order.contant.enumerate.*;
import com.xxfc.platform.order.entity.*;
import com.xxfc.platform.order.mapper.OrderReceivedStatisticsMapper;
import com.xxfc.platform.order.pojo.dto.CompanyPerformanceFindDTO;
import com.xxfc.platform.order.pojo.dto.OrderReceivedStatisticsFindDTO;
import com.xxfc.platform.order.pojo.vo.OrderReceivedStatisticsBaseVo;
import com.xxfc.platform.order.pojo.vo.OrderReceivedStatisticsVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;

/**
 * 全部订单统计
 *
 * @author libin
 * @email 18178966185@163.com
 * @date 2019-11-08 18:03:42
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class OrderReceivedStatisticsBiz extends BaseBiz<OrderReceivedStatisticsMapper, OrderReceivedStatistics> implements InitializingBean {
    private final OrderRentVehicleReceivedStatisticsBiz orderRentVehicleReceivedStatisticsBiz;
    private final OrderTourReceivedStatisticsBiz orderTourReceivedStatisticsBiz;
    private final OrderMemberReceivedStatisticsBiz orderMemberReceivedStatisticsBiz;

    private List<String> orderSigns;
    private List<String> orderMemberSigns;
    private List<String> orderRentVehicleSigns;
    private List<String> orderTourSigns;
    private Map<String, String> signAndDescMap;
    private final ThreadPoolTaskExecutor executor;


    /**
     * 公司业绩（按日统计）
     *
     * @param companyPerformanceFindDTO
     * @return
     */
    public PageDataVO<CompanyPerformanceBo> selectCompanyPerformanceWithDayPage(CompanyPerformanceFindDTO companyPerformanceFindDTO) {
        List<CompanyPerformanceBo> companyPerformanceBos = mapper.selectCompanyPerformanceWithDay(companyPerformanceFindDTO);
        PageDataVO<CompanyPerformanceBo> pageDataVO = new PageDataVO<>();
        pageDataVO.setData(companyPerformanceBos);
        return pageDataVO;
       /* return PageDataVO.pageInfo(companyPerformanceFindDTO.getPage(), companyPerformanceFindDTO.getLimit(),
                () -> mapper.selectCompanyPerformanceWithDay(companyPerformanceFindDTO));*/
    }

    public List<CompanyPerformanceBo> selectCompanyPerformanceWithDay(CompanyPerformanceFindDTO companyPerformanceFindDTO) {
        List<CompanyPerformanceBo> companyPerformanceBos = mapper.selectCompanyPerformanceWithDay(companyPerformanceFindDTO);
        return CollectionUtils.isEmpty(companyPerformanceBos) ? Collections.EMPTY_LIST : companyPerformanceBos;
    }

    /**
     * 公司业绩（按月统计）
     *
     * @param companyPerformanceFindDTO
     * @return
     */
    public PageDataVO<CompanyPerformanceBo> selectCompanyPerformanceWithMonthPage(CompanyPerformanceFindDTO companyPerformanceFindDTO) {
   /*     return PageDataVO.pageInfo(companyPerformanceFindDTO.getPage(), companyPerformanceFindDTO.getLimit(),
                () -> mapper.selectCompanyPerformanceWithMonth(companyPerformanceFindDTO));*/
        List<CompanyPerformanceBo> companyPerformanceBos = mapper.selectCompanyPerformanceWithMonth(companyPerformanceFindDTO);
        PageDataVO<CompanyPerformanceBo> pageDataVO = new PageDataVO<>();
        pageDataVO.setData(companyPerformanceBos);
        return pageDataVO;
    }

    public List<CompanyPerformanceBo> selectCompanyPerformanceWithMonth(CompanyPerformanceFindDTO companyPerformanceFindDTO) {
        List<CompanyPerformanceBo> companyPerformanceBos = mapper.selectCompanyPerformanceWithMonth(companyPerformanceFindDTO);
        return CollectionUtils.isEmpty(companyPerformanceBos) ? Collections.EMPTY_LIST : companyPerformanceBos;
    }

    /**
     * 公司业绩（按周统计）
     *
     * @param companyPerformanceFindDTO
     * @return
     */
    public PageDataVO<CompanyPerformanceBo> selectCompanyPerformanceWithWeekPage(CompanyPerformanceFindDTO companyPerformanceFindDTO) {
        /*return PageDataVO.pageInfo(companyPerformanceFindDTO.getPage(), companyPerformanceFindDTO.getLimit(),
                () -> mapper.selectCompanyPerformanceWithWeek(companyPerformanceFindDTO));*/
        List<CompanyPerformanceBo> companyPerformanceBos = mapper.selectCompanyPerformanceWithWeek(companyPerformanceFindDTO);
        PageDataVO<CompanyPerformanceBo> pageDataVO = new PageDataVO<>();
        pageDataVO.setData(companyPerformanceBos);
        return pageDataVO;
    }

    public List<CompanyPerformanceBo> selectCompanyPerformanceWithWeek(CompanyPerformanceFindDTO companyPerformanceFindDTO) {
        List<CompanyPerformanceBo> companyPerformanceBos = mapper.selectCompanyPerformanceWithWeek(companyPerformanceFindDTO);
        return CollectionUtils.isEmpty(companyPerformanceBos) ? Collections.EMPTY_LIST : companyPerformanceBos;
    }

    /**
     * 订单统计数据导出
     *
     * @param orderReceivedStatisticsFindDTO
     * @param outputStream
     */
    public void exportOrderReceivedStatisticsData(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO, ServletOutputStream outputStream) throws IOException {
        Map<String, List<OrderReceivedStatisticsVo>> orderReceivedStatisticsResult = getOrderReceivedStatisticsResult(orderReceivedStatisticsFindDTO);

        XSSFWorkbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("订单统计");
        Row headerRow = sheet.createRow(0);
        //标题样式
        CellStyle headerCellStyle = createCellStyle(workbook, true);
        //创建标题
        createHeader(headerRow, headerCellStyle, orderReceivedStatisticsFindDTO.getStatisticalSigns());
        //创建数据样式
        CellStyle dataCellStyle = createCellStyle(workbook, false);
        createData(orderReceivedStatisticsResult, orderReceivedStatisticsFindDTO.getStatisticalWay(), orderReceivedStatisticsFindDTO.getStatisticalSigns(), sheet, 1, dataCellStyle);
        workbook.write(outputStream);
        workbook.close();
    }

    private void createData(Map<String, List<OrderReceivedStatisticsVo>> data, Integer statisticalWay, List<String> signs, Sheet sheet, int rowIndex, CellStyle cellStyle) {
        //自然排序
        Collections.sort(signs);
        int size = data.get(signs.get(0)).size();
        for (int i = 0; i < size; i++) {
            Row dataRow = sheet.createRow(rowIndex++);
            Cell firstCell = dataRow.createCell(0);
            firstCell.setCellStyle(cellStyle);
            for (int cellIndex = 1; cellIndex <= signs.size(); cellIndex++) {
                Cell dataCell = dataRow.createCell(cellIndex);
                dataCell.setCellStyle(cellStyle);
                String sign = signs.get(cellIndex - 1);
                List<OrderReceivedStatisticsVo> orderReceivedStatisticsVos = data.get(sign);
                if (ReceivedStatisticsEnum.DAY.getWayCode() == statisticalWay){
                    orderReceivedStatisticsVos.sort(Comparator.comparing(OrderReceivedStatisticsVo::getDate));
                }

                if (ReceivedStatisticsEnum.WEEK.getWayCode() == statisticalWay){
                    orderReceivedStatisticsVos.sort(Comparator.comparing(OrderReceivedStatisticsVo::getWeekOfYear));
                }

                if (ReceivedStatisticsEnum.MONTH.getWayCode() == statisticalWay){
                    orderReceivedStatisticsVos.sort(Comparator.comparing(OrderReceivedStatisticsVo::getMonth));

                }
                if (CollectionUtils.isEmpty(orderReceivedStatisticsVos) || i > orderReceivedStatisticsVos.size()) {
                    continue;
                }
                OrderReceivedStatisticsVo orderReceivedStatisticsVo = orderReceivedStatisticsVos.get(i);
                if (sign.endsWith("q")) {
                    dataCell.setCellValue(String.valueOf(orderReceivedStatisticsVo.getOrderNum()));
                }
                if (sign.endsWith("a")) {
                    dataCell.setCellValue(String.valueOf(orderReceivedStatisticsVo.getOrderAmount()));
                }
                if (cellIndex == 1) {
                    if (ReceivedStatisticsEnum.DAY.getWayCode() == statisticalWay) {
                        firstCell.setCellValue(DateUtil.format(orderReceivedStatisticsVo.getDate(), "yyyy.MM.dd"));
                    }
                    if (ReceivedStatisticsEnum.WEEK.getWayCode() == statisticalWay) {
                        Calendar cal = Calendar.getInstance();
                        cal.setFirstDayOfWeek(Calendar.MONDAY);
                        cal.set(Calendar.YEAR, Integer.valueOf(orderReceivedStatisticsVo.getYear()));
                        cal.set(Calendar.WEEK_OF_YEAR, Integer.valueOf(orderReceivedStatisticsVo.getWeekOfYear().replace("" + orderReceivedStatisticsVo.getYear(), "")));
                        cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
                        Date startDate = cal.getTime();
                        cal.add(Calendar.DAY_OF_WEEK, 6);
                        Date endDate = cal.getTime();
                        firstCell.setCellValue(String.format("%s~%s", DateUtil.format(startDate,"yyyy-MM-dd"), DateUtil.format(endDate,"yyyy-MM-dd")));
                    }
                    if (ReceivedStatisticsEnum.MONTH.getWayCode() == statisticalWay) {
                        StringBuilder sb = new StringBuilder(orderReceivedStatisticsVo.getMonth());
                        sb.insert(4, ".");
                        firstCell.setCellValue(sb.toString());
                    }
                }
            }
        }
    }

    private void createHeader(Row row, CellStyle cellStyle, List<String> signs) {
        //自然排序
        Collections.sort(signs);
        Cell firstCell = row.createCell(0);
        firstCell.setCellValue("时间");
        firstCell.setCellStyle(cellStyle);
        for (int i = 1; i <= signs.size(); i++) {
            Cell cell = row.createCell(i);
            cell.setCellValue(signAndDescMap.get(signs.get(i - 1)));
            cell.setCellStyle(cellStyle);
        }
    }

    private CellStyle createCellStyle(Workbook workbook, boolean bold) {
        CellStyle cellStyle = workbook.createCellStyle();
        Font font = createFont(workbook, bold);
        cellStyle.setFont(font);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        return cellStyle;
    }

    private Font createFont(Workbook workbook, boolean bold) {
        Font font = workbook.createFont();
        font.setFontName("黑体");
        font.setBold(bold);
        font.setBold(true);
        return font;
    }

    /**
     * 获取订单统计数据
     *
     * @param orderReceivedStatisticsFindDTO
     * @return
     */
    public Map<String, List<OrderReceivedStatisticsVo>> getOrderReceivedStatisticsResult(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO) {
        Map<String, List<OrderReceivedStatisticsVo>> resultMap = new HashMap<>();
        List<String> statisticalSigns = orderReceivedStatisticsFindDTO.getStatisticalSigns();
        CountDownLatch latch = new CountDownLatch(4);
        try {
        executor.execute(()->{
            //订单统计
            Map<String, List<OrderReceivedStatisticsVo>> orderReceivedStatisticsMap = orderReceivedStatistics(orderReceivedStatisticsFindDTO, statisticalSigns);
            resultMap.putAll(orderReceivedStatisticsMap);
            latch.countDown();
        });

        executor.execute(()->{
            //租车订单统计
            Map<String, List<OrderReceivedStatisticsVo>> orderRentVehicleReceivedStatisticsMap = orderRentVehicleRceicedStatistics(orderReceivedStatisticsFindDTO, statisticalSigns);
            resultMap.putAll(orderRentVehicleReceivedStatisticsMap);
            latch.countDown();
        });

        executor.execute(()->{
            //旅游订单统计
            Map<String, List<OrderReceivedStatisticsVo>> orderTourReceivedStatisticsMap = orderTourReceivedStatistcs(orderReceivedStatisticsFindDTO, statisticalSigns);
            resultMap.putAll(orderTourReceivedStatisticsMap);
            latch.countDown();
        });

        executor.execute(()->{
            //会员订单统计
            Map<String, List<OrderReceivedStatisticsVo>> orderMemberReceivedStatisticsMap = orderMemberReceivedStatistics(orderReceivedStatisticsFindDTO, statisticalSigns);
            resultMap.putAll(orderMemberReceivedStatisticsMap);
            latch.countDown();
        });

            latch.await();
        } catch (Exception e) {
            log.error("订单概况统计失败【{}】",e);
        }
        return resultMap;
    }

    /**
     * 统计汇总
     *
     * @param orderMemberReceivedStatistics
     * @param orderTourReceivedStatistics
     * @param orderRentVehicleReceivedStatistics
     */
    public void orderReceivedStatistics(List<OrderMemberReceivedStatistics> orderMemberReceivedStatistics,
                                        List<OrderTourReceivedStatistics> orderTourReceivedStatistics,
                                        List<OrderRentVehicleReceivedStatistics> orderRentVehicleReceivedStatistics, Date date) {

        List<OrderReceivedStatistics> orderReceivedStatisticsList = new ArrayList<>();
        Map<String, List<OrderMemberReceivedStatistics>> memberMap = orderMemberReceivedStatistics.stream().collect(Collectors.groupingBy(OrderMemberReceivedStatistics::getStateGroup, Collectors.toList()));
        Map<String, List<OrderTourReceivedStatistics>> tourMap = orderTourReceivedStatistics.stream().collect(Collectors.groupingBy(OrderTourReceivedStatistics::getStateGroup, Collectors.toList()));
        Map<String, List<OrderRentVehicleReceivedStatistics>> rentVehicleMap = orderRentVehicleReceivedStatistics.stream().collect(Collectors.groupingBy(OrderRentVehicleReceivedStatistics::getStateGroup, Collectors.toList()));


        OrderReceivedStatistics orderReceivedStatistics = new OrderReceivedStatistics();
        Set<Map.Entry<String, List<OrderRentVehicleReceivedStatistics>>> rentVehicleSet = rentVehicleMap.entrySet();
        for (Map.Entry<String, List<OrderRentVehicleReceivedStatistics>> rentVehicleEntry : rentVehicleSet) {
            try {
                String stateGroup = rentVehicleEntry.getKey();
                List<OrderRentVehicleReceivedStatistics> rentVehicleEntryValue = rentVehicleEntry.getValue();
                //创建默认的订单统计对象并设置默认值
                OrderReceivedStatistics orderReceivedStatisticsClone = StatisticsStatusEnum.wrapStatisticsObject(date, stateGroup, Collections.EMPTY_MAP, ObjectUtil.clone(orderReceivedStatistics));
                //租车单
                OrderRentVehicleReceivedStatistics orderRentVehicle = rentVehicleEntryValue.get(0);
                //会员单
                OrderMemberReceivedStatistics orderMember = memberMap.get(stateGroup).get(0);
                //旅游单
                OrderTourReceivedStatistics orderTour = tourMap.get(stateGroup).get(0);
                //公司id
                orderReceivedStatisticsClone.setCompanyId(orderRentVehicle.getCompanyId());
                //公司名称
                orderReceivedStatisticsClone.setCompanyName(orderRentVehicle.getCompanyName());
                //押金
                orderReceivedStatisticsClone.setDepositAmount(orderRentVehicle.getDepositAmount());
                //退款押金
                orderReceivedStatisticsClone.setDepositRefundAmount(orderRentVehicle.getDepositRefundAmount());
                //定损
                orderReceivedStatisticsClone.setLossSpecifiedAmount(orderRentVehicle.getLossSpecifiedAmount());
                //违章
                orderReceivedStatisticsClone.setBreakRulesRegulationAmount(orderRentVehicle.getBreakRulesRegulationAmount());
                //免赔退款金额
                orderReceivedStatisticsClone.setNoDeductibleRefundAmount(orderRentVehicle.getNoDeductibleRefundAmount());
                //免赔金额
                orderReceivedStatisticsClone.setNoDeductibleAmount(orderRentVehicle.getNoDeductibleAmount());

                //旅游订单总额
                orderReceivedStatisticsClone.setTravelAmount(orderTour.getTotalAmount());
                orderReceivedStatisticsClone.setTravelRefundAmount(orderTour.getOrderRefundAmount());
                //会员订单总额
                orderReceivedStatisticsClone.setMemberAmount(orderMember.getTotalAmount());
                orderReceivedStatisticsClone.setMemberRefundAmout(orderMember.getOrderRefundAmount());
                //租车订单总额
                orderReceivedStatisticsClone.setRentVehicleAmount(orderRentVehicle.getTotalAmount());
                orderReceivedStatisticsClone.setRentVehicleRefundAmount(orderRentVehicle.getOrderRefundAmount());
                //合计订单总额
                BigDecimal totalAmount = orderRentVehicle.getTotalAmount().add(orderTour.getTotalAmount()).add(orderMember.getTotalAmount());
                //合计订单退款总额
                BigDecimal totalRefundAmount = orderRentVehicle.getOrderRefundAmount().add(orderTour.getOrderRefundAmount()).add(orderMember.getOrderRefundAmount());
                //合计订单违约金
                BigDecimal lateFeeAmount = orderRentVehicle.getLateFeeAmount().add(orderTour.getLateFeeAmount()).add(orderMember.getLateFeeAmount());
                //合计额外费用
                BigDecimal totalExtraAmount = orderRentVehicle.getExtraAmount().add(orderMember.getExtraAmount()).add(orderTour.getExtraAmount());
                //会员订单量
                orderReceivedStatisticsClone.setMemberQuantity(orderMember.getTotalQuantity());
                //旅游订单量
                orderReceivedStatisticsClone.setTravelQuantity(orderTour.getTotalQuantity());
                //租车订单量
                orderReceivedStatisticsClone.setRentVehicleQuantity(orderRentVehicle.getTotalQuantity());
                //合计订单量
                Integer totalQuantity = orderRentVehicle.getTotalQuantity() + (orderTour.getTotalQuantity()) + orderMember.getTotalQuantity();

                orderReceivedStatisticsClone.setExtraAmount(totalExtraAmount);
                orderReceivedStatisticsClone.setLateFeeAmount(lateFeeAmount);
                orderReceivedStatisticsClone.setTotalAmount(totalAmount);
                orderReceivedStatisticsClone.setOrderRefundAmount(totalRefundAmount);
                orderReceivedStatisticsClone.setTotalQuantity(totalQuantity);
                orderReceivedStatisticsList.add(orderReceivedStatisticsClone);
            }catch (Exception ex){
                log.error("当前状态组合【{}】===日期【{}】",rentVehicleEntry.getKey(),rentVehicleEntry.getValue().get(0).getDate());
            }
        }
        //保存
        StatisticsStatusEnum.insertReceivedStatisticsBatch(orderReceivedStatisticsList, mapper);
    }

    /**
     * 订单统计
     *
     * @param orderReceivedStatisticsFindDTO
     * @param statisticalSigns
     * @return
     */
    private Map<String, List<OrderReceivedStatisticsVo>> orderReceivedStatistics(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO, List<String> statisticalSigns) {
        if (CollectionUtil.containsAny(statisticalSigns, orderSigns)) {
            List<OrderReceivedStatistics> orderReceivedStatisticsList = new ArrayList<>();
             if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.DAY.getWayCode()){
                 orderReceivedStatisticsList = selectOrderReceivedStatisticsByDate(orderReceivedStatisticsFindDTO);
             }
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.MONTH.getWayCode()){
                orderReceivedStatisticsList = selectOrderReceivedStatisticsByMonth(orderReceivedStatisticsFindDTO);
            }
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.WEEK.getWayCode()){
                orderReceivedStatisticsList = selectOrderReceivedStatisticsByWeekOfYear(orderReceivedStatisticsFindDTO);
            }
            //日 周 月  的统计
            Map<Object, List<OrderReceivedStatisticsBase>> orderstatisticsMap = ReceivedStatisticsEnum.orderstatistics(orderReceivedStatisticsList, orderReceivedStatisticsFindDTO.getStatisticalWay());
            //统计项
            Map<String, List<OrderReceivedStatisticsVo>> orderReceivedStatisticsMap = OrderReceivedStatisticsSignEnum.orderReceivedStatistics(orderstatisticsMap, retainAll(orderSigns, statisticalSigns));
            return orderReceivedStatisticsMap.isEmpty() ? Collections.EMPTY_MAP : orderReceivedStatisticsMap;
        }
        return Collections.EMPTY_MAP;
    }

    /**
     * 租车统计
     *
     * @param orderReceivedStatisticsFindDTO
     * @param statisticalSigns
     * @return
     */
    private Map<String, List<OrderReceivedStatisticsVo>> orderRentVehicleRceicedStatistics(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO, List<String> statisticalSigns) {
        if (CollectionUtil.containsAny(statisticalSigns, orderRentVehicleSigns)) {
            List<OrderRentVehicleReceivedStatistics> orderRentVehicleReceivedStatisticsList = new ArrayList<>();
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.DAY.getWayCode()){
                orderRentVehicleReceivedStatisticsList =  orderRentVehicleReceivedStatisticsBiz.selectOrderReceivedStatisticsGroupByDate(orderReceivedStatisticsFindDTO);
            }
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.MONTH.getWayCode()){
                orderRentVehicleReceivedStatisticsList =  orderRentVehicleReceivedStatisticsBiz.selectOrderReceivedStatisticsGroupByMonth(orderReceivedStatisticsFindDTO);
            }
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.WEEK.getWayCode()){
                orderRentVehicleReceivedStatisticsList =  orderRentVehicleReceivedStatisticsBiz.selectOrderReceivedStatisticsGroupByWeekOfYear(orderReceivedStatisticsFindDTO);
            }
            //日 周 月  的统计
            Map<Object, List<OrderReceivedStatisticsBase>> orderRentVehiclestatisticsMap = ReceivedStatisticsEnum.orderstatistics(orderRentVehicleReceivedStatisticsList, orderReceivedStatisticsFindDTO.getStatisticalWay());
            //统计项
            Map<String, List<OrderReceivedStatisticsVo>> orderRentVehicleReceivedStatisticsMap = OrderRentVehicleReceivedStatisticsSignEnum.orderMemberstatisticsMap(orderRentVehiclestatisticsMap, retainAll(orderRentVehicleSigns, statisticalSigns));
            return orderRentVehicleReceivedStatisticsMap.isEmpty() ? Collections.EMPTY_MAP : orderRentVehicleReceivedStatisticsMap;
        }
        return Collections.EMPTY_MAP;
    }

    /**
     * 旅游统计
     *
     * @param orderReceivedStatisticsFindDTO
     * @param statisticalSigns
     * @return
     */
    private Map<String, List<OrderReceivedStatisticsVo>> orderTourReceivedStatistcs(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO, List<String> statisticalSigns) {
        if (CollectionUtil.containsAny(statisticalSigns, orderTourSigns)) {

            List<OrderTourReceivedStatistics> orderTourReceivedStatisticsList = new ArrayList<>();
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.DAY.getWayCode()){
                orderTourReceivedStatisticsList =  orderTourReceivedStatisticsBiz.selectOrderReceivedStatisticsGroupByDate(orderReceivedStatisticsFindDTO);
            }
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.MONTH.getWayCode()){
                orderTourReceivedStatisticsList =  orderTourReceivedStatisticsBiz.selectOrderReceivedStatisticsGroupByMonth(orderReceivedStatisticsFindDTO);
            }
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.WEEK.getWayCode()){
                orderTourReceivedStatisticsList = orderTourReceivedStatisticsBiz.selectOrderReceivedStatisticsGroupByWeekOfYear(orderReceivedStatisticsFindDTO);
            }
            //日 周 月  的统计
            Map<Object, List<OrderReceivedStatisticsBase>> orderTourstatisticsMap = ReceivedStatisticsEnum.orderstatistics(orderTourReceivedStatisticsList, orderReceivedStatisticsFindDTO.getStatisticalWay());
            //统计项
            Map<String, List<OrderReceivedStatisticsVo>> orderTourReceivedStatisticsMap = OrderTourReceivedStatisticsSignEnum.orderMemberstatisticsMap(orderTourstatisticsMap, retainAll(orderTourSigns, statisticalSigns));
            return orderTourReceivedStatisticsMap.isEmpty() ? Collections.EMPTY_MAP : orderTourReceivedStatisticsMap;
        }
        return Collections.EMPTY_MAP;
    }

    /**
     * 会员统计
     *
     * @param orderReceivedStatisticsFindDTO
     * @param statisticalSigns
     * @return
     */
    private Map<String, List<OrderReceivedStatisticsVo>> orderMemberReceivedStatistics(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO, List<String> statisticalSigns) {
        if (CollectionUtil.containsAny(statisticalSigns, orderMemberSigns)) {

            List<OrderMemberReceivedStatistics> orderMemberReceivedStatisticsList = new ArrayList<>();
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.DAY.getWayCode()){
                orderMemberReceivedStatisticsList = orderMemberReceivedStatisticsBiz.selectOrderReceivedStatisticsGroupByDate(orderReceivedStatisticsFindDTO);
            }
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.MONTH.getWayCode()){
                orderMemberReceivedStatisticsList = orderMemberReceivedStatisticsBiz.selectOrderReceivedStatisticsGroupByMonth(orderReceivedStatisticsFindDTO);
            }
            if (orderReceivedStatisticsFindDTO.getStatisticalWay()==ReceivedStatisticsEnum.WEEK.getWayCode()){
                orderMemberReceivedStatisticsList = orderMemberReceivedStatisticsBiz.selectOrderReceivedStatisticsGroupByWeekOfYear(orderReceivedStatisticsFindDTO);
            }
            //日 周 月  的统计
            Map<Object, List<OrderReceivedStatisticsBase>> orderMemberstatisticsMap = ReceivedStatisticsEnum.orderstatistics(orderMemberReceivedStatisticsList, orderReceivedStatisticsFindDTO.getStatisticalWay());
            //统计项
            Map<String, List<OrderReceivedStatisticsVo>> orderMemberReceivedStatisticsMap = OrderMemberReceivedStatisticsSignEnum.orderMemberstatisticsMap(orderMemberstatisticsMap, retainAll(orderMemberSigns, statisticalSigns));
            return orderMemberReceivedStatisticsMap.isEmpty() ? Collections.EMPTY_MAP : orderMemberReceivedStatisticsMap;
        }
        return Collections.EMPTY_MAP;
    }

    private List<OrderReceivedStatistics> selectOrderReceivedStatisticsByDate(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO) {
        return mapper.selectOrderReceivedStatisticsDateList(orderReceivedStatisticsFindDTO);
    }
    private List<OrderReceivedStatistics> selectOrderReceivedStatisticsByMonth(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO) {
        return mapper.selectOrderReceivedStatisticsMonthList(orderReceivedStatisticsFindDTO);
    }
    private List<OrderReceivedStatistics> selectOrderReceivedStatisticsByWeekOfYear(OrderReceivedStatisticsFindDTO orderReceivedStatisticsFindDTO) {
        return mapper.selectOrderReceivedStatisticsWeekOfYearList(orderReceivedStatisticsFindDTO);
    }

    public int selectCountByCondition(CompanyPerformanceFindDTO companyPerformanceFindDTO) {
        if (companyPerformanceFindDTO.getStatisticalWay() == ReceivedStatisticsEnum.DAY.getWayCode()) {
            return mapper.selectCountByDate(companyPerformanceFindDTO);
        }
        if (companyPerformanceFindDTO.getStatisticalWay() == ReceivedStatisticsEnum.MONTH.getWayCode()) {
            return mapper.selectCountByMonth(companyPerformanceFindDTO);
        }
        if (companyPerformanceFindDTO.getStatisticalWay() == ReceivedStatisticsEnum.WEEK.getWayCode()) {
            return mapper.selectCountByWeekOfYear(companyPerformanceFindDTO);
        }
        return 0;
    }

    /**
     * 取两个集合的交集
     *
     * @param source
     * @param target
     * @return
     */
    private List<String> retainAll(List<String> source, List<String> target) {
        ArrayList<String> sourceBak = Lists.newArrayList(source);
        sourceBak.retainAll(target);
        return sourceBak;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        signAndDescMap = new HashMap<>();
        orderSigns = EnumSet.allOf(OrderReceivedStatisticsSignEnum.class).stream().map(OrderReceivedStatisticsSignEnum::getSign).collect(Collectors.toList());
        Map<String, String> orderSignAndDescMap = EnumSet.allOf(OrderReceivedStatisticsSignEnum.class).stream().collect(Collectors.toMap(OrderReceivedStatisticsSignEnum::getSign, OrderReceivedStatisticsSignEnum::getDesc));
        signAndDescMap.putAll(orderSignAndDescMap);
        orderMemberSigns = EnumSet.allOf(OrderMemberReceivedStatisticsSignEnum.class).stream().map(OrderMemberReceivedStatisticsSignEnum::getSign).collect(Collectors.toList());
        Map<String, String> orderMemberSignAndDescMap = EnumSet.allOf(OrderMemberReceivedStatisticsSignEnum.class).stream().collect(Collectors.toMap(OrderMemberReceivedStatisticsSignEnum::getSign, OrderMemberReceivedStatisticsSignEnum::getDesc));
        signAndDescMap.putAll(orderMemberSignAndDescMap);
        orderRentVehicleSigns = EnumSet.allOf(OrderRentVehicleReceivedStatisticsSignEnum.class).stream().map(OrderRentVehicleReceivedStatisticsSignEnum::getSign).collect(Collectors.toList());
        Map<String, String> orderRentVehicleSignAndDescMap = EnumSet.allOf(OrderRentVehicleReceivedStatisticsSignEnum.class).stream().collect(Collectors.toMap(OrderRentVehicleReceivedStatisticsSignEnum::getSign, OrderRentVehicleReceivedStatisticsSignEnum::getDesc));
        signAndDescMap.putAll(orderRentVehicleSignAndDescMap);
        orderTourSigns = EnumSet.allOf(OrderTourReceivedStatisticsSignEnum.class).stream().map(OrderTourReceivedStatisticsSignEnum::getSign).collect(Collectors.toList());
        Map<String, String> orderTourSignAndDescMap = EnumSet.allOf(OrderTourReceivedStatisticsSignEnum.class).stream().collect(Collectors.toMap(OrderTourReceivedStatisticsSignEnum::getSign, OrderTourReceivedStatisticsSignEnum::getDesc));
        signAndDescMap.putAll(orderTourSignAndDescMap);
    }


    public List<OrderReceivedStatisticsBaseVo> findOrderReceivedStatisticsByDate(Date startDate, Date endDate) {
         List<OrderReceivedStatistics> orderReceivedStatisticsList = mapper.findOrderReceivedStatisticsByDate(startDate,endDate);
         if (CollectionUtils.isEmpty(orderReceivedStatisticsList)){
             return Collections.emptyList();
         }
        return JSON.parseObject(JSON.toJSONString(orderReceivedStatisticsList),new TypeReference<List<OrderReceivedStatisticsBaseVo>>(){});
    }

}