package com.tykj.dev.device.usereport.service.impl;

import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
import com.tykj.dev.blockcha.subject.entity.BcHash;
import com.tykj.dev.blockcha.subject.service.BlockChainUtil;
import com.tykj.dev.config.base.DeviceLifeStatus;
import com.tykj.dev.device.allot.repository.AllotBackBillDao;
import com.tykj.dev.device.allot.repository.AllotBillDao;
import com.tykj.dev.device.allot.subject.domin.AllotBackBill;
import com.tykj.dev.device.allot.subject.domin.AllotBill;
import com.tykj.dev.device.destroy.repository.DeviceDestroyBillDao;
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.packing.repository.PackingLibraryDao;
import com.tykj.dev.device.packing.subject.domin.PackingLibrary;
import com.tykj.dev.device.repair.repository.RepairBackBillDao;
import com.tykj.dev.device.repair.repository.RepairDetailDao;
import com.tykj.dev.device.repair.repository.RepairSendBillDao;
import com.tykj.dev.device.repair.subject.domin.RepairBackBill;
import com.tykj.dev.device.repair.subject.domin.RepairSendBill;
import com.tykj.dev.device.scrap.repository.ScrapBillDao;
import com.tykj.dev.device.sendback.entity.vo.PagingVo;
import com.tykj.dev.device.sendback.entity.vo.RepelManagementVo;
import com.tykj.dev.device.sendback.service.RepelQueryService;
import com.tykj.dev.device.storage.repository.StorageBillDao;
import com.tykj.dev.device.storage.subject.domin.StorageBill;
import com.tykj.dev.device.user.subject.service.UserPublicService;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.device.usereport.repository.DeviceUseReportDao;
import com.tykj.dev.device.usereport.service.DeviceUseReportService;
import com.tykj.dev.device.usereport.subject.domin.DeviceUseReport;
import com.tykj.dev.device.usereport.subject.vo.DeviceStatistics;
import com.tykj.dev.device.usereport.subject.vo.DeviceUseReportCreateVo;
import com.tykj.dev.device.usereport.subject.vo.DeviceUseReportSelectVo;
import com.tykj.dev.misc.utils.JacksonUtil;
import com.tykj.dev.misc.utils.StringSplitUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.util.*;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;

/**
 * @author dengdiyi
 */
@Service
public class DeviceUseReportServiceImpl implements DeviceUseReportService {


    @Autowired
    private DeviceUseReportDao deviceUseReportDao;
    @Autowired
    private UserUtils userUtils;
    @Autowired
    private DeviceLibraryService deviceLibraryService;
    @Autowired
    private StorageBillDao storageBillDao;
    @Autowired
    private UserPublicService userPublicService;

    @Autowired
    private AllotBillDao allotBillDao;

    @Autowired
    DeviceLibraryDao deviceLibraryDao;

    @Autowired
    private DeviceDestroyBillDao deviceDesroyBillDao;

    @Autowired
    private RepelQueryService repelQueryService;

    @Autowired
    private RepairSendBillDao repairSendBillDao;

    @Autowired
    private RepairBackBillDao repairBackBillDao;

    @Autowired
    private ScrapBillDao scrapBillDao;

    @Autowired
    private PackingLibraryDao packingLibraryDao;

    @Autowired
    private RepairDetailDao repairDetailDao;

    @Autowired
    private BlockChainUtil blockChainUtil;
    @Autowired
    private AllotBackBillDao allotBackBillDao;

    @Override
    public DeviceUseReport addEntity(DeviceUseReport deviceUseReportEntity) {
        return deviceUseReportDao.save(deviceUseReportEntity);
    }

    /**
     * @param deviceUseReports 异步上链
     */
    @Override
    @Async
    public void sendHash(List<DeviceUseReport> deviceUseReports) {
        deviceUseReports.forEach(deviceUseReport -> {
            BcHash bcText = blockChainUtil.sendHash(1000, JacksonUtil.toJSon(deviceUseReport));
            String recordId = bcText.getData().getRecordID();
            deviceUseReport.setRecordId(recordId);
            update(deviceUseReport);
        });
    }

    @Override
    public Page<DeviceUseReport> getPage(DeviceUseReportSelectVo deviceUseReportSelectVo, Pageable pageable) {
        return deviceUseReportDao.findAll(getSelectSpecification(deviceUseReportSelectVo), deviceUseReportSelectVo.getPageable());
    }

    @Override
    public DeviceUseReport getOne(Integer id) {
        Optional<DeviceUseReport> deviceUseReportEntity = deviceUseReportDao.findById(id);
        return deviceUseReportEntity.orElse(null);
    }

    @Override
    public DeviceUseReport update(DeviceUseReport deviceUseReportEntity) {
//        blockChainUtil.appendHash(JacksonUtil.toJSon(deviceUseReportEntity),deviceUseReportEntity.getRecordId());
        return deviceUseReportDao.save(deviceUseReportEntity);
    }

//    @Override
//    public DeviceUseReport createReport(DeviceUseReportCreateVo deviceUseReportCreateVo) {
//        DeviceUseReport deviceUseReportEntity = new DeviceUseReport();
//        deviceUseReportEntity.setUnit(userUtils.getCurrentUserUnitName());
//        deviceUseReportEntity.setStartTime(deviceUseReportCreateVo.getStartTime());
//        deviceUseReportEntity.setEndTime(deviceUseReportCreateVo.getEndTime());
//        StringBuffer stringBuffer = new StringBuffer();
//        //按照开始时间和结束时间设置标题
//        Date date = deviceUseReportCreateVo.getStartTime();
//        Date date2 = deviceUseReportCreateVo.getEndTime();
//        Calendar calendar = Calendar.getInstance();
//        Calendar calendar2 = Calendar.getInstance();
//        calendar.setTime(date);
//        calendar2.setTime(date2);
//        stringBuffer.append(calendar.get(Calendar.YEAR)).append("年");
//        stringBuffer.append(calendar.get(Calendar.MONTH) + 1).append("月");
//        stringBuffer.append(calendar.get(Calendar.DAY_OF_MONTH)).append("日");
//        stringBuffer.append("至");
//        stringBuffer.append(calendar2.get(Calendar.YEAR)).append("年");
//        stringBuffer.append(calendar2.get(Calendar.MONTH) + 1).append("月");
//        stringBuffer.append(calendar2.get(Calendar.DAY_OF_MONTH)).append("日");
//        stringBuffer.append("使用情况报告");
//        deviceUseReportEntity.setTitle(stringBuffer.toString());
//        //获取所属当前单位的所有装备
//        DeviceLibrarySelectVo deviceLibrarySelectVo = new DeviceLibrarySelectVo();
//        deviceLibrarySelectVo.setSize(Integer.MAX_VALUE);
//        List<DeviceLibrary> deviceLibraryEntities = deviceLibraryService.getPage(deviceLibrarySelectVo, deviceLibrarySelectVo.getPageable()).getContent();
//        int num = deviceLibraryEntities.size();
//        int inLibraryNum = 0;//入库
//        int repairNum;//维修
//        int destoryNum = 0;
//        int allotNum = 0;
//        int sendBackNum = 0;
//        int packingNum = 0;
//        int retiredNum = 0;
//        //筛选出日期范围内所有入库账单
//        List<StorageBill> storageBillEntities = storageBillDao.findAll().stream()
//                .filter(storageBillEntity -> storageBillEntity.getStorageStatus() == 2 && userUtils.getCurrentUserUnitName().equals(userPublicService.findUnitsNameByUserId(storageBillEntity.getReceiveUseraId())) && storageBillEntity.getUpdateTime().after(date) && storageBillEntity.getUpdateTime().before(date2))
//                .collect(toList());
//        //累加入库数量
//        if (storageBillEntities.size() > 0) {
//            for (StorageBill s : storageBillEntities) {
//                inLibraryNum = inLibraryNum + s.getStoragedCount();
//            }
//        }
//        //配发状态list
//        List<Integer> allotStatusList = new ArrayList<>();
//        allotStatusList.add(2);
//        allotStatusList.add(3);
//        allotStatusList.add(5);
//        //筛选出接收配发装备的账单
//        List<AllotBill> allotBillEntities = allotBillDao.findAll().stream()
//                .filter(allotBillEntity -> allotBillEntity.getAllotStatus() == 5 && userUtils.getCurrentUserUnitName().equals(allotBillEntity.getReceiveUnit()) && allotBillEntity.getReceiveTime().after(date) && allotBillEntity.getReceiveTime().before(date2))
//                .collect(toList());
//        //筛选出配发给其它单位的账单
//        List<AllotBill> allotBillEntities2 = allotBillDao.findAll().stream()
//                .filter(allotBillEntity -> allotStatusList.contains(allotBillEntity.getAllotStatus()) && userUtils.getCurrentUserUnitName().equals(userPublicService.findUnitsNameByUserId(allotBillEntity.getSendUseraId())) && allotBillEntity.getSendTime().after(date) && allotBillEntity.getSendTime().before(date2))
//                .collect(toList());
//        //退回状态list
//        List<Integer> allotStatusBackList = new ArrayList<>();
//        allotStatusBackList.addAll(Arrays.asList(0,3));
//        //筛选出配接收退回的账单
//        List<AllotBackBill> allotBackBills = allotBackBillDao.findAll().stream()
//                .filter(allotBackBill -> allotBackBill.getBackStatus() == 3 && userUtils.getCurrentUserUnitName().equals(allotBackBill.getReceiveUnit()) && allotBackBill.getReceiveTime().after(date) && allotBackBill.getReceiveTime().before(date2))
//                .collect(toList());
////        //筛选出退回给其它单位的账单
////        List<AllotBackBill> allotBackBills2 = allotBackBillDao.findAll().stream()
////                .filter(allotBackBill -> allotStatusBackList.contains(allotBackBill.getBackStatus()) && userUtils.getCurrentUserUnitName().equals(userPublicService.findUnitsNameByUserId(allotBackBill.getSendUseraId())) && allotBackBill.getSendTime().after(date) && allotBackBill.getSendTime().before(date2))
////                .collect(toList());
//
//
//        //累加入库数量
//        if (allotBillEntities.size() > 0) {
//            for (AllotBill s : allotBillEntities) {
////                inLibraryNum = inLibraryNum + s.getReceiveCount();
//                inLibraryNum = inLibraryNum + s.getAllotCount();
//            }
//        }
//        //累加配发退回数量
//        if (allotBackBills.size() > 0) {
//            for (AllotBackBill allotBackBill : allotBackBills) {
//                inLibraryNum = inLibraryNum + allotBackBill.getBackCount();
//            }
//        }
//        //累加配发数量
//        if (allotBillEntities2.size() > 0) {
//            for (AllotBill s : allotBillEntities2) {
//                allotNum = allotNum + s.getAllotedCount();
//            }
//        }
//
//        //省级才能销毁,列装,退装
//        if (userUtils.getCurrentUnitLevel() == 1) {
//            //筛选出在日期范围内的销毁单
////            List<DeviceDestroyBill> deviceDestoryBillEntities = deviceDestroyBillDao.findAll().stream()
////                    .filter(deviceDestoryBillEntity -> deviceDestoryBillEntity.getDestroyStatus() == 2 && deviceDestoryBillEntity.getDestroyTime()!=null&&deviceDestoryBillEntity.getDestroyTime().after(date) && deviceDestoryBillEntity.getDestroyTime().before(date2))
////                    .collect(toList());
////            //累加销毁数量
////            if (deviceDestoryBillEntities.size() > 0) {
////                for (DeviceDestroyBill s : deviceDestoryBillEntities) {
////                    List<Integer> list = StringSplitUtil.split(s.getDestroyDeviceDetail());
////                    destoryNum = destoryNum + list.size();
////                }
////            }
//            //筛选列装
//            List<PackingLibrary> packingLibraryEntities = packingLibraryDao.findAll().stream()
//                    .filter(packingLibraryEntity -> packingLibraryEntity.getPackingStatus()!=null&&packingLibraryEntity.getPackingStatus() == 2 &&packingLibraryEntity.getCreateTime()!=null && packingLibraryEntity.getCreateTime().after(date) && packingLibraryEntity.getCreateTime().before(date2))
//                    .collect(toList());
//            //筛选退装
//            List<PackingLibrary> packingLibraryEntities2 = packingLibraryDao.findAll().stream()
//                    .filter(packingLibraryEntity -> packingLibraryEntity.getPackingStatus()!=null&&packingLibraryEntity.getPackingStatus() == 3 && packingLibraryEntity.getExitTime()!=null&&packingLibraryEntity.getExitTime().after(date) && packingLibraryEntity.getExitTime().before(date2))
//                    .collect(toList());
//            //添加列装数量
//            if (packingLibraryEntities.size() > 0) {
//                packingNum = packingNum + packingLibraryEntities.size();
//            }
//            //添加退装数量
//            if (packingLibraryEntities2.size() > 0) {
//                retiredNum = retiredNum + packingLibraryEntities2.size();
//            }
//        }
//
//        //筛选出清退账单
//        RepelManagementVo repelManagementVo=new RepelManagementVo();
//        repelManagementVo.setUnitName(userUtils.getCurrentUserUnitName());
//        repelManagementVo.setPage(0);
//        repelManagementVo.setSize(2);
//        repelManagementVo.setTime(deviceUseReportCreateVo.startTime.getTime());
//        repelManagementVo.setEndTime(deviceUseReportCreateVo.endTime.getTime());
//        PagingVo pagingVo = repelQueryService.clearedDeviceList(repelManagementVo);
//        sendBackNum=pagingVo.getTotal();
////        //累加清退数量
////        if (sendBackBillDetailEntities.size() > 0) {
////            for (SendBackBillDetail s : sendBackBillDetailEntities) {
////                sendBackNum = sendBackNum + s.getSendedCount();
////            }
////        }
//        //维修数量
//        List<RepairDetail> repairDetails = repairDetailDao.findAll().stream()
//                .filter(repairDetail -> repairDetail.getOwnUnit().equals(userUtils.getCurrentUserUnitName()) && repairDetail.getRepairStatus() != 3 && repairDetail.getCreateTime().after(date) && repairDetail.getCreateTime().before(date2))
//                .collect(toList());
//        //筛选出配接收维修退回的账单
//        List<Integer> repairBackList = new ArrayList<>();
//        repairBackList.addAll(Arrays.asList(5,7));
//        List<RepairBackBill> repairBackBills = repairBackBillDao.findAll().stream()
//                .filter(repairBackBill -> repairBackBill.getReceiveUnit().equals(userUtils.getCurrentUserUnitName()) && repairBackList.contains(repairBackBill.getBackStatus()) && repairBackBill.getCreateTime().after(date) && repairBackBill.getCreateTime().before(date2))
//                .collect(toList());
//        //将数量进行新增 累加维修数量
//        if (repairBackBills.size() >0){
//            for (RepairBackBill repairBackBill : repairBackBills) {
//                inLibraryNum = inLibraryNum + repairBackBill.getReceiveCount();
//            }
//        }
//
//        repairNum = repairDetails.size();
//
//
//        //拼接组合字段
//        deviceUseReportEntity.setReportDetail(num + "x" + inLibraryNum + "x" + repairNum + "x" + allotNum + "x" + sendBackNum + "x" + destoryNum + "x" + packingNum + "x" + retiredNum + "x");
//        return deviceUseReportDao.save(deviceUseReportEntity);
//    }
    @Override
    public DeviceUseReport createReport(DeviceUseReportCreateVo deviceUseReportCreateVo) {
        DeviceUseReport deviceUseReportEntity = new DeviceUseReport();
        deviceUseReportEntity.setUnit(userUtils.getCurrentUserUnitName());
        deviceUseReportEntity.setStartTime(deviceUseReportCreateVo.getStartTime());
        deviceUseReportEntity.setEndTime(deviceUseReportCreateVo.getEndTime());
        StringBuffer stringBuffer = new StringBuffer();
        //按照开始时间和结束时间设置标题
        Date date = deviceUseReportCreateVo.getStartTime();
        Date date2 = deviceUseReportCreateVo.getEndTime();
        Calendar calendar = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();
        calendar.setTime(date);
        calendar2.setTime(date2);
        stringBuffer.append(calendar.get(Calendar.YEAR)).append("年");
        stringBuffer.append(calendar.get(Calendar.MONTH) + 1).append("月");
        stringBuffer.append(calendar.get(Calendar.DAY_OF_MONTH)).append("日");
        stringBuffer.append("至");
        stringBuffer.append(calendar2.get(Calendar.YEAR)).append("年");
        stringBuffer.append(calendar2.get(Calendar.MONTH) + 1).append("月");
        stringBuffer.append(calendar2.get(Calendar.DAY_OF_MONTH)).append("日");
        stringBuffer.append("使用情况报告");
        deviceUseReportEntity.setTitle(stringBuffer.toString());

        //获取所属当前单位的所有装备
        DeviceLibrarySelectVo deviceLibrarySelectVo = new DeviceLibrarySelectVo();
        deviceLibrarySelectVo.setSize(Integer.MAX_VALUE);
        List<DeviceLibrary> deviceLibraryEntities = deviceLibraryService.getPage(deviceLibrarySelectVo, deviceLibrarySelectVo.getPageable()).getContent();
        int num = deviceLibraryEntities.size();
        int inLibraryNum = 0;//入库
        int sendRepairNum = 0;//送修
        int receiveRepairNum = 0;//维修退回
        int destoryNum = 0;//销毁
        int sendAllotNum = 0;//发起配发
        int receiveAllotNum = 0;//接收配发
        int sendAllotBackNum = 0;//发起退回
        int receiveAllotBackNum = 0;//接收退回
        int sendBackNum = 0;//清退
        int packingNum = 0;//列装
        int retiredNum = 0;//退装
        int scrapStatisticsNum = 0;//报废
        int decommissioningStatisticsNum = 0;//退役
        int toRepairBackNum = 0;//向下级进行维修退回
        int toRepairNum = 0;// 接收下级单位维修
        //筛选出日期范围内所有入库账单
        List<StorageBill> storageBillEntities = storageBillDao.findAll().stream()
                .filter(storageBillEntity -> storageBillEntity.getStorageStatus() == 2 && userUtils.getCurrentUserUnitName().equals(userPublicService.findUnitsNameByUserId(storageBillEntity.getReceiveUseraId())) && storageBillEntity.getUpdateTime().after(date) && storageBillEntity.getUpdateTime().before(date2))
                .collect(toList());
        //累加入库数量
        if (storageBillEntities.size() > 0) {
            for (StorageBill s : storageBillEntities) {
                inLibraryNum = inLibraryNum + s.getStoragedCount();
            }
        }
        //配发状态list
        List<Integer> allotStatusList = new ArrayList<>(Arrays.asList(2, 3, 5));
        //筛选出接收配发装备的账单    接收配发
        List<AllotBill> allotBillEntities = allotBillDao.findAll().stream()
                .filter(allotBillEntity -> allotBillEntity.getAllotStatus() == 5 && userUtils.getCurrentUserUnitName().equals(allotBillEntity.getReceiveUnit()) && allotBillEntity.getReceiveTime().after(date) && allotBillEntity.getReceiveTime().before(date2))
                .collect(toList());
        //筛选出配发给其它单位的账单  发起配发
        List<AllotBill> allotBillEntities2 = allotBillDao.findAll().stream()
                .filter(allotBillEntity -> allotStatusList.contains(allotBillEntity.getAllotStatus()) && userUtils.getCurrentUserUnitName().equals(userPublicService.findUnitsNameByUserId(allotBillEntity.getSendUseraId())) && allotBillEntity.getSendTime().after(date) && allotBillEntity.getSendTime().before(date2))
                .collect(toList());
        //接收配发装备
        if (allotBillEntities.size() > 0) {
            for (AllotBill s : allotBillEntities) {
                int receiveAllotCount = s.getAllotedCount() == null ? s.getReceiveCount():s.getAllotedCount();
                receiveAllotNum = receiveAllotNum + receiveAllotCount;
            }
        }
        //发起配发
        if (allotBillEntities2.size()>0){
            for (AllotBill allotBill : allotBillEntities2) {
                int addAllotCount = allotBill.getAllotedCount() == null ? allotBill.getReceiveCount():allotBill.getAllotedCount();
                sendAllotNum = sendAllotNum + addAllotCount;
            }
        }
        //退回状态list
        List<Integer> allotStatusBackList = new ArrayList<>(Arrays.asList(0, 3));
        List<AllotBackBill> receiveAllotBackBills = allotBackBillDao.findAll().stream()
                .filter(allotBackBill -> allotBackBill.getBackStatus() == 3 && userUtils.getCurrentUserUnitName().equals(allotBackBill.getReceiveUnit()) && allotBackBill.getReceiveTime().after(date) && allotBackBill.getReceiveTime().before(date2))
                .collect(toList());
        //接收退回
        if (receiveAllotBackBills.size()>0){
            for (AllotBackBill receiveAllotBackBill : receiveAllotBackBills) {
                int receiveBackCount = receiveAllotBackBill.getBackCount() == null ? receiveAllotBackBill.getReceiveCount():receiveAllotBackBill.getBackCount();

                receiveAllotBackNum = receiveAllotBackNum + receiveBackCount;
            }
        }
        //筛选出配接收退回的账单  接收退回
        if (userUtils.getCurrentUnitLevel() != 1){
            //发起退回
            List<AllotBackBill> sendAllotBackBills = allotBackBillDao.findAll().stream()
                    .filter(allotBackBill -> allotStatusBackList.contains(allotBackBill.getBackStatus()) && userUtils.getCurrentUserUnitName().equals(allotBackBill.getSendUnit()) && allotBackBill.getSendTime().after(date) && allotBackBill.getSendTime().before(date2))
                    .collect(toList());
            //发起退回
            if (sendAllotBackBills.size()>0){
                for (AllotBackBill sendAllotBackBill : sendAllotBackBills) {
                    int addBackCount = sendAllotBackBill.getBackCount() == null ? sendAllotBackBill.getReceiveCount():sendAllotBackBill.getBackCount();

                    sendAllotBackNum = sendAllotBackNum + addBackCount;
                }
            }
        }

        //省级才能销毁,列装,退装 退役 报废
        if (userUtils.getCurrentUnitLevel() == 1) {
            //报废
            int scrapStatisticsCount = this.getScrapStatisticsCount(date, date2);
            scrapStatisticsNum = scrapStatisticsCount;
            //销毁
            int destroyStatisticsCount = this.getDestroyStatisticsCount(date, date2);
            destoryNum = destroyStatisticsCount;
            //退役
            int decommissioningStatisticsCount = this.getDecommissioningStatisticsCount(date, date2);
            decommissioningStatisticsNum = decommissioningStatisticsCount;
            //筛选列装
            List<PackingLibrary> packingLibraryEntities = packingLibraryDao.findAll().stream()
//                    .filter(packingLibraryEntity -> packingLibraryEntity.getPackingStatus()!=null&&packingLibraryEntity.getPackingStatus() == 2 &&packingLibraryEntity.getCreateTime()!=null && packingLibraryEntity.getCreateTime().after(date) && packingLibraryEntity.getCreateTime().before(date2))
                    .filter(packingLibraryEntity -> packingLibraryEntity.getPackingStatus()!=null&&packingLibraryEntity.getPackingStatus() == 2)
                    .collect(toList());
            //筛选退装
            List<PackingLibrary> packingLibraryEntities2 = packingLibraryDao.findAll().stream()
                    .filter(packingLibraryEntity -> packingLibraryEntity.getPackingStatus()!=null&&packingLibraryEntity.getPackingStatus() == 3)
                    .collect(toList());
            //添加列装数量
            if (packingLibraryEntities.size() > 0) {
                packingNum = packingNum + packingLibraryEntities.size();
            }
            //添加退装数量
            if (packingLibraryEntities2.size() > 0) {
                retiredNum = retiredNum + packingLibraryEntities2.size();
            }
        }

        //筛选出清退账单
        RepelManagementVo repelManagementVo=new RepelManagementVo();
        repelManagementVo.setUnitId(userUtils.getCurrentUnitId());
        repelManagementVo.setPage(0);
        repelManagementVo.setSize(2);
        repelManagementVo.setTime(deviceUseReportCreateVo.startTime.getTime());
        repelManagementVo.setEndTime(deviceUseReportCreateVo.endTime.getTime());
        PagingVo pagingVo = repelQueryService.clearedDeviceList(repelManagementVo);
        sendBackNum=pagingVo.getTotal();
        //维修数量
//        List<RepairDetail> repairDetails = repairDetailDao.findAll().stream()
//                .filter(repairDetail -> repairDetail.getOwnUnit().equals(userUtils.getCurrentUserUnitName()) && repairDetail.getRepairStatus() != 3 && repairDetail.getCreateTime().after(date) && repairDetail.getCreateTime().before(date2))
//                .collect(toList());
        List<Integer> toUpRepairStatusList = new ArrayList<>(Arrays.asList(5,2,3,4));
        //向上送修
        List<RepairSendBill> repairDetails = repairSendBillDao.findAll().stream()
                .filter(repairSendBill -> repairSendBill.getSendUnit().equals(userUtils.getCurrentUserUnitName()) && toUpRepairStatusList.contains(repairSendBill.getRepairStatus()) && repairSendBill.getUpdateTime().after(date) && repairSendBill.getUpdateTime().before(date2))
                .collect(toList());
        //发起维修数量
        if(repairDetails.size()>0){
            for (RepairSendBill repairDetail : repairDetails) {
                int addRepairCount = repairDetail.getSendingCount() == null ? repairDetail.getReceiveCount():repairDetail.getSendingCount();

                sendRepairNum = sendRepairNum + addRepairCount;
            }
        }

        // 接收下级维修
        List<RepairSendBill> toUpRepairList = repairSendBillDao.findAll().stream()
                .filter(repairSendBill -> repairSendBill.getReceiveUnit().equals(userUtils.getCurrentUserUnitName()) && toUpRepairStatusList.contains(repairSendBill.getRepairStatus()) && repairSendBill.getUpdateTime().after(date) && repairSendBill.getUpdateTime().before(date2))
                .collect(toList());
        if (toUpRepairList.size()>0){
            for (RepairSendBill repairSendBill : toUpRepairList) {
                int receiveRepairCount = repairSendBill.getSendingCount() == null ? repairSendBill.getReceiveCount():repairSendBill.getSendingCount();

                toRepairNum = toRepairNum + receiveRepairCount;
            }
        }
        //筛选出配接收维修退回的账单
        List<Integer> repairBackList = new ArrayList<>(Arrays.asList(5,2));

        List<RepairBackBill> repairBackBills = repairBackBillDao.findAll().stream()
                .filter(repairBackBill -> repairBackBill.getReceiveUnit().equals(userUtils.getCurrentUserUnitName()) && repairBackList.contains(repairBackBill.getBackStatus()) && repairBackBill.getUpdateTime().after(date) && repairBackBill.getUpdateTime().before(date2))
                .collect(toList());

        //筛选出向下级的维修退回
        List<RepairBackBill> repairBackBillList = repairBackBillDao.findAll().stream()
                .filter(repairBackBill -> repairBackBill.getSendUnit().equals(userUtils.getCurrentUserUnitName()) && repairBackList.contains(repairBackBill.getBackStatus()) && repairBackBill.getUpdateTime().after(date) && repairBackBill.getUpdateTime().before(date2))
                .collect(toList());

        //将数量进行新增 累加数量
        if (repairBackBills.size() >0){
            for (RepairBackBill repairBackBill : repairBackBills) {
                int toRepairBackSendingCount = repairBackBill.getSendingCount() == null ? repairBackBill.getReceiveCount():repairBackBill.getSendingCount();

                receiveRepairNum = receiveRepairNum + toRepairBackSendingCount;
            }
        }
        //将数量进行新增 累加维修数量
        if (repairBackBillList.size() >0){
            for (RepairBackBill repairBackBill : repairBackBillList) {
                int toRepairBackSendingCount = repairBackBill.getSendingCount() == null ? repairBackBill.getReceiveCount():repairBackBill.getSendingCount();
                toRepairBackNum = toRepairBackNum + toRepairBackSendingCount;
            }
        }

        //拼接组合字段
        deviceUseReportEntity.setReportDetail(
                num + "x" + inLibraryNum + "x" + sendRepairNum + "x" 
                        + receiveRepairNum + "x" + destoryNum 
                        + "x" + sendAllotNum + "x" + receiveAllotNum + "x" + sendAllotBackNum
                        + "x"+ receiveAllotBackNum + "x"+ sendBackNum + "x"+ scrapStatisticsNum
                        + "x"+ packingNum + "x"+ retiredNum + "x"+ decommissioningStatisticsNum + "x"+toRepairBackNum+"x"+toRepairNum+"x");
        return deviceUseReportDao.save(deviceUseReportEntity);
    }

    /**
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 这一段时间省入库的统计
     */
    @Override
    public List<DeviceStatistics> getStorageStatistics(Date startDate, Date endDate) {
        List<DeviceLibrary> deviceLibraries = new ArrayList<>();
        //获取这一段时间所有入库的装备
        //筛选出日期范围内所有入库账单
        List<StorageBill> storageBillEntities = storageBillDao.findAll().stream()
                .filter(storageBillEntity -> storageBillEntity.getStorageStatus() == 2 && userPublicService.findByUnitsToname(1).equals(userPublicService.findUnitsNameByUserId(storageBillEntity.getReceiveUseraId())) && storageBillEntity.getUpdateTime().after(startDate) && storageBillEntity.getUpdateTime().before(endDate))
                .collect(toList());
        //获取所有入库的装备
        if (storageBillEntities.size() > 0) {
            for (StorageBill s : storageBillEntities) {
                List<Integer> integerList = StringSplitUtil.userIdSplit(s.getStorageDetail());
//                deviceLibraries.addAll(integerList.stream()
//                        .map(deviceLibraryService::getOne)
//                        .filter(Objects::nonNull)
//                        .distinct()
//                        .collect(toList()));
                deviceLibraries.addAll(deviceLibraryDao.findAllByIdIn(integerList));
            }
        }
        return getDeviceStatistics(deviceLibraries);
    }

    @Override
    public List<DeviceStatistics> getAllotStatistics(Date startDate, Date endDate) {
        return null;
    }

    /**
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 这一段时间省送国家维修的统计
     */
    @Override
    public List<DeviceStatistics> getRepairStatistics(Date startDate, Date endDate) {
        List<DeviceLibrary> deviceLibraries = new ArrayList<>();
        //筛选出日期范围内所有送修账单
        List<RepairSendBill> repairSendBills = repairSendBillDao.findAll().stream()
                .filter(repairSendBill -> repairSendBill.getRepairStatus() == 5 && userPublicService.findByUnitsToname(1).equals(repairSendBill.getSendUnit()) && repairSendBill.getSendTime().after(startDate) && repairSendBill.getSendTime().before(endDate))
                .collect(toList());
        //获取所有维修的装备
        if (repairSendBills.size() > 0) {
            for (RepairSendBill s : repairSendBills) {
//                String[] strings = s.getRepairDeviceCheckResult().split("x");
                String[] strings = s.getRepairDeviceCheckDetail().split("x");
                for (String s1 : strings) {
                    if (s1.length() >= 2) {
                        //出库无误装备
                        if ("1".equals(s1.substring(s1.length() - 1))) {
                            Integer id = Integer.parseInt(s1.substring(0, s1.length() - 1));
                            DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id);
                            deviceLibraries.add(deviceLibraryEntity);
                        }
                    }
                }
            }
        }
        return getDeviceStatistics(deviceLibraries);
    }

    @Override
    public List<DeviceStatistics> getRepairBackStatistics(Date startDate, Date endDate) {
        List<DeviceLibrary> deviceLibraries = new ArrayList<>();
        List<RepairBackBill> backBills = repairBackBillDao.findAll().stream()
                .filter(repairBackBill -> repairBackBill.getBackStatus() == 5 && userPublicService.findByUnitsToname(1).equals(repairBackBill.getReceiveUnit()) && repairBackBill.getCreateTime().after(startDate) && repairBackBill.getCreateTime().before(endDate))
                .collect(toList());
        //获取所有的装备维修退回的
        if (backBills.size()>0){
            for (RepairBackBill backBill : backBills) {
                String[] strings = backBill.getBackCheckDetail().split("x");
                for (String s1 : strings) {
                    if (s1.length() >= 2) {
                        //出库无误装备
                        if ("1".equals(s1.substring(s1.length() - 1))) {
                            Integer id = Integer.parseInt(s1.substring(0, s1.length() - 1));
                            DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id);
                            deviceLibraries.add(deviceLibraryEntity);
                        }
                    }
                }
            }
        }
        return getDeviceStatistics(deviceLibraries);
    }

    @Override
    public int getDestroyStatisticsCount(Date startDate, Date endDate) {
        List<DeviceLibrary> libraryList= deviceLibraryDao.findAll(getPredicateBuilder(startDate,endDate,DeviceLifeStatus.DESTROYED));
        return libraryList.size();
    }

    /**
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 这一段时间省销毁的统计
     */
    @Override
    public List<DeviceStatistics> getDestroyStatistics(Date startDate, Date endDate) {
        List<DeviceLibrary> libraryList= deviceLibraryDao.findAll(getPredicateBuilder(startDate,endDate,DeviceLifeStatus.DESTROYED));
        return getDeviceStatistics(libraryList);
    }

    @Override
    public int getDecommissioningStatisticsCount(Date startDate, Date endDate) {
        List<DeviceLibrary> libraryList= deviceLibraryDao.findAll(getPredicateBuilder(startDate,endDate,DeviceLifeStatus.RETIRE));
        return libraryList.size();
    }

    @Override
    public List<DeviceStatistics> getDecommissioningStatistics(Date startDate, Date endDate) {
        List<DeviceLibrary> libraryList= deviceLibraryDao.findAll(getPredicateBuilder(startDate,endDate,DeviceLifeStatus.RETIRE));
        return getDeviceStatistics(libraryList);

    }

    @Override
    public int getScrapStatisticsCount(Date startDate, Date endDate) {
        List<DeviceLibrary> libraryList= deviceLibraryDao.findAll(getPredicateBuilder(startDate,endDate,DeviceLifeStatus.SCRAP_I));
        return libraryList.size();
    }

    @Override
    public int getLossStatisticsCount(Date startDate, Date endDate) {
        List<DeviceLibrary> libraryList = deviceLibraryDao.findAll(getPredicateBuilder(startDate, endDate, DeviceLifeStatus.LOSS));
        return libraryList.size();
    }

    @Override
    public List<DeviceStatistics> getLossStatistics(Date startDate, Date endDate) {
        List<DeviceLibrary> libraryList= deviceLibraryDao.findAll(getPredicateBuilder(startDate,endDate,DeviceLifeStatus.LOSS));
        return getDeviceStatistics(libraryList);
    }

    /**
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 这一段时间省报废的统计
     */
    @Override
    public List<DeviceStatistics> getScrapStatistics(Date startDate, Date endDate) {
        List<DeviceLibrary> libraryList= deviceLibraryDao.findAll(getPredicateBuilder(startDate,endDate,DeviceLifeStatus.SCRAP_I));
        return getDeviceStatistics(libraryList);
    }

    @Override
    public void delete(Integer id) {
        deviceUseReportDao.deleteById(id);
    }

    private Specification<DeviceUseReport> getSelectSpecification(DeviceUseReportSelectVo deviceUseReportSelectVo) {
        PredicateBuilder<DeviceUseReport> predicateBuilder = Specifications.and();
        if (deviceUseReportSelectVo != null) {
            if (deviceUseReportSelectVo.getContent() != null) {
                Class<DeviceUseReport> deviceUseReportEntityClass = DeviceUseReport.class;
                Field[] declaredFields = deviceUseReportEntityClass.getDeclaredFields();
                PredicateBuilder<DeviceUseReport> p = Specifications.or();
                for (Field field : declaredFields) {
                    if (field.getType().equals(String.class) && field.getAnnotation(Transient.class) == null) {
                        p.like(field.getName(), "%" + deviceUseReportSelectVo.getContent() + "%");
                    }
                }
                predicateBuilder.predicate(p.build());
            }
            if (deviceUseReportSelectVo.getStartTime() != null) {
                predicateBuilder.gt("createTime", deviceUseReportSelectVo.getStartTime());
            }
            if (deviceUseReportSelectVo.getUnitId() !=null){
                String name=userPublicService.findByUnitsToname(deviceUseReportSelectVo.unitId);
                predicateBuilder.eq("unit", name);
            }
            if (deviceUseReportSelectVo.getEndTime() != null) {
                predicateBuilder.lt("updateTime", deviceUseReportSelectVo.getEndTime());
            }
        }
        return predicateBuilder.build();
    }


    /**
     * 销毁、报废、退役使用
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 装备集合
     */
    private Specification<DeviceLibrary> getPredicateBuilder(Date startTime, Date endTime, DeviceLifeStatus deviceLifeStatus) {
        PredicateBuilder<DeviceLibrary> predicateBuilder = Specifications.and();

        if (startTime!=null){
            predicateBuilder.gt("updateTime",startTime);
        }

        if (endTime !=null){
            predicateBuilder.lt("updateTime",endTime);
        }
        predicateBuilder.eq("lifeStatus", deviceLifeStatus.id);

        return predicateBuilder.build();
    }


    /**
     * 按型号组合统计
     */
    private List<DeviceStatistics> getDeviceStatistics(List<DeviceLibrary> deviceLibraries) {
        List<DeviceStatistics> deviceStatisticsList = new ArrayList<>();
        //按型号组合成map
        Map<String, List<DeviceLibrary>> map = deviceLibraries.stream().collect(groupingBy(deviceLibrary -> deviceLibrary.getModel()+"Ǵ"+deviceLibrary.getName()));
        //不同型号生成统计vo
        for (String s:map.keySet()) {
            String[] strings = s.split("Ǵ");
            String model = strings[0];
            String name = strings[1];
            DeviceStatistics deviceStatistics = new DeviceStatistics();
            deviceStatistics.setModel(model);
            deviceStatistics.setName(name);
            deviceStatistics.setNum(map.get(s).size());
            deviceStatisticsList.add(deviceStatistics);
        }
        return deviceStatisticsList;
    }
}
