package com.tykj.dev.statistical.service.impl;

import com.tykj.dev.device.confirmcheck.entity.domain.DeviceCheckDetail;
import com.tykj.dev.device.confirmcheck.repository.DeviceCheckDetailDao;
import com.tykj.dev.device.confirmcheck.repository.DeviceCheckStatDao;
import com.tykj.dev.device.library.repository.DeviceLibraryDao;
import com.tykj.dev.device.library.service.DeviceLibraryService;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.device.library.subject.vo.DeviceLibrarySelectVo;
import com.tykj.dev.device.matching.repository.MatchingDeviceLibraryDao;
import com.tykj.dev.device.packing.repository.PackingLibraryDao;
import com.tykj.dev.device.selfcheck.base.SelfCheckSchedulerTask;
import com.tykj.dev.device.selfcheck.repository.SelfCheckBillDao;
import com.tykj.dev.device.selfcheck.subject.domin.SelfCheckBill;
import com.tykj.dev.device.task.repository.TaskDao;
import com.tykj.dev.device.task.service.TaskService;
import com.tykj.dev.device.task.subject.domin.Task;
import com.tykj.dev.device.task.subject.vo.TaskSelectVo;
import com.tykj.dev.device.task.subject.vo.TaskUserVo;
import com.tykj.dev.device.train.dao.TrainThemeDao;
import com.tykj.dev.device.train.entity.TrainTheme;
import com.tykj.dev.device.user.base.ret.UserSituationVo;
import com.tykj.dev.device.user.cache.AreaCache;
import com.tykj.dev.device.user.cache.UnitsCache;
import com.tykj.dev.device.user.subject.dao.AreaDao;
import com.tykj.dev.device.user.subject.dao.UnitsDao;
import com.tykj.dev.device.user.subject.dao.UserDao;
import com.tykj.dev.device.user.subject.entity.Area;
import com.tykj.dev.device.user.subject.entity.Units;
import com.tykj.dev.device.user.subject.entity.User;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.rfid.entity.domin.LibraryWarningLog;
import com.tykj.dev.rfid.repository.LibraryWarningLogDao;
import com.tykj.dev.statistical.service.StatisticalService;
import com.tykj.dev.statistical.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author dengdiyi
 */
@Service
public class StatisticalServiceImpl implements StatisticalService {

    @Autowired
    private DeviceLibraryDao deviceLibraryDao;

    @Autowired
    private AreaDao areaDao;

    @Autowired
    private UnitsDao unitsDao;

    @Autowired
    TrainThemeDao trainThemeDao;

    @Autowired
    private SelfCheckBillDao selfCheckBillDao;

    @Autowired
    private LibraryWarningLogDao libraryWarningLogDao;

    @Autowired
    private TaskService taskService;

    @Autowired
    private UserDao userDao;
    @Autowired
    private UnitsCache unitsCache;

    @Autowired
    private AreaCache areaCache;

    @Autowired
    private DeviceCheckDetailDao deviceCheckDetailDao;

    @Autowired
    private DeviceCheckStatDao deviceCheckStatDao;

    @Autowired
    private DeviceLibraryService deviceLibraryService;

    @Autowired
    private MatchingDeviceLibraryDao matchingDeviceLibraryDao;

    @Autowired
    private PackingLibraryDao packingLibraryDao;

    @Autowired
    private TaskDao taskDao;

    @Autowired
    private UserUtils userUtils;

    /**
     *  获取装备统计信息
     */
    @Override
    public List<DevNum> getDeviceNum() {
        List<DevNum> nums=new ArrayList<>();
        //获取所有装备
        List<DeviceLibrary> deviceLibraries = deviceLibraryDao.findAll();
        //获取所有市
        List<Area> areas = areaDao.findAreasByType(2);
        //获取所有单位
        List<Units> units = unitsCache.findAll();
        //统计各市装备数量
        areas.forEach(area -> {
            DevNum devNum = new DevNum();
            devNum.setAreaName(area.getName());
            //获取市以及子区县所有区域id
            List<Integer> areaIds = areaDao.findAllByFatherId(area.getId()).stream()
                    .map(Area::getId)
                    .collect(Collectors.toList());
            areaIds.add(area.getId());
            //根据区域id找单位id集合
            List<String> names = units.stream()
                    .filter(units1 -> areaIds.contains(units1.getAreaId()))
                    .map(Units::getName)
                    .collect(Collectors.toList());
            //筛选出所属单位在id集合中的装备
            List<DeviceLibrary> deviceLibraryList = deviceLibraries.stream()
                    .filter(deviceLibrary -> names.contains(deviceLibrary.getOwnUnit()))
                    .collect(Collectors.toList());
            //获取装备总数量
            devNum.setCount(deviceLibraryList.size());
            nums.add(devNum);
        });
        return nums;
    }

    /**
     * @param type 类型（1：省，2：市）
     *             获取装备生命状态统计信息
     */
    @Override
    public List<DevLifeSector> getLifeStatus(Integer type) {
        List<DevLifeSector> nums=new ArrayList<>();
        //获取所有装备
        List<DeviceLibrary> deviceLibraries = deviceLibraryDao.findAll();
        //省
        if (type==1){
            DevLifeSector devLifeSector = new DevLifeSector();
            //获取省区域名
            List<Area> areas = areaDao.findAreasByType(1);
            if (areas.size()==1){
                devLifeSector.setAreaName(areas.get(0).getName());
                countDevice(devLifeSector,deviceLibraries);
                nums.add(devLifeSector);
            }
            return nums;
        }
        //市
        else if (type==2){
            List<Area> areas = areaDao.findAreasByType(2);
            //每个市进行统计
            for (Area area: areas) {
                DevLifeSector devLifeSector = new DevLifeSector();
                devLifeSector.setAreaName(area.getName());
                //获取市以及子区县所有区域
                List<Area> areas1 = areaDao.findAllByFatherId(area.getId());
                areas1.add(area);
                //获取所有单位名称
                List<String> unitNames = new ArrayList<>();
                areas1.forEach(area1 -> {
                    List<Units> units = unitsDao.findAllByAreaId(area1.getId());
                    if (units.size()==1){
                        unitNames.add(units.get(0).getName());
                    }
                });
                //筛选出当前区域单位装备
                List<DeviceLibrary> deviceLibraries1 = deviceLibraries.stream()
                        .filter(deviceLibrary -> unitNames.contains(deviceLibrary.getOwnUnit()))
                        .collect(Collectors.toList());
                countDevice(devLifeSector,deviceLibraries1);
                nums.add(devLifeSector);
            }
            return nums;
        }
        else {
            throw new ApiException(ResponseEntity.ok("type只能为1，2"));
        }
    }

    /**
     * 获取季度自查统计信息
     */
    @Override
    public List<SelfInspection> getSelfCheck() {
        List<SelfInspection> nums=new ArrayList<>();
        //获取所有自查单
        List<SelfCheckBill> selfCheckBills = selfCheckBillDao.findAll();
        //计算当前季度
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        String quarter = calendar.get(Calendar.YEAR)+"年"+SelfCheckSchedulerTask.getQuarter(calendar.get(Calendar.MONTH)+1);
        //筛选出标题包含当前年份季度的
        List<SelfCheckBill> selfCheckBillList = selfCheckBills.stream()
                .filter(selfCheckBill -> selfCheckBill.getTitle().contains(quarter))
                .collect(Collectors.toList());
        //获取所有市
        List<Area> areas = areaDao.findAreasByType(2);
        //遍历每个市
        for (Area area : areas) {
            //获取当前区域所有区县
            List<Area> sonAreas = areaDao.findAllByFatherId(area.getId());
            SelfInspection selfInspection = new SelfInspection();
            selfInspection.setAreaName(area.getName());
            if (selfCheckBillList.size()>0) {
                //获取未完成区县
                List<Area> areas1 = getSelfCheckUndoAreas(area.getId(), quarter, selfCheckBills);
                //set未完成数量
                selfInspection.setNoCompleteCount(areas1.size());
                //set已完成数量
                selfInspection.setCompleteCount(sonAreas.size() - areas1.size());
            }
            nums.add(selfInspection);
        }
        return nums;
    }

    /**
     * 获取各市最近一次自查完成情况
     */
    @Override
    public List<SelfCheckVo> getSelfCheckStat() {
        List<SelfCheckVo> selfCheckVos = new ArrayList<>();
        //获取所有自查单
        List<SelfCheckBill> selfCheckBills = selfCheckBillDao.findAll();
        //获取最近一次自查标题
        List<SelfCheckBill> selfCheckBillList = selfCheckBills.stream().filter(selfCheckBill -> selfCheckBill.getCycle()!=null).sorted(Comparator.comparing(SelfCheckBill::getCreateTime,Comparator.nullsLast(Date::compareTo).reversed())).collect(Collectors.toList());
        if (selfCheckBillList.size()>0){
            Map<String,Integer> selfCheckBillMap = selfCheckBills.stream().filter(selfCheckBill ->selfCheckBill.getCycle()!=null && selfCheckBill.getTitle().equals(selfCheckBillList.get(0).getTitle())).collect(Collectors.toMap(SelfCheckBill::getCheckUnit,SelfCheckBill::getCheckStatus,(v1, v2)->v1));
            //获取所有市
            List<Area> areas = areaDao.findAreasByType(2);
            //遍历每个市
            for (Area area : areas) {
                SelfCheckVo selfCheckVo = new SelfCheckVo();
                selfCheckVo.setAreaName(area.getName());
                List<Units> units = unitsDao.findAllByAreaId(area.getId());
                if (units.size()>0) {
                    if (selfCheckBillMap.get(units.get(0).getName()) != null) {
                        if (selfCheckBillMap.get(units.get(0).getName()) == 2) {
                            selfCheckVo.setIsComplete(1);
                        } else {
                            selfCheckVo.setIsComplete(0);
                        }
                    }
                }
                else {
                    selfCheckVo.setIsComplete(0);
                }
                selfCheckVos.add(selfCheckVo);
            }
        }
        return selfCheckVos;
    }

    /**
     * 获取年度自查统计信息
     */
    @Override
    public List<YearSelfInspection> getYearSelfCheck() {
        List<YearSelfInspection> yearSelfInspections = new ArrayList<>();
        //获取所有自查单
        List<SelfCheckBill> selfCheckBills = selfCheckBillDao.findAll();
        //获取所有市
        List<Area> areas = areaDao.findAreasByType(2);
        //判断当前季度
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        String quarter1 = calendar.get(Calendar.YEAR)+"年第一季度";
        String quarter2 = calendar.get(Calendar.YEAR)+"年第二季度";
        String quarter3 = calendar.get(Calendar.YEAR)+"年第三季度";
        String quarter4 = calendar.get(Calendar.YEAR)+"年第四季度";
        //筛选出标题包含当前年份季度的
        List<SelfCheckBill> selfCheckBillList1 = selfCheckBills.stream()
                .filter(selfCheckBill -> selfCheckBill.getTitle().contains(quarter1))
                .collect(Collectors.toList());
        List<SelfCheckBill> selfCheckBillList2 = selfCheckBills.stream()
                .filter(selfCheckBill -> selfCheckBill.getTitle().contains(quarter2))
                .collect(Collectors.toList());
        List<SelfCheckBill> selfCheckBillList3 = selfCheckBills.stream()
                .filter(selfCheckBill -> selfCheckBill.getTitle().contains(quarter3))
                .collect(Collectors.toList());
        List<SelfCheckBill> selfCheckBillList4 = selfCheckBills.stream()
                .filter(selfCheckBill -> selfCheckBill.getTitle().contains(quarter4))
                .collect(Collectors.toList());
        //遍历所有市
        areas.forEach(area -> {
            YearSelfInspection yearSelfInspection = new YearSelfInspection();
            PerQuarter firstQuarter = new PerQuarter();
            PerQuarter secondQuarter = new PerQuarter();
            PerQuarter thirdQuarter = new PerQuarter();
            PerQuarter fourthQuarter = new PerQuarter();
            yearSelfInspection.setAreaName(area.getName());
            //获取当前区域所有区县
            List<Area> sonAreas = areaDao.findAllByFatherId(area.getId());
            if (selfCheckBillList1.size()>0){
                List<Area> undoAreas = getSelfCheckUndoAreas(area.getId(),quarter1,selfCheckBills);
                setPerQuarter(firstQuarter, sonAreas, undoAreas);
            }
            if (selfCheckBillList2.size()>0){
                List<Area> undoAreas = getSelfCheckUndoAreas(area.getId(),quarter2,selfCheckBills);
                setPerQuarter(secondQuarter, sonAreas, undoAreas);
            }
            if (selfCheckBillList3.size()>0){
                List<Area> undoAreas = getSelfCheckUndoAreas(area.getId(),quarter3,selfCheckBills);
                setPerQuarter(thirdQuarter, sonAreas, undoAreas);
            }
            if (selfCheckBillList4.size()>0){
                List<Area> undoAreas = getSelfCheckUndoAreas(area.getId(),quarter4,selfCheckBills);
                setPerQuarter(fourthQuarter, sonAreas, undoAreas);
            }
            yearSelfInspection.setFirstQuarter(firstQuarter);
            yearSelfInspection.setSecondQuarter(secondQuarter);
            yearSelfInspection.setThirdQuarter(thirdQuarter);
            yearSelfInspection.setFourthQuarter(fourthQuarter);
            yearSelfInspections.add(yearSelfInspection);
        });
        return yearSelfInspections;
    }

    /**
     * 获取年度告警统计信息
     */
    @Override
    public AlarmSituation getRfidWarning() {
        AlarmSituation alarmSituation = new AlarmSituation();
        //获取当前年份
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int year = calendar.get(Calendar.YEAR);
        //获取本年度所有告警记录
        List<LibraryWarningLog> libraryWarningLogs = libraryWarningLogDao.findAll().stream()
                .filter(libraryWarningLog -> {
                    calendar.setTime(libraryWarningLog.getCreateTime());
                    return year==calendar.get(Calendar.YEAR);
                })
                .collect(Collectors.toList());
        alarmSituation.setAlarmCount(libraryWarningLogs.size());
        //获取盘库异常数量
        int inventoryNum = (int)libraryWarningLogs.stream().filter(libraryWarningLog -> libraryWarningLog.getWarningType()==2).count();
        //获取未处理数量
        int unHandleNum = (int)libraryWarningLogs.stream().filter(libraryWarningLog -> libraryWarningLog.getWarningHandle()==0).count();
        alarmSituation.setInventoryCount(inventoryNum);
        alarmSituation.setInOutCount(libraryWarningLogs.size()-inventoryNum);
        alarmSituation.setUntreatedCount(unHandleNum);
        return alarmSituation;
    }

    /**
     * @param type 类型（1：上半年，2：下半年）
     *             获取业务统计信息
     */
    @Override
    public List<BusinessSituation> getBusinessNum(Integer type) throws ParseException {
        List<BusinessSituation> businessSituations = new ArrayList<>();
        TaskSelectVo taskSelectVo = new TaskSelectVo();
        taskSelectVo.setSelectNum(3);
        TaskSelectVo taskSelectVo2 = new TaskSelectVo();
        taskSelectVo2.setSelectNum(2);
        //跟踪
        List<TaskUserVo> trackings = taskService.getList(taskSelectVo);
        //待办
        List<TaskUserVo> belongings = taskService.getList(taskSelectVo2);
        //筛选出来的上半年或下半年待办
        List<TaskUserVo> tasks;
        //筛选出来的上半年或下半年跟踪
        List<TaskUserVo> tasks2;
        //上半年
        if (type==1){
            List<Date> dates = getFirstHalfYear();
            //筛选出上半年待办
            tasks = belongings.stream()
                    .filter(taskUserVo -> taskUserVo.getCreateTime().after(dates.get(0))&&taskUserVo.getCreateTime().before(dates.get(1)))
                    .collect(Collectors.toList());
            //筛选出上半年跟踪
            tasks2 = trackings.stream()
                    .filter(taskUserVo -> taskUserVo.getCreateTime().after(dates.get(0))&&taskUserVo.getCreateTime().before(dates.get(1)))
                    .collect(Collectors.toList());
            businessSituations.add(countBusiness(tasks));
            businessSituations.add(countBusiness(tasks2));
            return businessSituations;
        }
        else if (type==2){
            List<Date> dates = getLastHalfYear();
            //筛选出下半年待办
            tasks = belongings.stream()
                    .filter(taskUserVo -> taskUserVo.getCreateTime().after(dates.get(0))&&taskUserVo.getCreateTime().before(dates.get(1)))
                    .collect(Collectors.toList());
            //筛选出下半年跟踪
            tasks2 = trackings.stream()
                    .filter(taskUserVo -> taskUserVo.getCreateTime().after(dates.get(0))&&taskUserVo.getCreateTime().before(dates.get(1)))
                    .collect(Collectors.toList());
            businessSituations.add(countBusiness(tasks));
            businessSituations.add(countBusiness(tasks2));
            return businessSituations;
        }
        else {
            throw new ApiException("type只能为1或2");
        }
    }

    /**
     * @param type 类型（1：本季度，2：本年）
     * 获取各市告警统计信息
     */
    @Override
    public List<AlarmSituation> getRfidWarningDetail(Integer type) {
        List<AlarmSituation> alarmSituations = new ArrayList<>();
        List<Area> areas = areaDao.findAreasByType(2);
        //每个市进行统计
        for (Area area: areas) {
            AlarmSituation alarmSituation = new AlarmSituation();
            alarmSituation.setArea(area.getName());
            //获取市以及子区县所有区域
            List<Area> areas1 = areaDao.findAllByFatherId(area.getId());
            areas1.add(area);
            //获取所有单位名称
            List<String> unitNames = new ArrayList<>();
            areas1.forEach(area1 -> {
                List<Units> units = unitsDao.findAllByAreaId(area1.getId());
                if (units.size() == 1) {
                    unitNames.add(units.get(0).getName());
                }
            });
            //获取当前季度
            Integer quarter = getQuarter(new Date());
            //获取当前季度该区域所有告警记录
            List<LibraryWarningLog> libraryWarningLogs;
            if (type==1) {
                libraryWarningLogs = libraryWarningLogDao.findAll().stream()
                        .filter(libraryWarningLog -> getQuarter(libraryWarningLog.getCreateTime()).equals(quarter) && unitNames.contains(libraryWarningLog.getUnit()))
                        .collect(Collectors.toList());
            }
            else if (type==2){
                int year = new Date().getYear();
                libraryWarningLogs = libraryWarningLogDao.findAll().stream()
                        .filter(libraryWarningLog -> libraryWarningLog.getCreateTime().getYear()==year && unitNames.contains(libraryWarningLog.getUnit()))
                        .collect(Collectors.toList());
            }
            else {
                throw new ApiException("type只能为1，2");
            }
            alarmSituation.setAlarmCount(libraryWarningLogs.size());
            //获取盘库异常数量
            int inventoryNum = (int)libraryWarningLogs.stream().filter(libraryWarningLog -> libraryWarningLog.getWarningType()==2).count();
            //获取未处理数量
            int unHandleNum = (int)libraryWarningLogs.stream().filter(libraryWarningLog -> libraryWarningLog.getWarningHandle()==0).count();
            alarmSituation.setInventoryCount(inventoryNum);
            alarmSituation.setInOutCount(libraryWarningLogs.size()-inventoryNum);
            alarmSituation.setUntreatedCount(unHandleNum);
            alarmSituations.add(alarmSituation);
        }
        return alarmSituations;
    }

    @Override
    public UserGeneralSituation getUserGeneralSituation() {
        int count= (int) userDao.findAllByIsDel(0).stream().filter(user -> user.getTrainStatus()!=5).count();
        int hasTraining= 0;
        List<UserSituationVo> list=new ArrayList<>();
        List<Integer> ids= userDao.findAll().stream().filter(user -> user.getTrainStatus()!=null&&(user.getTrainStatus() == 1 || user.getTrainStatus() == 2)).map(User::getUserId).collect(Collectors.toList());
        hasTraining=count-ids.size();
        userDao.findAllByUserIdIn(ids).forEach(
                user -> {
                    if (user.getUnitsId()!=0) {
                        Units units = unitsDao.findById(user.getUnitsId()).get();
                        String position = "专管员";
                        if (user.getPosition() == 0) {
                            position = "领导";
                        }
                        list.add(new UserSituationVo(user.getName(),
                                units.getName(), position, user.getMobile(), "未培训"));
                    }
                }
        );

        return new UserGeneralSituation(count,hasTraining,ids.size(),list);
    }

    /**
     * 获取工作台统计
     */
    @Override
    public WorkBench getWorkBenchStat() {
        Integer unit = userUtils.getCurrentUnitId();
        String unitName = userUtils.getCurrentUserUnitName();
        WorkBench workBench = new WorkBench();
        DeviceLibrarySelectVo deviceLibrarySelectVo = new DeviceLibrarySelectVo();
        deviceLibrarySelectVo.setAreaId(areaCache.findByName("浙江省").getId());
        workBench.setPackingNum(packingLibraryDao.findAllByIsRootAndPackingStatus(0,2).size());
        List<DeviceLibrary> deviceLibraries = deviceLibraryService.getCoreDevicePage(deviceLibrarySelectVo);
        workBench.setAllDeviceNum(deviceLibraries.size());
        workBench.setSelfDeviceNum(Long.valueOf(deviceLibraries.stream().filter(deviceLibrary -> deviceLibrary.getOwnUnit().equals(unitName)).count()).intValue());
        workBench.setMatchingDeviceNum(new Long(matchingDeviceLibraryDao.count()).intValue());
        workBench.setDailyDeviceNum(Long.valueOf(deviceLibraries.stream().filter(deviceLibrary -> deviceLibrary.getOwnUnit().equals(unitName)&&Arrays.asList(2,14).contains(deviceLibrary.getLifeStatus())).count()).intValue());
        List<Task> allTasks = taskDao.findAll();
        List<Task> tasks = allTasks.stream().filter(task -> task.getBusinessType()==7).collect(Collectors.toList());
        List<Task> tasks2 = allTasks.stream().filter(task -> task.getBusinessType()==4).collect(Collectors.toList());
        workBench.setCheckNum(Long.valueOf(tasks.stream().filter(task -> "check".equals(task.getCustomInfo())).count()).intValue());
        workBench.setCompleteCheckNum(Long.valueOf(tasks.stream().filter(task -> task.getBillStatus()==9999&&"check".equals(task.getCustomInfo())).count()).intValue());
        workBench.setExamNum(Long.valueOf(tasks.stream().filter(task -> task.getParentTaskId()==0&&"exam".equals(task.getCustomInfo())&&task.getOwnUnit().equals(unit)).count()).intValue());
        workBench.setExamCompleteNum(Long.valueOf(tasks.stream().filter(task -> task.getBillStatus()==9999&&task.getParentTaskId()==0&&"exam".equals(task.getCustomInfo())&&task.getOwnUnit().equals(unit)).count()).intValue());
        workBench.setSelfCheckNum(Long.valueOf(tasks2.stream().filter(task -> task.getBillStatus()==9999&&unit.equals(task.getOwnUnit())).count()).intValue());
        List<TrainTheme> themeList=trainThemeDao.findAll();
        workBench.setTrainNum(themeList.size());
        workBench.setTrainCompleteNum((int)themeList.stream().filter(trainTheme -> trainTheme.getTrainStatus()==9999).count());
        return workBench;
    }

    /**
     * 获取各市最近一次自查和核查装备数量
     */
    @Override
    public List<Check> getCheckNum() {
        List<Check> checks = new ArrayList<>();
        //获取所有自查单
        List<SelfCheckBill> selfCheckBills = selfCheckBillDao.findAll();
        //获取所有核查单
        List<DeviceCheckDetail> deviceCheckDetails = deviceCheckDetailDao.findAll();
        //获取所有市
        List<Area> areas = areaDao.findAreasByType(2);
        //遍历市，找到最近完成的自查和核查账单
        for (Area a:areas) {
            Check check = new Check();
            check.setAreaName(a.getName());
            List<Units> units = unitsDao.findAllByAreaId(a.getId());
            if (units.size()==1) {
                //获取市单位名称
                String unitName = units.get(0).getName();
                //筛选出当前单位已完成的自查和核查账单，按更新时间排序
                List<SelfCheckBill> selfCheckBillList = selfCheckBills.stream()
                        .filter(selfCheckBill -> selfCheckBill.getCheckUnit().equals(unitName) && selfCheckBill.getCheckedCount() != null)
                        .sorted(Comparator.nullsLast(Comparator.comparing(SelfCheckBill::getUpdateTime).reversed()))
                        .collect(Collectors.toList());
                List<DeviceCheckDetail> deviceCheckDetailList = deviceCheckDetails.stream()
                        .filter(deviceCheckDetail -> deviceCheckDetail.getCheckUnit().equals(unitName) && deviceCheckDetail.getCheckedCount() != null)
                        .sorted(Comparator.nullsLast(Comparator.comparing(DeviceCheckDetail::getUpdateTime).reversed()))
                        .collect(Collectors.toList());
                if (!selfCheckBillList.isEmpty()) {
                    check.setSelfCheckCount(selfCheckBillList.get(0).getCheckedCount());
                }
                if (!deviceCheckDetailList.isEmpty()) {
                    check.setConfirmCheckCount(deviceCheckDetailList.get(0).getCheckedCount());
                }
            }
            checks.add(check);
        }
        return checks;
    }

    /**
     * @param type 类型（1：上半年，2：下半年）
     *             获取核查统计信息
     */
    @Override
    public List<Verification> getConfirmCheck(Integer type) throws ParseException{
        List<Verification> verifications = new ArrayList<>();
        //获取所有市
        List<Area> areas = areaDao.findAreasByType(2);
        //获取所有核查详情单
        List<DeviceCheckDetail> deviceCheckDetails = deviceCheckDetailDao.findAll();
        List<Date> dates;
        if (type==1) {
            dates = getFirstHalfYear();
        }
        else if (type==2) {
            dates = getLastHalfYear();
        }
        else {
            throw new ApiException("type只能为1，2");
        }
        //获取各市上半年自动核查
        for (Area a:areas) {
            Verification verification = new Verification();
            int completeNum = 0;
            int unCompleteNum =0;
            verification.setAreaName(a.getName());
            //获取所有区县区域id
            List<Integer> sonAreas = areaDao.findAllByFatherId(a.getId()).stream().map(Area::getId).collect(Collectors.toList());
            //获取所有区县单位名称
            List<String> unitNames = unitsCache.findAll().stream().filter(units -> sonAreas.contains(units.getAreaId())).map(Units::getName).collect(Collectors.toList());
            for (String unitName:unitNames){
                //筛选出上半年的自动核查按时间排序
                List<DeviceCheckDetail> deviceCheckDetailList = deviceCheckDetails.stream()
                        .filter(deviceCheckDetail -> deviceCheckDetail.getTitle().contains("自动")&& deviceCheckDetail.getTitle().contains(unitName) && Date.from(deviceCheckDetail.getCreateTime().atZone(ZoneId.systemDefault()).toInstant()).after(dates.get(0))&& Date.from(deviceCheckDetail.getCreateTime().atZone(ZoneId.systemDefault()).toInstant()).before(dates.get(1)))
                        .sorted(Comparator.nullsLast(Comparator.comparing(DeviceCheckDetail::getCreateTime).reversed()))
                        .collect(Collectors.toList());
                if (deviceCheckDetailList.size()>0){
                    if (deviceCheckDetailList.get(0).getCheckStatus()==2){
                        completeNum++;
                    }
                    else {
                        unCompleteNum++;
                    }
                }
            }
            verification.setCompleteCount(completeNum);
            verification.setNoCompleteCount(unCompleteNum);
            verifications.add(verification);
        }
        return verifications;
    }

    /**
     * @param devLifeSector 装备生命状态添统计
     * @param deviceLibraries 统计装备
     * 计算并set devLifeSector中各种生命状态装备数量
     */
    private void countDevice(DevLifeSector devLifeSector,List<DeviceLibrary> deviceLibraries){
        int inLibrary = 0;
        int destroy = 0;
        int retired = 0;
        int use = 0;
        int scrap = 0;
        int repair = 0;
        int transport = 0;
        for (DeviceLibrary d:deviceLibraries) {
            switch (d.getLifeStatus()){
                case 2:
                    inLibrary++;
                    break;
                case 3:
                    transport++;
                    break;
                case 4:
                    repair++;
                    break;
                case 5:
                    scrap++;
                    break;
                case 10:
                    destroy++;
                    break;
                case 12:
                    retired++;
                    break;
                case 13:
                    scrap++;
                    break;
                case 14:
                    use++;
                    break;
                default:break;
            }
        }
        devLifeSector.setDestructionCount(destroy);
        devLifeSector.setInStock(inLibrary);
        devLifeSector.setLockCount(transport);
        devLifeSector.setMaintenanceCount(repair);
        devLifeSector.setRetiredCount(retired);
        devLifeSector.setScrapCount(scrap);
        devLifeSector.setUseCount(use);
    }

    /**
     * @param areaId 市区域id
     * @param quarter 季度（例如：2020年第一季度，2020年第二季度，2020年第三季度，2020年第四季度）
     * @param selfCheckBills 自查单
     * @return 未完成区域
     * 计算并返回某季度某区域未完成区县
     */
    private List<Area> getSelfCheckUndoAreas(int areaId,String quarter,List<SelfCheckBill> selfCheckBills){
        //获取所有区县
        List<Area> sonAreas = areaDao.findAllByFatherId(areaId);
        //未完成区域
        List<Area> undoAreas = new ArrayList<>();
        //遍历区县
        sonAreas.forEach(area -> {
            //获取区域对应单位
            List<Units> units = unitsDao.findAllByAreaId(area.getId());
            if (units.size()==1){
                //筛选出标题包含当前年份季度的
                List<SelfCheckBill> selfCheckBillList = selfCheckBills.stream()
                        .filter(selfCheckBill -> selfCheckBill.getTitle().contains(quarter)&&selfCheckBill.getCheckUnit().equals(units.get(0).getName()))
                        .collect(Collectors.toList());
                if(selfCheckBillList.size()==1){
                    SelfCheckBill selfCheckBill = selfCheckBillList.get(0);
                    //如果未完成
                    if (selfCheckBill.getCheckStatus()!=2){
                        undoAreas.add(area);
                    }
                }
            }
        });
        return undoAreas;
    }

    /**
     * @param perQuarter 被set的对象
     * @param sonAreas 子区县
     * @param undoAreas 未完成自查区县
     */
    private void setPerQuarter(PerQuarter perQuarter,List<Area> sonAreas,List<Area> undoAreas){
        if (!undoAreas.isEmpty()) {
            perQuarter.setNoCompleteUnits(undoAreas.stream().map(Area::getName).collect(Collectors.toList()));
        }
        else {
            perQuarter.setNoCompleteUnits(new ArrayList<>());
        }
        perQuarter.setNoCompleteCount(undoAreas.size());
        perQuarter.setCompleteCount(sonAreas.size()-undoAreas.size());
    }

    /**
     * 获取上半年开始时间和结束时间
     */
    private List<Date> getFirstHalfYear() throws ParseException {
        List<Date> dates = new ArrayList<>();
        //获取当前年份
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int year = calendar.get(Calendar.YEAR);
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = dateformat.parse(year+"-1-1");
        Date date2 = dateformat.parse(year+"-7-1");
        dates.add(date1);
        dates.add(date2);
        return dates;
    }

    /**
     * 获取下半年开始时间和结束时间
     */
    private List<Date> getLastHalfYear() throws ParseException {
        List<Date> dates = new ArrayList<>();
        //获取当前年份
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int year = calendar.get(Calendar.YEAR);
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = dateformat.parse(year+"-7-1");
        Date date2 = dateformat.parse((year+1)+"-1-1");
        dates.add(date1);
        dates.add(date2);
        return dates;
    }

    private BusinessSituation countBusiness(List<TaskUserVo> tasks){
        int withCount = 0;
        int sendRepelCount = 0;
        int selfInspection = 0;
        int verification = 0;
        int train = 0;
        int putStorage = 0;
        int apply = 0;
        int fielding = 0;
        int backPack = 0;
        int destruction = 0;
        int maintenance = 0;
        for (TaskUserVo task: tasks) {
            switch (task.getBusinessType()){
                case 1:
                    fielding++;
                    break;
                case 2:
                    putStorage++;
                    break;
                case 3:
                    withCount++;
                    break;
                case 4:
                    selfInspection++;
                    break;
                case 5:
                    maintenance++;
                    break;
                case 7:
                    verification++;
                    break;
                case 9:
                    apply++;
                    break;
                case 13:
                    train++;
                    break;
                case 14:
                    destruction++;
                    break;
                case 15:
                    backPack++;
                    break;
                case 16:
                    sendRepelCount++;
                    break;
                default:break;
            }
        }
        return new BusinessSituation(withCount,sendRepelCount,selfInspection,verification,train,putStorage,apply,fielding,backPack,destruction,maintenance);
    }

    /**
     * 当前date属于本年第几个季度
     */
    private Integer getQuarter(Date date) {
        int month = date.getMonth()+1;
        if (month <= 3) {
            return 1;
        } else if (month <= 6) {
            return 2;
        } else if (month <= 9) {
            return 3;
        } else {
            return 4;
        }
    }

}
