package cn.com.ty.lift.batch.applet.service;

import cn.com.ty.lift.batch.applet.dao.mapper.LiftDataMapper;
import cn.com.ty.lift.batch.applet.dao.model.LiftDataModel;
import cn.com.ty.lift.batch.applet.dao.model.request.LiftDataRequest;
import cn.com.ty.lift.batch.applet.dao.model.response.RegionLiftResponse;
import cn.com.ty.lift.batch.applet.dao.model.response.RegionLiftResponseTotal;
import cn.com.ty.lift.batch.applet.util.DataStatisticsUtil;
import cn.com.ty.lift.common.constants.ApiConstants;
import cn.com.ty.lift.common.constants.CommonEnum;
import cn.com.ty.lift.common.utils.ProjectUtils;
import cn.com.xwy.boot.web.dto.RestResponse;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author huangyuan
 * @date 2020/2/3
 * @description
 */
@Service
public class LiftDataService {

    @Resource
    private LiftDataMapper liftDataMapper;

    /**
     * @param
     * @return
     * @description 获取电梯数据
     * @date 2020/2/7 12:01 下午
     */
    private List<LiftDataModel> getLiftDataModels(LiftDataRequest liftDataRequest) {
        List<LiftDataModel> liftDataModelList = liftDataMapper.getLiftDataList(liftDataRequest);
        //设置电梯状态:1:新增, 3:丢失
        if (liftDataModelList != null && liftDataModelList.size() > 0) {
            liftDataModelList.forEach(entry -> {
                //默认状态为新增
                entry.setLiftStatus(1);
                //电梯停保
                if (CommonEnum.LiftStatus.STOP_INSURANCE.getCode().equals(entry.getLiftCompanyStatus())) {
                    entry.setLiftStatus(3);
                    entry.setLostTime(entry.getUpdateTime());
                } else if (CommonEnum.ProjectStatus.STOP_SERVICE.getCode().equals(entry.getProjectStatus())) {
                    entry.setLiftStatus(3);
                    entry.setLostTime(entry.getProjectEndTime());
                }
            });
        }
        return liftDataModelList;
    }

    /**
     * @param
     * @return
     * @description 获取不同状态下的电梯数量 1:新增 2:在保 3:丢失
     * @date 2020/2/5 12:28 下午
     */
    public RestResponse liftOverView(LiftDataRequest liftDataRequest) {
        Map<Integer, List<Long>> liftStatusToNums = initLiftStatusToNums(liftDataRequest);
        //从redis中获取当前公司总的电梯信息
        List<LiftDataModel> companyTotalLiftDataList = getLiftDataModels(liftDataRequest);
        System.out.println(liftDataRequest.getStartTimeDate());
        //获取当前公司时间段之内的电梯信息
        List<LiftDataModel> liftDataModelList = getNewLiftData(companyTotalLiftDataList, liftDataRequest);
        if ((companyTotalLiftDataList != null && companyTotalLiftDataList.size() > 0)) {
            //获取传递起始时间之前的电梯信息
            List<LiftDataModel> beforeLiftDataList = companyTotalLiftDataList.stream()
                    //新建时间在起始时间之前的
                    .filter(liftDataModel -> {
                        if (liftDataModel.getConnectTime() != null) {
                            return liftDataModel.getConnectTime().isBefore(liftDataRequest.getStartTimeDate());
                        }
                        return true;
                    }).collect(Collectors.toList());
            //时间段之前的电梯台数,去掉丢失的电梯
            long beforeLiftTotalNum = 0L;
            if (beforeLiftDataList.size() > 0) {
                beforeLiftTotalNum = beforeLiftDataList.stream()
                        .filter(liftDataModel -> {
                            if (liftDataModel.getLiftStatus() != null) {
                                return liftDataModel.getLiftStatus() != 3;
                            }
                            return false;
                        }).count();
            }

            //获取时间段内按月份统计的新增电梯数量
//            liftDataModelList = liftDataModelList.stream()
//                    //获取电梯状态是新增的电梯数据
//                    .filter(liftDataModel -> {
//                        if (liftDataModel.getLiftStatus() != null) {
//                            return liftDataModel.getLiftStatus() == 1;
//                        }
//                        return false;
//                    }).sorted(Comparator.comparing(liftDataModel -> {
//                        if (liftDataModel.getConnectTime() != null) {
//                            return liftDataModel.getConnectTime();
//                        }
//                        return LocalDateTime.of(1997, 1, 1, 0, 0, 0);
//                    })).collect(Collectors.toList());
            Map<Integer, Long> monthToNewLiftNums = new HashMap<>();
            if (liftDataModelList.size() > 0) {
                monthToNewLiftNums = liftDataModelList.stream().collect(Collectors.groupingBy(liftDataModel ->
                        DataStatisticsUtil.getMonth(liftDataModel.getConnectTime()), Collectors.counting()));
            }

            //获取时间段内按月份统计的丢失电梯数量
            liftDataModelList = liftDataModelList.stream().filter(liftDataModel -> {
                //获取电梯状态是丢失的电梯数据
                if (liftDataModel.getLiftStatus() != null) {
                    return liftDataModel.getLiftStatus() == 3;
                }
                return false;
                //通过丢失时间顺序排列
            }).sorted(Comparator.comparing(liftDataModel -> {
                if (liftDataModel.getLostTime() != null) {
                    return liftDataModel.getLostTime();
                }
                return LocalDateTime.of(1970, 1, 1, 0, 0, 0);
            })).collect(Collectors.toList());
            Map<Integer, Long> monthToLostLiftNums = liftDataModelList.stream().collect(Collectors.groupingBy(liftDataModel ->
                    DataStatisticsUtil.getMonth(liftDataModel.getLostTime()), Collectors.counting()));
            //设置电梯总览情况
            setLiftOverViewNum(liftDataRequest, liftStatusToNums, beforeLiftTotalNum, monthToNewLiftNums, monthToLostLiftNums);
        }
        return RestResponse.success(ProjectUtils.transReturnMapToStatisticsKVModel(liftStatusToNums),
                ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    /**
     * @param
     * @return
     * @description 站点排名
     * @date 2020/2/5 2:43 下午
     */
    public RestResponse regionRank(LiftDataRequest liftDataRequest) {
        RegionLiftResponseTotal regionLiftResponseTotal = new RegionLiftResponseTotal();
        //区域电梯数据
        List<RegionLiftResponse> regionLiftResponseList = new ArrayList<>();
        List<LiftDataModel> liftDataModelList = getLiftDataModels(liftDataRequest);
        if (liftDataModelList != null && liftDataModelList.size() > 0) {
            regionLiftResponseTotal.setTotalLiftNum(liftDataModelList.size());
            final List<RegionLiftResponse> finalRegionLiftResponseList = new ArrayList<>();
            //将数据转化为 区域名称->电梯数据列表
            Map<String, List<LiftDataModel>> regionNameToLiftData = liftDataModelList.stream()
                    .collect(Collectors.groupingBy(liftDataModel -> {
                        if (liftDataModel.getRegionName() != null) {
                            return liftDataModel.getRegionName();
                        }
                        return "暂无";
                    }));
            //封装区域电梯信息
            regionNameToLiftData.forEach((key, value) -> {
                RegionLiftResponse regionLiftResponse = new RegionLiftResponse();
                regionLiftResponse.setRegionName(key);
                //总电梯数
                long totalLiftNums = value.size();
                //计算新增电梯的数量
                long newLiftNums = value.stream()
                        .filter(a -> a.getLiftStatus() == 1).count();
                regionLiftResponse.setNewLiftNums(newLiftNums);
                //丢失电梯台量
                long lostLiftNums = value.stream()
                        .filter(a -> a.getLiftStatus() == 3).count();
                regionLiftResponse.setLostLiftNums(lostLiftNums);
                //实际总台量
                regionLiftResponse.setTotalLiftNums(totalLiftNums - lostLiftNums);
                finalRegionLiftResponseList.add(regionLiftResponse);
            });
            //通过丢失台量排序并获取前五的数据
            regionLiftResponseList = finalRegionLiftResponseList.stream()
                    .sorted(Comparator.comparing(RegionLiftResponse::getLostLiftNums)).collect(Collectors.toList());
        }
        regionLiftResponseTotal.setRegionLiftResponseList(regionLiftResponseList);
        //通过丢失台量排序获取前五的台量
        return RestResponse.success(regionLiftResponseTotal, ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    /**
     * @param
     * @return
     * @description 项目电梯数量
     * @date 2020/2/5 4:46 下午
     */
    public RestResponse projectLiftNums(LiftDataRequest liftDataRequest) {
        Map<String, Long> projectNameToLiftNums = new HashMap<>();
        //获取时间段内的电梯数量
        List<LiftDataModel> liftDataModelList = getLiftDataModels(liftDataRequest);
        if (liftDataModelList != null && liftDataModelList.size() > 0) {
            //过滤掉丢失的电梯
            liftDataModelList = liftDataModelList.stream()
                    .filter(a -> a.getLiftStatus() != 3).collect(Collectors.toList());
            //通过项目名称给电梯数据分组
            projectNameToLiftNums = liftDataModelList.stream()
                    .collect(Collectors.groupingBy(liftDataModel -> {
                        if (liftDataModel.getProjectName() != null) {
                            return liftDataModel.getProjectName();
                        }
                        return "暂无";
                    }, Collectors.counting()));
        }
        //通过电梯台量给map排序 通过值降序
        projectNameToLiftNums = DataStatisticsUtil.sortByValue(projectNameToLiftNums, true);
        //获取前5的数据
//        Map<String, Long> topFive = new HashMap<>();
//        projectNameToLiftNums.forEach((key, value) -> {
//            if (topFive.size() < 5) {
//                topFive.put(key, value);
//            }
//        });
        return RestResponse.success(ProjectUtils.transReturnMapToStatisticsKVModel(projectNameToLiftNums),
                ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    /**
     * @param
     * @return
     * @description 设置电梯总览情况
     * @date 2020/2/10 11:36 上午
     */
    private void setLiftOverViewNum(LiftDataRequest liftDataRequest, Map<Integer,
            List<Long>> liftStatusToNums, long beforeLiftTotalNum, Map<Integer, Long> monthToNewLiftNums,
                                    Map<Integer, Long> monthToLostLiftNums) {
        int nowMonthValue = LocalDateTime.now().getMonthValue();
        //获取截止时间的月份值
        if (liftDataRequest != null) {
            nowMonthValue = liftDataRequest.getEndTimeDate().getMonthValue();
        }
        //设置不同状态对应的电梯台量
        List<Long> newLiftNums = new ArrayList<>();
        List<Long> onMaintenanceLiftNums = new ArrayList<>();
        List<Long> lostLiftNums = new ArrayList<>();
        for (int i = 1; i <= nowMonthValue; i++) {
            long newLiftNum = DataStatisticsUtil.getLongValue(monthToNewLiftNums.get(i));
            long lostLiftNum = DataStatisticsUtil.getLongValue(monthToLostLiftNums.get(i));
            //计算在保电梯台量:原有电梯台量 + 新增电梯台量 - 丢失电梯台量
            beforeLiftTotalNum = beforeLiftTotalNum + newLiftNum - lostLiftNum;
            newLiftNums.add(newLiftNum);
            onMaintenanceLiftNums.add(beforeLiftTotalNum);
            lostLiftNums.add(lostLiftNum);
        }
        liftStatusToNums.put(1, newLiftNums);
        liftStatusToNums.put(2, onMaintenanceLiftNums);
        liftStatusToNums.put(3, lostLiftNums);
    }

    /**
     * @param liftDataRequest 请求数据
     * @return
     * @description 初始化电梯总览数据
     * @date 2020/2/11 7:15 下午
     */
    private static Map<Integer, List<Long>> initLiftStatusToNums(LiftDataRequest liftDataRequest) {
        Map<Integer, List<Long>> liftStatusToNums = new HashMap<>();
        //时间初始化 默认时间为当前时间
        LocalDateTime time = LocalDateTime.now();
        if (liftDataRequest.getEndTimeDate() != null) {
            time = liftDataRequest.getEndTimeDate();
        }
        //设置不同状态对应的电梯台量
        List<Long> newLiftNums = new ArrayList<>();
        List<Long> onMaintenanceLiftNums = new ArrayList<>();
        List<Long> lostLiftNums = new ArrayList<>();
        for (int i = 1; i <= time.getMonthValue(); i++) {
            newLiftNums.add(0L);
            onMaintenanceLiftNums.add(0L);
            lostLiftNums.add(0L);
        }
        //设置初始值
        liftStatusToNums.put(1, newLiftNums);
        liftStatusToNums.put(2, onMaintenanceLiftNums);
        liftStatusToNums.put(3, lostLiftNums);
        return liftStatusToNums;
    }

    /**
     * @param liftDataRequest 新增电梯
     * @return
     * @description
     * @date 2020/5/23 4:44 下午
     */
    private List<LiftDataModel> getNewLiftData(List<LiftDataModel> liftDataModelList, LiftDataRequest liftDataRequest) {
        if (liftDataModelList != null && liftDataModelList.size() > 0) {
            return liftDataModelList.stream().filter(liftDataModel -> {
                if (liftDataModel.getConnectTime() != null) {
                    return liftDataModel.getConnectTime().isAfter(liftDataRequest.getStartTimeDate()) ||
                            liftDataModel.getConnectTime().isBefore(liftDataRequest.getEndTimeDate());
                }
                return false;
            }).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

}
