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

import cn.com.ty.lift.batch.applet.constants.DataStatisticsConstants;
import cn.com.ty.lift.batch.applet.dao.mapper.MaintenanceDataMapper;
import cn.com.ty.lift.batch.applet.dao.model.MaintenanceDataModel;
import cn.com.ty.lift.batch.applet.dao.model.request.CommonRequest;
import cn.com.ty.lift.batch.applet.dao.model.request.MaintenanceDataRequest;
import cn.com.ty.lift.batch.applet.dao.model.response.MaintenanceOverViewResponse;
import cn.com.ty.lift.batch.applet.util.DataStatisticsUtil;
import cn.com.ty.lift.common.constants.ApiConstants;
import cn.com.ty.lift.common.utils.ProjectUtils;
import cn.com.xwy.boot.web.dto.RestResponse;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

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

    @Resource
    private MaintenanceDataMapper maintenanceDataMapper;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * @param commonRequest 起始时间 终止时间
     * @return
     * @description 将维保数据放入redis中
     * @date 2020/2/4 1:50 下午
     */
    public void putMaintenanceDataListToRedis(CommonRequest commonRequest) {
        List<MaintenanceDataModel> maintenanceDataModelList = maintenanceDataMapper.getMaintenanceDataList(commonRequest);
        //通过公司id对数据进行分组,并将维保数据放入redis中
        DataStatisticsUtil.putStatisticsDataToRedis(maintenanceDataModelList, redisTemplate,
                DataStatisticsConstants.MAINTENANCE_DATA_FIELD);
    }

    /**
     * @param
     * @return
     * @description 将维保数据从redis中取出来
     * @date 2020/2/4 2:04 下午
     */
    public List<MaintenanceDataModel> getMaintenanceDataListFromRedis(MaintenanceDataRequest maintenanceDataRequest) {
        //从redis中获取当前公司维保数据
        List<MaintenanceDataModel> maintenanceDataModelList = (List<MaintenanceDataModel>) DataStatisticsUtil
                .getStatisticsDataFromRedis(redisTemplate, DataStatisticsConstants.MAINTENANCE_DATA_FIELD,
                        maintenanceDataRequest.getMtCompanyId());
        if (maintenanceDataModelList != null && maintenanceDataModelList.size() > 0) {
            //通过起始时间过滤
            if (maintenanceDataRequest.getStartDate() != null) {
                maintenanceDataModelList = maintenanceDataModelList.stream()
                        .filter(a -> {
                            if (a.getPlanDate() != null) {
                                return a.getPlanDate().isAfter(maintenanceDataRequest.getStartDate());
                            }
                            return false;
                        })
                        .collect(Collectors.toList());
            }
            //通过终止时间过滤
            if (maintenanceDataRequest.getEndDate() != null) {
                maintenanceDataModelList = maintenanceDataModelList.stream()
                        .filter(a -> {
                            if (a.getPlanDate() != null) {
                                return a.getPlanDate().isBefore(maintenanceDataRequest.getEndDate());
                            }
                            return false;
                        })
                        .collect(Collectors.toList());
            }
        }
        return maintenanceDataModelList;
    }

    /**
     * @param
     * @return
     * @description 获取维保统计总览情况
     * @date 2020/2/5 4:50 下午
     */
    public RestResponse maintenanceOverView(MaintenanceDataRequest maintenanceDataRequest) {
        MaintenanceOverViewResponse maintenanceOverViewResponse = new MaintenanceOverViewResponse();
        //从redis中获取数据
        List<MaintenanceDataModel> maintenanceDataModelList = getMaintenanceDataListFromRedis(maintenanceDataRequest);
        if (maintenanceDataModelList != null && maintenanceDataModelList.size() > 0) {
            //设置计划保养数
            maintenanceOverViewResponse.setPlanNum(maintenanceDataModelList.stream().count());
            //保养状态 0:待完成 1:已完成 2:超期
            //设置完成保养数
            long finishNum = maintenanceDataModelList.stream()
                    .filter(a -> {
                        if (a.getMaintenanceStatus() != null) {
                            return a.getMaintenanceStatus() == 1;
                        }
                        return false;
                    })
                    .count();
            maintenanceOverViewResponse.setFinishNum(finishNum);
            setBeyondNum(maintenanceOverViewResponse, maintenanceDataModelList);
        }
        return RestResponse.success(maintenanceOverViewResponse, ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    /**
     * @param
     * @return
     * @description 超期统计
     * @date 2020/2/5 4:53 下午
     */
    public RestResponse beyondStatistics(MaintenanceDataRequest maintenanceDataRequest) {
        Map<String, Long> projectNameToBeyondNum = getTestBeyondStatistics();
        //从redis中获取维保数据
        List<MaintenanceDataModel> maintenanceDataModelList = getMaintenanceDataListFromRedis(maintenanceDataRequest);
        if (maintenanceDataModelList != null && maintenanceDataModelList.size() > 0) {
            //获取超期数
            maintenanceDataModelList = maintenanceDataModelList.stream()
                    .filter(a -> {
                        if (a.getMaintenanceStatus() != null) {
                            return a.getMaintenanceStatus() == 2;
                        }
                        return false;
                    })
                    .collect(Collectors.toList());
            Map<String, Long> allProjectNameToBeyondNum = maintenanceDataModelList.stream()
                    .collect(Collectors.groupingBy(MaintenanceDataModel::getProjectName, Collectors.counting()));
            //通过超期台量倒序排列
            allProjectNameToBeyondNum = DataStatisticsUtil.sortByValue(allProjectNameToBeyondNum, true);
            //获取前5的数据
            allProjectNameToBeyondNum.forEach((key, value) -> {
                if (projectNameToBeyondNum.size() < 5) {
                    projectNameToBeyondNum.put(key, value);
                }
            });
        }
        return RestResponse.success(ProjectUtils.transReturnMapToStatisticsKVModel(projectNameToBeyondNum), ApiConstants.RESULT_SUCCESS, "获取统计数据成功");
    }

    /**
     * @param
     * @return
     * @description 获取超期统计测试数据
     * @date 2020/2/24 7:49 上午
     */
    private Map<String, Long> getTestBeyondStatistics() {
        Map<String, Long> testMap = new HashMap<>();
        Random random = new Random();
        for(int i = 1; i <= 5; i++) {
            testMap.put("测试项目" + i, (long)random.nextInt(10));
        }
        return testMap;
    }

    /**
     * @param
     * @return
     * @description 设置超期数
     * @date 2020/2/9 9:57 下午
     */
    private void setBeyondNum(MaintenanceOverViewResponse maintenanceOverViewResponse,
                              List<MaintenanceDataModel> maintenanceDataModelList) {
        //设置总超期数
        long totalBeyondNum = maintenanceDataModelList.stream()
                .filter(a -> {
                    if (a.getMaintenanceStatus() != null) {
                        return a.getMaintenanceStatus() == 2;
                    }
                    return false;
                })
                .count();
        maintenanceOverViewResponse.setTotalBeyondNum(totalBeyondNum);
        //获取超期的维保记录
        List<MaintenanceDataModel> beyondMaintenanceDataModelList = maintenanceDataModelList.stream()
                .filter(a -> {
                    if (a.getMaintenanceStatus() != null) {
                        return a.getMaintenanceStatus() == 2;
                    }
                    return false;
                })
                .collect(Collectors.toList());
        if (beyondMaintenanceDataModelList != null && beyondMaintenanceDataModelList.size() > 0) {
            //获取当前时间
            LocalDate now = LocalDate.now();
            //设置超期类型
            setBeyondType(maintenanceDataModelList, beyondMaintenanceDataModelList, now);
            //设置计划超期数
            long planBeyondNum = beyondMaintenanceDataModelList.stream()
                    .filter(a -> {
                        if (a.getBeyondType() != null) {
                            return a.getBeyondType() == 1;
                        }
                        return false;
                    })
                    .count();
            //设置法规超期数
            long lawBeyondNum = beyondMaintenanceDataModelList.stream()
                    .filter(a -> {
                        if (a.getBeyondType() != null) {
                            return a.getBeyondType() == 2;
                        }
                        return false;
                    })
                    .count();
            maintenanceOverViewResponse.setPlanBeyondNum(planBeyondNum);
            maintenanceOverViewResponse.setLawBeyondNum(lawBeyondNum);
        }
    }

    /**
     * @param
     * @return
     * @description 设置超期类型
     * @date 2020/2/9 10:01 下午
     */
    private void setBeyondType(List<MaintenanceDataModel> maintenanceDataModelList, List<MaintenanceDataModel> beyondMaintenanceDataModelList, LocalDate now) {
        //通过电梯将维保记录分组
        Map<Long, List<MaintenanceDataModel>> liftIdToMaintenanceData = maintenanceDataModelList.stream()
                .collect(Collectors.groupingBy(MaintenanceDataModel::getLiftId));
        //设置超期类型 1:计划超期 2:法规超期
        beyondMaintenanceDataModelList.forEach(beyondMaintenanceDataModel -> {
            //获取电梯的维保计划
            List<MaintenanceDataModel> liftMaintenanceDataModelList =
                    liftIdToMaintenanceData.get(beyondMaintenanceDataModel.getLiftId());
            //保养时间
            LocalDate maintenanceDate;
            if (beyondMaintenanceDataModel.getCount() == 1) {
                //第一次保养, 获取首保时间
                maintenanceDate = beyondMaintenanceDataModel.getFirstDate();
            } else {
                //获取上次保养记录
                MaintenanceDataModel lastMaintenanceDataModel = liftMaintenanceDataModelList.stream()
                        .filter(a -> a.getCount() == beyondMaintenanceDataModel.getCount() - 1)
                        .collect(Collectors.toList()).get(0);
                //获取保养完成时间
                maintenanceDate = lastMaintenanceDataModel.getFinishDate();
            }
            //计划现在时间与上次保养间隔天数
            long intervalDay = Duration.between(now, maintenanceDate).toDays();
            beyondMaintenanceDataModel.setBeyondType(1);
            //间隔天数大于15属于法规超期
            if (intervalDay > 15) {
                beyondMaintenanceDataModel.setBeyondType(2);
            }
        });
    }
}
