package cn.com.ty.lift.system.homepage.service;

import cn.com.ty.lift.common.constants.ApiConstants;
import cn.com.ty.lift.common.utils.ProjectUtils;
import cn.com.ty.lift.system.constants.CommonConstants;
import cn.com.ty.lift.system.homepage.dao.dto.request.PlatformCalendarRequest;
import cn.com.ty.lift.system.homepage.dao.mapper.CommonDataMapper;
import cn.com.ty.lift.system.homepage.dao.model.*;
import cn.com.ty.lift.system.utils.CommonUtil;
import cn.com.xwy.boot.web.dto.RestResponse;
import org.springframework.stereotype.Service;

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

/**
 * @author huangyuan
 * @date 2020/2/14
 * @description 平台日历
 */
@Service
public class PlatformCalendarService {

    @Resource
    private CommonDataMapper commonDataMapper;

    /**
     * @param
     * @return
     * @description 任务数
     * @date 2020/2/14 6:59 下午
     */
    public RestResponse taskNum(PlatformCalendarRequest platformCalendarRequest) {
        Map<Integer, Map<Integer, Long>> dayToLiftDataToNum = CommonUtil.initCalendarMapData(
                platformCalendarRequest.getRequestDateStr(), CommonConstants.PlatformCalendarConstants.TRANS_DATE_FORMAT);
        //获取日期数 -> 电梯信息 (不同电梯状态 -> 电梯数据)
        Map<Integer, Map<Integer, List<CalendarLiftDataModel>>> dayToCalendarLift = getDayToCalendarLift(
                platformCalendarRequest);
        //循环设置不同状态的电梯数量
        dayToCalendarLift.forEach((day, dayToCalendarLiftMap) -> {
            if (dayToCalendarLiftMap != null) {
                //循环设置不同状态的电梯数量
                Map<Integer, Long> statusToLiftNum = new HashMap<>();
                dayToCalendarLiftMap.forEach((status, calendarLiftList) -> {
                    if (calendarLiftList != null) {
                        if (status != 0) {
                            statusToLiftNum.put(status, (long) calendarLiftList.size());
                        }
                    }
                });
                dayToLiftDataToNum.put(day, statusToLiftNum);
            }
        });
        return RestResponse.success(ProjectUtils.transReturnMapToStatisticsKVModel(dayToLiftDataToNum),
                ApiConstants.RESULT_SUCCESS, "获取任务数成功");
    }

    /**
     * @param
     * @return
     * @description 任务电梯列表
     * @date 2020/2/14 7:01 下午
     */
    public RestResponse taskLiftNum(PlatformCalendarRequest platformCalendarRequest) {
        List<CalendarLiftDataModel> calendarLiftDataModelList = new ArrayList<>();
        //获取日期数 -> 电梯信息 (不同电梯状态 -> 电梯数据)
        Map<Integer, Map<Integer, List<CalendarLiftDataModel>>> dayToCalendarLift = getDayToCalendarLift(
                platformCalendarRequest);
        //获取指定日期的电梯数据
        Map<Integer, List<CalendarLiftDataModel>> statusToLiftData = dayToCalendarLift.get(CommonUtil.getDateStrDayValue(
                platformCalendarRequest.getRequestDateDayStr(), CommonConstants.PlatformCalendarConstants.TRANS_DATE_FORMAT));
        if (statusToLiftData != null && statusToLiftData.size() > 0) {
            if (platformCalendarRequest.getCalendarLiftStatus() == null) {
                //如果不传类型就获取所有状态的电梯数据
                List<CalendarLiftDataModel> finalCalendarLiftDataModelList = calendarLiftDataModelList;
                statusToLiftData.forEach((status, calendarLiftList) -> {
                    if (status != 0) {
                        finalCalendarLiftDataModelList.addAll(calendarLiftList);
                    }
                });
                calendarLiftDataModelList = finalCalendarLiftDataModelList;
            } else {
                //传类型就获取指定状态的电梯数据
                calendarLiftDataModelList = statusToLiftData.get(platformCalendarRequest.getCalendarLiftStatus());
            }
        }
        //去除id相同的电梯数据
        removeDuplicationLift(calendarLiftDataModelList);
        return RestResponse.success(calendarLiftDataModelList, ApiConstants.RESULT_SUCCESS, "获取任务数成功");
    }

    /**
     * @param
     * @return
     * @description 获取日期对应的电梯数据 天 -> 电梯数据(电梯状态 -> 电梯数据)
     * @date 2020/2/21 11:12 上午
     */
    private Map<Integer, Map<Integer, List<CalendarLiftDataModel>>> getDayToCalendarLift(
            PlatformCalendarRequest platformCalendarRequest) {
        //时间转化
        CommonUtil.setMonthDate(platformCalendarRequest);
        Map<Integer, Map<Integer, List<CalendarLiftDataModel>>> dayToCalendarLift = new HashMap<>();
        //获取维保计划,并将维保计划信息转化为 天 -> 维保计划(电梯id -> 维保计划)
        Map<Integer, Map<Long, List<MtPlanDataModel>>> dayToMtPlan = getDayToMtPlan(platformCalendarRequest);
        //获取急修记录,并将急修记录转化为 天 -> 急修数据(电梯id -> 急修数据)
        Map<Integer, Map<Long, List<EmergencyRecordDataModel>>> dayToEmergencyRecord = getDayToEmergencyRecord(
                platformCalendarRequest);
        //获取年检记录,并将年检记录转化为 天 -> 年检数据(电梯 -> 年检数据)
        Map<Integer, Map<Long, List<AnnualInspectionDataModel>>> dayToAnnualInspection = getDayToAnnualInspection(
                platformCalendarRequest);
        //获取请求日期的天数
        int monthDayNum = CommonUtil.getLastDayNumOfMonthFromDateStr(
                platformCalendarRequest.getRequestDateStr(), CommonConstants.PlatformCalendarConstants.REQUEST_DATE_FORMAT);
        //循环设置每日的数据
        for (int day = 1; day <= monthDayNum; day++) {
            addCalendarLift(dayToCalendarLift, dayToMtPlan, dayToEmergencyRecord, dayToAnnualInspection, day);
        }
        return dayToCalendarLift;
    }

    /**
     * @param
     * @return
     * @description 向对应状态中添加电梯信息
     * @date 2020/2/21 3:05 下午
     */
    private void addCalendarLift(Map<Integer, Map<Integer, List<CalendarLiftDataModel>>> dayToCalendarLift,
                                 Map<Integer, Map<Long, List<MtPlanDataModel>>> dayToMtPlan,
                                 Map<Integer, Map<Long, List<EmergencyRecordDataModel>>> dayToEmergencyRecord,
                                 Map<Integer, Map<Long, List<AnnualInspectionDataModel>>> dayToAnnualInspection, int day) {
        //获取每天的维保计划数据
        Map<Long, List<MtPlanDataModel>> liftIdToMtPlan = dayToMtPlan.get(day);
        //获取每天的急修记录数据
        Map<Long, List<EmergencyRecordDataModel>> liftIdToEmergencyRecord = dayToEmergencyRecord.get(day);
        //获取每天的年检记录数据
        Map<Long, List<AnnualInspectionDataModel>> liftIdToAnnualInspection = dayToAnnualInspection.get(day);
        //获取电梯id集合
        Set liftIdSet = getLiftIdSet(liftIdToMtPlan, liftIdToEmergencyRecord, liftIdToAnnualInspection);
        //状态 -> 电梯列表
        Map<Integer, List<CalendarLiftDataModel>> statusToCalendarLift = new HashMap<>();
        if (liftIdSet.size() > 0) {
            List<CalendarLiftDataModel> calendarLiftDataModelList = new ArrayList<>();
            liftIdSet.forEach(liftId -> {
                long liftIdLong = Long.parseLong(liftId.toString());
                //封装维保的电梯信息
                addMaintenanceStatusLift(liftIdToMtPlan, calendarLiftDataModelList, liftIdLong);
                //封装急修信息
                addEmergencyStatusLift(liftIdToEmergencyRecord, calendarLiftDataModelList, liftIdLong);
                //封装年检信息
                addAnnualInspectionLift(liftIdToAnnualInspection, calendarLiftDataModelList, liftIdLong);
                //分类封装电梯数据
                classifyStatusPutLIftData(statusToCalendarLift, calendarLiftDataModelList);
            });
        }
        dayToCalendarLift.put(day, statusToCalendarLift);
    }

    /**
     * @param
     * @return
     * @description 分类封装电梯数据
     * @date 2020/2/21 4:01 下午
     */
    private void classifyStatusPutLIftData(Map<Integer, List<CalendarLiftDataModel>> statusToCalendarLift, List<CalendarLiftDataModel> calendarLiftDataModelList) {
        if (calendarLiftDataModelList.size() > 0) {
            //通过维保状态来分类电梯信息
            Map<Integer, List<CalendarLiftDataModel>> statusToMtCalendarLift = calendarLiftDataModelList.stream()
                    .collect(Collectors.groupingBy(calendarLiftDataModel -> {
                        if (calendarLiftDataModel.getMaintenanceStatus() != null) {
                            return calendarLiftDataModel.getMaintenanceStatus();
                        }
                        return 0;
                    }));
            statusToCalendarLift.putAll(statusToMtCalendarLift);
            //通过急修状态来分类电梯信息
            Map<Integer, List<CalendarLiftDataModel>> statusToMtEmergencyLift = calendarLiftDataModelList.stream()
                    .collect(Collectors.groupingBy(calendarLiftDataModel -> {
                        if (calendarLiftDataModel.getEmergencyStatus() != null) {
                            return calendarLiftDataModel.getEmergencyStatus();
                        }
                        return 0;
                    }));
            statusToCalendarLift.putAll(statusToMtEmergencyLift);
            //通过年检状态来分类电梯信息
            Map<Integer, List<CalendarLiftDataModel>> statusToAnnualLift = calendarLiftDataModelList.stream()
                    .collect(Collectors.groupingBy(calendarLiftDataModel -> {
                        if (calendarLiftDataModel.getAnnualInspectionStatus() != null) {
                            return calendarLiftDataModel.getAnnualInspectionStatus();
                        }
                        return 0;
                    }));
            statusToCalendarLift.putAll(statusToAnnualLift);
        }
    }

    /**
     * @param
     * @return
     * @description 封装维保的电梯信息
     * @date 2020/2/21 2:55 下午
     */
    private void addMaintenanceStatusLift(Map<Long, List<MtPlanDataModel>> liftIdToMtPlan,
                                          List<CalendarLiftDataModel> calendarLiftDataModelList,
                                          Long liftId) {
        if (liftIdToMtPlan != null) {
            //获取保养计划数据
            List<MtPlanDataModel> mtPlanDataModelList = liftIdToMtPlan.get(liftId);
            if (mtPlanDataModelList != null && mtPlanDataModelList.size() > 0) {
                MtPlanDataModel mtPlanDataModel = mtPlanDataModelList.get(0);
                CalendarLiftDataModel calendarLiftDataModel = new CalendarLiftDataModel(
                        mtPlanDataModel.getLiftId(), mtPlanDataModel.getProjectName(),
                        mtPlanDataModel.getRegistrationCode(), mtPlanDataModel.getLiftCode(),
                        mtPlanDataModel.getWorkerName());
                //默认是维保已完成
                calendarLiftDataModel.setMaintenanceStatus(3);
                if (mtPlanDataModel.getStatus() != null) {
                    switch (mtPlanDataModel.getStatus()) {
                        case 0:
                            //待完成
                            calendarLiftDataModel.setMaintenanceStatus(1);
                            break;
                        case 2:
                            //维保中
                            calendarLiftDataModel.setMaintenanceStatus(2);
                            break;
                        case -1:
                            calendarLiftDataModel.setMaintenanceStatus(-1);
                            break;
                    }
                }
                calendarLiftDataModelList.add(calendarLiftDataModel);
            }

        }
    }

    /**
     * @param
     * @return
     * @description 封装急修电梯信息
     * @date 2020/2/21 2:59 下午
     */
    private void addEmergencyStatusLift(Map<Long, List<EmergencyRecordDataModel>> liftIdToEmergencyRecord,
                                        List<CalendarLiftDataModel> calendarLiftDataModelList, Long liftId) {
        if (liftIdToEmergencyRecord != null) {
            //获取急修记录数
            List<EmergencyRecordDataModel> emergencyRecordDataModelList = liftIdToEmergencyRecord.get(liftId);
            if (emergencyRecordDataModelList != null && emergencyRecordDataModelList.size() > 0) {
                EmergencyRecordDataModel emergencyRecordDataModel = emergencyRecordDataModelList.get(0);
                CalendarLiftDataModel calendarLiftDataModel = new CalendarLiftDataModel(
                        emergencyRecordDataModel.getLiftId(), emergencyRecordDataModel.getProjectName(),
                        emergencyRecordDataModel.getRegistrationCode(), emergencyRecordDataModel.getLiftCode(),
                        emergencyRecordDataModel.getWorkerName());
                //急修默认状态是 待急修
                calendarLiftDataModel.setEmergencyStatus(4);
                if (emergencyRecordDataModel.getStatus() != null) {
                    switch (emergencyRecordDataModel.getStatus()) {
                        case 1:
                        case 3:
                            calendarLiftDataModel.setEmergencyStatus(5);
                            break;
                        case 2:
                            calendarLiftDataModel.setEmergencyStatus(6);
                    }
                }
                calendarLiftDataModelList.add(calendarLiftDataModel);
            }
        }
    }

    /**
     * @param
     * @return
     * @description 封装年检电梯信息
     * @date 2020/2/21 3:03 下午
     */
    private void addAnnualInspectionLift(Map<Long, List<AnnualInspectionDataModel>> liftIdToAnnualInspection,
                                         List<CalendarLiftDataModel> calendarLiftDataModelList, Long liftId) {
        if (liftIdToAnnualInspection != null) {
            //获取年检记录
            List<AnnualInspectionDataModel> annualInspectionDataModelList = liftIdToAnnualInspection.get(liftId);
            if (annualInspectionDataModelList != null && annualInspectionDataModelList.size() > 0) {
                AnnualInspectionDataModel annualInspectionDataModel = annualInspectionDataModelList.get(0);
                CalendarLiftDataModel calendarLiftDataModel = new CalendarLiftDataModel(
                        annualInspectionDataModel.getLiftId(), annualInspectionDataModel.getProjectName(),
                        annualInspectionDataModel.getRegistrationCode(), annualInspectionDataModel.getLiftCode(),
                        annualInspectionDataModel.getWorkerName());
                //年检默认状态 默认 计划年检
                calendarLiftDataModel.setAnnualInspectionStatus(7);
                if (annualInspectionDataModel.getStatus() != null) {
                    if (annualInspectionDataModel.getStatus() == 1) {
                        calendarLiftDataModel.setAnnualInspectionStatus(9);
                    } else {
                        if (annualInspectionDataModel.getStepStatus() != null &&
                                annualInspectionDataModel.getStepStatus() != 1) {
                            calendarLiftDataModel.setAnnualInspectionStatus(8);
                        }
                    }
                }
            }
        }
    }

    /**
     * @param
     * @return
     * @description 获取维保记录信息，并将信息转化为 天 -> 维保记录(电梯id -> 维保记录)
     * @date 2020/2/21 10:46 上午
     */
    private Map<Integer, Map<Long, List<MtRecordDataModel>>> getDayToMtRecord(PlatformCalendarRequest platformCalendarRequest) {
        //获取当前公司的维保记录 传递时间值 月初时间 - 当前时间
        List<MtRecordDataModel> mtRecordDataModelList = commonDataMapper
                .getMonthBeginToNowMtRecord(platformCalendarRequest);
        //将维保记录数据转化为 天 -> 维保记录(电梯id -> 维保记录)
        return CommonUtil.getDayToDataMap(mtRecordDataModelList,
                "workDate");
    }

    /**
     * @param
     * @return
     * @description 获取维保计划, 并将维保计划信息转化为 天 -> 维保计划(电梯id -> 维保计划)
     * @date 2020/2/21 10:48 上午
     */
    private Map<Integer, Map<Long, List<MtPlanDataModel>>> getDayToMtPlan(PlatformCalendarRequest platformCalendarRequest) {
        //获取当前公司的维保计划 传递时间值 当前时间 - 月末时间
        List<MtPlanDataModel> mtPlanDataModelList = commonDataMapper
                .getMonthNowToEndMtPlan(platformCalendarRequest);
        //将维保计划数据转化为 天 -> 维保计划(电梯id -> 维保计划)
        return CommonUtil.getDayToDataMap(mtPlanDataModelList,
                "planDate");
    }

    /**
     * @param
     * @return
     * @description 获取急修记录, 并将急修记录转化为 天 -> 急修数据(电梯id -> 急修数据)
     * @date 2020/2/21 10:51 上午
     */
    private Map<Integer, Map<Long, List<EmergencyRecordDataModel>>> getDayToEmergencyRecord(PlatformCalendarRequest platformCalendarRequest) {
        //获取当前公司的急修记录 传递时间值 月初时间 - 当前时间
        List<EmergencyRecordDataModel> emergencyRecordDataModelList = commonDataMapper
                .getMonthBeginToNowEmergencyRecord(platformCalendarRequest);
        //将急修记录数据转化为 天 -> 急修数据(电梯id -> 急修数据)
        return CommonUtil.getDayToDataMap(emergencyRecordDataModelList, "callerDate");
    }

    /**
     * @param
     * @return
     * @description 获取年检记录, 并将年检记录转化为 天 -> 年检数据(电梯 -> 年检数据)
     * @date 2020/2/21 10:53 上午
     */
    private Map<Integer, Map<Long, List<AnnualInspectionDataModel>>> getDayToAnnualInspection(PlatformCalendarRequest platformCalendarRequest) {
        //获取当前公司的年检记录 传递时间值 月初时间 - 月末时间
        List<AnnualInspectionDataModel> annualInspectionDataModelList = commonDataMapper
                .getMonthBeginToEndAnnualInspectionRecord(platformCalendarRequest);
        //将年检数据转化为 天 -> 年检数据(电梯id -> 年检数据)
        return CommonUtil.getDayToDataMap(
                annualInspectionDataModelList, "planDate");
    }

    /**
     * @param
     * @return
     * @description 去除id相同的电梯数据
     * @date 2020/2/21 11:40 上午
     */
    private void removeDuplicationLift(List<CalendarLiftDataModel> calendarLiftDataModelList) {
        List<CalendarLiftDataModel> noDuplicationLiftList = new ArrayList<>();
        if (calendarLiftDataModelList != null && calendarLiftDataModelList.size() > 0) {
            //存放电梯id的map
            Map<Long, Integer> liftIdToLiftNum = new HashMap<>();
            calendarLiftDataModelList.forEach(calendarLiftDataModel -> {
                //如果电梯id不存在，就向电梯list中添加电梯，存在就跳过
                if (liftIdToLiftNum.get(calendarLiftDataModel.getLiftId()) == null) {
                    noDuplicationLiftList.add(calendarLiftDataModel);
                    liftIdToLiftNum.put(calendarLiftDataModel.getLiftId(), 1);
                }
            });
        }
    }

    /**
     * @param
     * @return
     * @description 获取电梯id集合
     * @date 2020/2/21 1:16 下午
     */
    private Set getLiftIdSet(Map<Long, List<MtPlanDataModel>> liftIdToMtPlan,
                             Map<Long, List<EmergencyRecordDataModel>> liftIdToEmergencyRecord,
                             Map<Long, List<AnnualInspectionDataModel>> liftIdToAnnualInspection) {
        //数据集合数组
        Map[] dataMapArray = {
                liftIdToMtPlan,
                liftIdToEmergencyRecord,
                liftIdToAnnualInspection
        };
        //获取当天所有电梯数据
        Set liftIdSet = new HashSet<>();
        //循环设置电梯id
        for (Map dataMap : dataMapArray) {
            if (dataMap != null && dataMap.size() > 0) {
                liftIdSet.addAll(dataMap.keySet());
            }
        }
        return liftIdSet;
    }

}
