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

import com.fasterxml.jackson.core.type.TypeReference;
import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
import com.tykj.dev.config.base.DeviceLifeStatus;
import com.tykj.dev.device.file.entity.FileRet;
import com.tykj.dev.device.library.repository.DeviceLibraryDao;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.device.library.subject.vo.ScriptSaveVo;
import com.tykj.dev.device.sendback.entity.domain.DeviceRepel;
import com.tykj.dev.device.sendback.entity.domain.DeviceRepelDetail;
import com.tykj.dev.device.sendback.entity.domain.RepelEscrow;
import com.tykj.dev.device.sendback.entity.vo.*;
import com.tykj.dev.device.sendback.service.*;
import com.tykj.dev.device.task.service.TaskService;
import com.tykj.dev.device.task.subject.bto.TaskBto;
import com.tykj.dev.device.user.subject.entity.Units;
import com.tykj.dev.device.user.subject.service.UnitsService;
import com.tykj.dev.misc.base.BusinessEnum;
import com.tykj.dev.misc.base.StatusEnum;
import com.tykj.dev.misc.utils.DeviceSeqUtil;
import com.tykj.dev.misc.utils.JacksonUtil;
import com.tykj.dev.misc.utils.PageUtil;
import com.tykj.dev.misc.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName RepelQueryServiceImpl.java
 * @Description 清退查询接口服务
 * @createTime 2021年01月10日 15:30:00
 */
@Service
@Slf4j
public class RepelQueryServiceImpl implements RepelQueryService {
    @Autowired
    RepelTaskStatisticalService repelTaskStatisticalService;
    @Autowired
    DeviceRepelDetailService repelDetailService;
    @Autowired
    TaskService taskService;
    @Autowired
    DeviceRepelService deviceRepelService;
    @Autowired
    DeviceLibraryDao deviceLibraryDao;
    @Autowired
    UnitsService unitsService;
    @Autowired
    RepelDeviceUnitService deviceUnitService;
    @Autowired
    RepelEscrowService repelEscrowService;

    @Override
    public RepelStatisticsVo findRepelTaskStatisticals(Integer taskId, Integer billId) {
       DeviceRepel deviceRepel=deviceRepelService.findDeviceRepel(billId);
       return new RepelStatisticsVo(deviceRepel.getInitiateName(),deviceRepel.getTime(),repelTaskStatisticalService.findAllRepelTaskStatistical(taskId,billId));
    }

    @Override
    public DeviceRepelDetail findDeviceRepelDetail(Integer taskId) {
        TaskBto taskBto= taskService.get(taskId);
        DeviceRepelDetail deviceRepelDetail=  repelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        if (taskBto.getCustomInfo().equals("DirectlyUnder")){
            List<DeviceLibrary> libraryList=new ArrayList<>();
            repelEscrowService.findAllBillId(deviceRepelDetail.getRepelId()).forEach(
                    repelEscrow -> {
                        libraryList.addAll(repelEscrow.getDeviceLibraries());
                    }
            );
            deviceRepelDetail.setDeviceLibraryEntities(libraryList);
        }
        if (deviceRepelDetail.getScriptJson()!=null) {
            deviceRepelDetail.setScripts(JacksonUtil.readValue(deviceRepelDetail.getScriptJson(), new TypeReference<List<ScriptSaveVo>>() {
            }));
        }
        return deviceRepelDetail;
    }

    @Override
    public DeviceRepel findDeviceRepel(Integer taskId) {
        TaskBto taskBto= taskService.get(taskId);
        if (taskBto.getBusinessType().equals(BusinessEnum.SEND_BACK_STATISTICAL.id)){
            return deviceRepelService.findDeviceRepel(taskBto.getBillId());
        }
        DeviceRepelDetail deviceRepelDetail = repelDetailService.findDeviceRepelDetailNoDev(taskBto.getBillId());
        return deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
    }

    @Override
    public  DeviceChooseRepel findDeviceChooseRepel(DeviceChoosePageVo deviceChoosePageVo) {
        List<DeviceLibrary> deviceLibraries=new ArrayList<>();
        List<DeviceLibrary> deviceLibrariesAbnormal=new ArrayList<>();
        Map<Integer,String> typeMap=new HashMap<>();
        Map<String,String> modelMap=new HashMap<>();

        Map<Integer,String> typeMapAbnormal=new HashMap<>();
        Map<String,String> modelMapAbnormal=new HashMap<>();
        Units units= unitsService.findById(deviceChoosePageVo.getUnitId());
        DeviceRepelDetail deviceRepelDetail= repelDetailService.findDeviceRepelDetailNoDev(taskService.get(deviceChoosePageVo.getTaskId()).getBillId());
        DeviceRepel deviceRepel=deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
        if (deviceRepel.getSeqNumbers()==null||deviceRepel.getSeqNumbers().equals("")) {
            deviceLibraryDao.findAllByPackingIdInAndOwnUnit(deviceChoosePageVo.getFielding(), units.getName()).stream()
                    .filter(deviceLibrary -> deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_LIBRARY.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPEL.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.SEND_BACK.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPAIRING.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_TRANSIT.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.USE.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.TO_BE_SCRAPPED.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.TO_BE_DESTROYED.id))
                    .map(DeviceLibrary::setConfigName).forEach(
                    deviceLibrary -> {
                        if (deviceLibrary.getOwnUnit().equals(deviceLibrary.getLocationUnit())) {
                            if (deviceLibrary.getLifeStatus() == 2 || deviceLibrary.getLifeStatus() == 14 || deviceLibrary.getLifeStatus() == 6) {
                                deviceLibraries.add(deviceLibrary);
                                modelMap.put(deviceLibrary.getModel(),"");
                                if (deviceLibrary.getType()!=null) {
                                    typeMap.put(deviceLibrary.getType(), deviceLibrary.getTypeName());
                                }
                            } else {
                                deviceLibrariesAbnormal.add(deviceLibrary);
                                modelMapAbnormal.put(deviceLibrary.getModel(),"");
                                if (deviceLibrary.getType()!=null) {
                                    typeMapAbnormal.put(deviceLibrary.getType(),deviceLibrary.getTypeName());
                                }
                            }
                        } else {
                            deviceLibrariesAbnormal.add(deviceLibrary);
                            modelMapAbnormal.put(deviceLibrary.getModel(),"");
                            if (deviceLibrary.getType()!=null) {
                                typeMapAbnormal.put(deviceLibrary.getType(), deviceLibrary.getTypeName());
                            }
                        }
                    }
            );
        }else {
            deviceLibraryDao.findAllBySeqNumberIn(DeviceSeqUtil.selectDeviceSeqs(deviceRepel.getSeqNumbers())).stream()
                    .filter(deviceLibrary -> deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_LIBRARY.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPEL.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.SEND_BACK.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPAIRING.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_TRANSIT.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.USE.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.TO_BE_SCRAPPED.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.TO_BE_DESTROYED.id))
                    .filter(deviceLibrary -> deviceLibrary.getOwnUnit().equals(units.getName()))
                    .map(DeviceLibrary::setConfigName).forEach(
                    deviceLibrary -> {
                        if (deviceLibrary.getOwnUnit().equals(deviceLibrary.getLocationUnit())) {
                            if (deviceLibrary.getLifeStatus() == 2 || deviceLibrary.getLifeStatus() == 14 || deviceLibrary.getLifeStatus() == 6) {
                                deviceLibraries.add(deviceLibrary);
                                modelMap.put(deviceLibrary.getModel(),"");
                                if (deviceLibrary.getType()!=null) {
                                    typeMap.put(deviceLibrary.getType(), deviceLibrary.getTypeName());
                                }
                            } else {
                                deviceLibrariesAbnormal.add(deviceLibrary);
                                modelMapAbnormal.put(deviceLibrary.getModel(),"");
                                if (deviceLibrary.getType()!=null) {
                                    typeMapAbnormal.put(deviceLibrary.getType(), deviceLibrary.getTypeName());
                                }
                            }
                        } else {
                            deviceLibrariesAbnormal.add(deviceLibrary);
                            modelMapAbnormal.put(deviceLibrary.getModel(),"");
                            if (deviceLibrary.getType()!=null) {
                                typeMapAbnormal.put(deviceLibrary.getType(),deviceLibrary.getTypeName());
                            }
                        }
                    }
            );
        }
        int isNotSub = 1;
        if (units.getLevel()==2) {
            TaskBto taskBto = taskService.findFatherIdAndCustomInfo(deviceChoosePageVo.getTaskId());
            if (!taskBto.getBillStatus().equals(StatusEnum.END.id)) {
                isNotSub = 0;
            }
        }
        Page<DeviceLibrary> deviceLibraryPage= PageUtil.getPerPage(deviceChoosePageVo.getDeviceSelectVos().getPage(), deviceChoosePageVo.getDeviceSelectVos().getSize(), findModelAndType(deviceChoosePageVo.getDeviceSelectVos(),deviceLibraries), deviceChoosePageVo.getDeviceSelectVos().getPageable());
        Page<DeviceLibrary> deviceLibraryPageAbnormal= PageUtil.getPerPage(deviceChoosePageVo.getDeviceSelectVoAbnormal().getPage(), deviceChoosePageVo.getDeviceSelectVoAbnormal().getSize(), findModelAndType(deviceChoosePageVo.getDeviceSelectVoAbnormal(),deviceLibrariesAbnormal), deviceChoosePageVo.getDeviceSelectVoAbnormal().getPageable());
        return new DeviceChooseRepel(deviceLibraryPage,deviceLibraryPageAbnormal,isNotSub,modelMap,typeMap,modelMapAbnormal,typeMapAbnormal);
    }


    @Override
    public List<Integer> findIdList(DeviceChoosePageVo deviceChoosePageVo) {
        List<Integer> deviceLibraries=new ArrayList<>();
        Units units= unitsService.findById(deviceChoosePageVo.getUnitId());
        DeviceRepelDetail deviceRepelDetail= repelDetailService.findDeviceRepelDetail(taskService.get(deviceChoosePageVo.getTaskId()).getBillId());
        DeviceRepel deviceRepel=deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
        if (deviceRepel.getSeqNumbers()==null||deviceRepel.getSeqNumbers().equals("")) {
            deviceLibraryDao.findAllByPackingIdInAndOwnUnit(deviceChoosePageVo.getFielding(), units.getName()).stream()
                    .filter(deviceLibrary -> deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_LIBRARY.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPEL.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.SEND_BACK.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPAIRING.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_TRANSIT.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.USE.id))
                    .map(DeviceLibrary::setConfigName).forEach(
                    deviceLibrary -> {
                        if (deviceLibrary.getOwnUnit().equals(deviceLibrary.getLocationUnit())) {
                            if (deviceLibrary.getLifeStatus() == 2 || deviceLibrary.getLifeStatus() == 15 || deviceLibrary.getLifeStatus() == 14 || deviceLibrary.getLifeStatus() == 6) {
                                deviceLibraries.add(deviceLibrary.getId());
                            }
                        }
                    }
            );
        }else {
            deviceLibraryDao.findAllBySeqNumberIn(DeviceSeqUtil.selectDeviceSeqs(deviceRepel.getSeqNumbers())).stream()
                    .filter(deviceLibrary -> deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_LIBRARY.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPEL.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.SEND_BACK.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPAIRING.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_TRANSIT.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.USE.id))
                    .filter(deviceLibrary -> deviceLibrary.getOwnUnit().equals(units.getName()))
                    .map(DeviceLibrary::setConfigName).forEach(
                    deviceLibrary -> {
                        if (deviceLibrary.getOwnUnit().equals(deviceLibrary.getLocationUnit())) {
                            if (deviceLibrary.getLifeStatus() == 2 || deviceLibrary.getLifeStatus() == 15 || deviceLibrary.getLifeStatus() == 14 || deviceLibrary.getLifeStatus() == 6) {
                                deviceLibraries.add(deviceLibrary.getId());
                            }
                        }
                    }
            );
        }
        return deviceLibraries;
    }

    private List<DeviceLibrary> findModelAndType(DeviceSelectVo deviceSelectVo,List<DeviceLibrary> libraries){
        if (deviceSelectVo.getModel()!=null&&deviceSelectVo.getType()==null){
           return libraries.stream().filter(deviceLibrary -> deviceLibrary.getModel().equals(deviceSelectVo.getModel())).collect(Collectors.toList());
        }else if (deviceSelectVo.getModel()==null&&deviceSelectVo.getType()!=null){
            return libraries.stream().filter(deviceLibrary -> deviceLibrary.getType().equals(deviceSelectVo.getType())).collect(Collectors.toList());
        }else if (deviceSelectVo.getModel()!=null&&deviceSelectVo.getType()!=null){
            return libraries.stream().filter(deviceLibrary -> deviceLibrary.getType().equals(deviceSelectVo.getType())&&deviceLibrary.getModel().equals(deviceSelectVo.getModel())).collect(Collectors.toList());
        }else {
            return libraries;
        }
    }

//    private PredicateBuilder<DeviceLibrary> getPredicateBuilderDeviceChooseRepel(List<Integer> packingList,List<Integer> lifeStatusList) {
//        PredicateBuilder<DeviceLibrary> predicateBuilder = Specifications.and();
//        predicateBuilder.in("packingId",packingList);
//        predicateBuilder.in("lifeStatus",lifeStatusList);
//        return predicateBuilder;
//    }



    @Override
    public List<DeviceLibrary> findDeviceSendOut(Integer taskId) {
        TaskBto taskBto = taskService.get(taskId);
        DeviceRepelDetail deviceRepelDetail= repelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        return findInvoleDevice(deviceRepelDetail.getDeviceIds());
    }

    @Override
    public List<ModelNameGroup> toRepelList(RepelManagementVo repelManagementVo) {
        Units units=  unitsService.findById(repelManagementVo.getUnitId());
        return toModelNameGroup(deviceLibraryDao.findAllByOwnUnitAndLocationUnitAndLifeStatus(units.getName(),units.getName(),DeviceLifeStatus.REPEL.id).stream().map(DeviceLibrary::setConfigName).filter(deviceLibrary ->deviceLibrary.getUpdateTime()==null ||(deviceLibrary.getUpdateTime().getTime()>=repelManagementVo.getTime()&&deviceLibrary.getUpdateTime().getTime()<=repelManagementVo.getEndTime())).collect(Collectors.toList()));
    }

    @Override
    public List<DeviceLibrary> toRepelListDev(RepelManagementVo repelManagementVo) {
        return null;
    }

    private List<ModelNameGroup> toModelNameGroup(List<DeviceLibrary> deviceLibraries){
        Map<String,ModelNameGroup> modelNameGroupMap=new HashMap<>();
        deviceLibraries.forEach(
                deviceLibrary -> {
                    List<Integer> ids=new ArrayList<>();
                    String key=deviceLibrary.getModel()+deviceLibrary.getName();
                    if (!modelNameGroupMap.containsKey(key)){
                        ids.add(deviceLibrary.getId());
                        modelNameGroupMap.put(key,new ModelNameGroup(deviceLibrary.getModel(),deviceLibrary.getName(),ids));
                    }else {
                        ModelNameGroup modelNameGroup=modelNameGroupMap.get(key);
                        ids=modelNameGroupMap.get(key).getIds();
                        ids.add(deviceLibrary.getId());
                        modelNameGroup.setIds(ids);
                        modelNameGroupMap.put(key,modelNameGroup);
                    }
                }
        );
        return modelNameGroupMap.values().stream().sorted(Comparator.comparing(ModelNameGroup::getModel)).collect(Collectors.toList());
    }

    @Override
    public List<DevRepelVo> findRepelListModelNameGroup(ModelAndTypeVo modelAndTypeVo) {
        Units units=  unitsService.findById(modelAndTypeVo.getUnitId());
        if (modelAndTypeVo.getModel()==null&&modelAndTypeVo.getType()==null){
          return deviceLibraryDao.findAllByOwnUnitAndLocationUnitAndLifeStatus(units.getName(),units.getName(),15).stream().map(DeviceLibrary::setConfigName)
                  .map(this::devRepelVo).collect(Collectors.toList());
        }else if (modelAndTypeVo.getModel()!=null&&modelAndTypeVo.getType()==null){
            return deviceLibraryDao.findAllByOwnUnitAndLocationUnitAndLifeStatus(units.getName(),units.getName(),15).stream().filter(deviceLibrary -> deviceLibrary.getModel().equals(modelAndTypeVo.getModel())).map(DeviceLibrary::setConfigName)
                    .map(this::devRepelVo).collect(Collectors.toList());
        }else if (modelAndTypeVo.getModel()==null&&modelAndTypeVo.getType()!=null){
            return deviceLibraryDao.findAllByOwnUnitAndLocationUnitAndLifeStatus(units.getName(),units.getName(),15).stream().map(DeviceLibrary::setConfigName)
                    .filter(deviceLibrary -> deviceLibrary.getType().equals(modelAndTypeVo.getType()))
//                    .filter(deviceLibrary -> deviceLibrary.getModel()==null|| deviceLibrary.getModel().equals(modelAndTypeVo.getModel()))
                    .map(this::devRepelVo).collect(Collectors.toList());
        }else {
          return  deviceLibraryDao.findAllByOwnUnitAndLocationUnitAndLifeStatus(units.getName(),units.getName(),15).stream().filter(deviceLibrary -> deviceLibrary.getModel().equals(modelAndTypeVo.getModel())).map(DeviceLibrary::setConfigName)
                    .filter(deviceLibrary -> deviceLibrary.getType().equals(modelAndTypeVo.getType()))
                   .map(this::devRepelVo).collect(Collectors.toList());
        }
    }



    @Override
    public  List<ModelNameGroup> clearedList(RepelManagementVo repelManagementVo) {
         new Date(repelManagementVo.getTime());
//        return toModelNameGroup(repelDetailService.findYearAndUnitToDeviceList(new Date(repelManagementVo.getTime()),new Date(repelManagementVo.getEndTime()),repelManagementVo.getUnitId()));
    return new ArrayList<>();
    }

    @Override
    public List<ModelNameGroup> retiredList(RepelManagementVo repelManagementVo) {
//        Units units=  unitsService.findById(repelManagementVo.getUnitId());

        return toModelNameGroup(deviceLibraryDao.findAllByLifeStatus(DeviceLifeStatus.RETIRE.id).stream().filter(deviceLibrary ->deviceLibrary.getUpdateTime()==null ||(deviceLibrary.getUpdateTime().getTime()>=repelManagementVo.getTime()&&deviceLibrary.getUpdateTime().getTime()<=repelManagementVo.getEndTime())).collect(Collectors.toList()));

    }

    @Override
    public AllDirectUnderDevVo provinceDirectlyUnderDev(Integer taskId) {
        TaskBto taskBto= taskService.get(taskId);
        Map<String,List<DeviceLibrary>> map=new HashMap<>();
        List<DeviceLibrary> librarieList=new ArrayList<>();
        AllDirectUnderDevVo allDirectUnderDevVo=new AllDirectUnderDevVo();
        DeviceRepelDetail deviceRepelDetail=repelDetailService.findDeviceRepelDetailNoDev(taskBto.getBillId());
        DeviceRepel deviceRepel=deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
        List<String> unitNameList=  unitsService.findAllByIdIn(StringUtils.stringToList(deviceRepel.getTaskScope())).stream().filter(units -> units.getType()==2).map(Units::getName).collect(Collectors.toList());
        List<DeviceLibrary> deviceLibraries;
        if (deviceRepel.getSeqNumbers()==null||deviceRepel.getSeqNumbers().equals("")) {
            deviceLibraries =  deviceLibraryDao.findAllByPackingIdInAndOwnUnitIn(StringUtils.stringToList(deviceRepel.getFielding()), unitNameList).stream()
                    .filter(deviceLibrary -> deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_LIBRARY.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPEL.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.SEND_BACK.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPAIRING.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_TRANSIT.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.USE.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.TO_BE_SCRAPPED.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.TO_BE_DESTROYED.id))
                    .map(DeviceLibrary::setConfigName).collect(Collectors.toList());
        }else {
            deviceLibraries=  deviceLibraryDao.findAllBySeqNumberInAndOwnUnitIn(DeviceSeqUtil.selectDeviceSeqs(deviceRepel.getSeqNumbers()),unitNameList).stream()
                    .filter(deviceLibrary -> deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_LIBRARY.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPEL.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.SEND_BACK.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPAIRING.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_TRANSIT.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.USE.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.TO_BE_SCRAPPED.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.TO_BE_DESTROYED.id))
                    .map(DeviceLibrary::setConfigName).collect(Collectors.toList());
        }


        for (DeviceLibrary deviceLibrary:deviceLibraries) {
            if (deviceLibrary.getOwnUnit().equals(deviceLibrary.getLocationUnit())) {
                if (deviceLibrary.getLifeStatus() == 2 ||  deviceLibrary.getLifeStatus() == 14 || deviceLibrary.getLifeStatus() == 6) {
                    if (map.containsKey(deviceLibrary.getOwnUnit())) {
                        List<DeviceLibrary> libraries = map.get(deviceLibrary.getOwnUnit());
                        libraries.add(deviceLibrary);
                        map.put(deviceLibrary.getOwnUnit(), libraries);
                    } else {
                        librarieList.add(deviceLibrary);
                        map.put(deviceLibrary.getOwnUnit(), librarieList);
                    }
                } else {
                    allDirectUnderDevVo.setUnitName(deviceLibrary.getOwnUnit());
                    allDirectUnderDevVo.setNotAbnormal(true);
                    break;
                }
            } else {
                allDirectUnderDevVo.setUnitName(deviceLibrary.getOwnUnit());
                allDirectUnderDevVo.setNotAbnormal(true);
                break;
            }
        }
        allDirectUnderDevVo.setUnitNameDeviceMap(map);
        return allDirectUnderDevVo;
    }


    @Override
    public List<RepelEscrow> directlyUnderUnitLeftNavigation(Integer taskId,Integer type) {
        DeviceRepelDetail deviceRepelDetail;
        if (type==1){
            TaskBto taskBto = taskService.get(taskId);
            deviceRepelDetail =repelDetailService.findDeviceRepelDetailNoDev(taskBto.getBillId());
        }else {
            deviceRepelDetail =repelDetailService.findDeviceRepelDetailNoDev(taskId);
        }

        return repelEscrowService.findAllBillId(deviceRepelDetail.getRepelId());
    }



    @Override
    public List<DeviceLibrary> provinceDirectlyUnderSelectedDev(Integer taskId, Integer unitId,Integer type) {
        Units units=unitsService.findById(unitId);

        DeviceRepelDetail deviceRepelDetail;
        if (type==1){
            TaskBto taskBto= taskService.get(taskId);
            deviceRepelDetail=repelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        }else {
            deviceRepelDetail=repelDetailService.findDeviceRepelDetail(taskId);
        }
        Map<String,List<Integer>> map=JacksonUtil.readValue(deviceRepelDetail.getDirectlyUnderDevices(), new TypeReference<Map<String, List<Integer>>>() {});
        if (map!=null) {
            if (map.containsKey(units.getName())) {
                return deviceLibraryDao.findAllById(map.get(units.getName()));
            }else {
                log.info("直属单位-{}-没有提交的装备，请查看",units.getName());
                return new ArrayList<>();
            }
        }else {
            log.info("直属单位任务{}没有提交的装备，请查看",taskId);
            return new ArrayList<>();
        }

    }

    @Override
    public List<DevRepelVo> repelManagementListDetails(List<Integer> ids) {
        return deviceLibraryDao.findAllById(ids).stream().map(DeviceLibrary::setConfigName).map(this::devRepelVo).collect(Collectors.toList());
    }

    @Override
    public Page<DeviceRepelDetail> getList(RepelDetailSelectVo repelDetailSelectVo) {
        return repelDetailService.findPageDeviceRepelDetail(repelDetailSelectVo);
    }


    @Override
    public DeviceChooseRepel findDeviceChooseRepel1(DeviceChoosePageVo deviceChoosePageVo) {
        List<DeviceLibrary> deviceLibraries=new ArrayList<>();
        List<DeviceLibrary> deviceLibrariesAbnormal=new ArrayList<>();
        Map<Integer,String> typeMap=new HashMap<>();
        Map<String,String> modelMap=new HashMap<>();

        Map<Integer,String> typeMapAbnormal=new HashMap<>();
        Map<String,String> modelMapAbnormal=new HashMap<>();
        Units units= unitsService.findById(deviceChoosePageVo.getUnitId());
        DeviceRepelDetail deviceRepelDetail= repelDetailService.findDeviceRepelDetailNoDev(taskService.get(deviceChoosePageVo.getTaskId()).getBillId());
        DeviceRepel deviceRepel=deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
        if (deviceRepel.getSeqNumbers()==null||deviceRepel.getSeqNumbers().equals("")) {
            deviceLibraryDao.findAllByPackingIdInAndOwnUnit(deviceChoosePageVo.getFielding(), units.getName()).stream()
                    .filter(deviceLibrary ->
                               deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_LIBRARY.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPAIRING.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_TRANSIT.id)
                            || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.USE.id))
                    .map(DeviceLibrary::setConfigName).forEach(
                    deviceLibrary -> {
                        if (deviceLibrary.getOwnUnit().equals(deviceLibrary.getLocationUnit())) {
                            if (deviceLibrary.getLifeStatus() == 2 || deviceLibrary.getLifeStatus() == 14 || deviceLibrary.getLifeStatus() == 6) {
                                deviceLibraries.add(deviceLibrary);
                                modelMap.put(deviceLibrary.getModel(), "");
                                if (deviceLibrary.getType() != null) {
                                    typeMap.put(deviceLibrary.getType(), deviceLibrary.getTypeName());
                                }
                            } else {
                                deviceLibrariesAbnormal.add(deviceLibrary);
                                modelMapAbnormal.put(deviceLibrary.getModel(), "");
                                if (deviceLibrary.getType() != null) {
                                    typeMapAbnormal.put(deviceLibrary.getType(), deviceLibrary.getTypeName());
                                }
                            }
                        } else {
                            deviceLibrariesAbnormal.add(deviceLibrary);
                            modelMapAbnormal.put(deviceLibrary.getModel(), "");
                            if (deviceLibrary.getType() != null) {
                                typeMapAbnormal.put(deviceLibrary.getType(), deviceLibrary.getTypeName());
                            }
                        }
                    }
            );
        }else {
            deviceLibraryDao.findAllBySeqNumberIn(DeviceSeqUtil.selectDeviceSeqs(deviceRepel.getSeqNumbers())).stream()
                    .filter(deviceLibrary ->
                            deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_LIBRARY.id)
                                    || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.REPAIRING.id)
                                    || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.IN_TRANSIT.id)
                                    || deviceLibrary.getLifeStatus().equals(DeviceLifeStatus.USE.id))
                    .filter(deviceLibrary -> deviceLibrary.getOwnUnit().equals(units.getName()))
                    .map(DeviceLibrary::setConfigName).forEach(
                    deviceLibrary -> {
                        if (deviceLibrary.getOwnUnit().equals(deviceLibrary.getLocationUnit())) {
                            if (deviceLibrary.getLifeStatus() == 2 ||  deviceLibrary.getLifeStatus() == 14 || deviceLibrary.getLifeStatus() == 6) {
                                deviceLibraries.add(deviceLibrary);
                                modelMap.put(deviceLibrary.getModel(),"");
                                if (deviceLibrary.getType()!=null) {
                                    typeMap.put(deviceLibrary.getType(), deviceLibrary.getTypeName());
                                }
                            } else {
                                deviceLibrariesAbnormal.add(deviceLibrary);
                                modelMapAbnormal.put(deviceLibrary.getModel(),"");
                                if (deviceLibrary.getType()!=null) {
                                    typeMapAbnormal.put(deviceLibrary.getType(), deviceLibrary.getTypeName());
                                }
                            }
                        } else {
                            deviceLibrariesAbnormal.add(deviceLibrary);
                            modelMapAbnormal.put(deviceLibrary.getModel(),"");
                            if (deviceLibrary.getType()!=null) {
                                typeMapAbnormal.put(deviceLibrary.getType(),deviceLibrary.getTypeName());
                            }
                        }
                    }
            );
        }
        Page<DeviceLibrary> deviceLibraryPage= PageUtil.getPerPage(deviceChoosePageVo.getDeviceSelectVos().getPage(), deviceChoosePageVo.getDeviceSelectVos().getSize(), deviceLibraries, deviceChoosePageVo.getDeviceSelectVos().getPageable());
        Page<DeviceLibrary> deviceLibraryPageAbnormal= PageUtil.getPerPage(deviceChoosePageVo.getDeviceSelectVoAbnormal().getPage(), deviceChoosePageVo.getDeviceSelectVoAbnormal().getSize(), deviceLibrariesAbnormal, deviceChoosePageVo.getDeviceSelectVoAbnormal().getPageable());
        return new DeviceChooseRepel(deviceLibraryPage,deviceLibraryPageAbnormal,1,modelMap,typeMap,modelMapAbnormal,typeMapAbnormal);
    }

    private DevRepelVo devRepelVo(DeviceLibrary deviceLibrary){
        return new DevRepelVo(deviceLibrary.getId(),deviceLibrary.getName(),deviceLibrary.getModel(),deviceLibrary.getSeqNumber(),deviceLibrary.getType(),deviceLibrary.getTypeName(),deviceLibrary.getUpdateTime());

    }


    /**
     * 查询已清退装备列表
     */
    @Override
    public PagingVo clearedDeviceList(RepelManagementVo repelManagementVo) {
        List<DeviceLibrary> deviceLibraries=new ArrayList<>();
        PredicateBuilder<DeviceLibrary> predicateBuilder = getPredicateBuilder(repelManagementVo);
        //unitId为空，默认查询当前单位
        List<Integer> ids= repelDetailService.findYearAndUnitToDeviceList(new Date(repelManagementVo.getTime()),new Date(repelManagementVo.getEndTime()),repelManagementVo.getUnitId());
        if (ids!=null&&ids.size()!=0) {
            predicateBuilder.in("id", ids.toArray());
            deviceLibraries = deviceLibraryDao.findAll(predicateBuilder.build());
        }
        Page<DeviceLibrary> page = PageUtil.getPerPage(repelManagementVo.getPage(), repelManagementVo.getSize(), deviceLibraries, repelManagementVo.getPageable());

        return PagingVo.builder()
                .data(page.getContent().stream().map(DeviceLibrary::setConfigName).collect(Collectors.toList())).page(repelManagementVo.getPage())
                .size(repelManagementVo.getSize()).total((int)page.getTotalElements())
                .models(deviceLibraries.stream().map(DeviceLibrary::getModel).collect(Collectors.toSet()))
                .names(deviceLibraries.stream().map(DeviceLibrary::getName).collect(Collectors.toSet()))
                .build();
    }

    @Override
    public PagingVo repelDeviceList(RepelManagementVo repelManagementVo) {
        List<DeviceLibrary> deviceLibraries=deviceLibraryDao.findAll(getRepelDeviceSpecification(repelManagementVo));
        Page<DeviceLibrary> page = PageUtil.getPerPage(repelManagementVo.getPage(), repelManagementVo.getSize(), deviceLibraries, repelManagementVo.getPageable());

        return PagingVo.builder()
                .data(page.getContent().stream().map(DeviceLibrary::setConfigName).collect(Collectors.toList())).page(repelManagementVo.getPage())
                .size(repelManagementVo.getSize()).total((int)page.getTotalElements())
                .models(deviceLibraries.stream().map(DeviceLibrary::getModel).collect(Collectors.toSet()))
                .names(deviceLibraries.stream().map(DeviceLibrary::getName).collect(Collectors.toSet()))
                .build();
    }

    @Override
    public PagingVo repelDeviceInList(RepelManagementVo repelManagementVo) {
        List<DeviceLibrary> deviceLibraries=deviceLibraryDao.findAll(getRepelDeviceSpecificationIn(repelManagementVo));
        Page<DeviceLibrary> page = PageUtil.getPerPage(repelManagementVo.getPage(), repelManagementVo.getSize(), deviceLibraries, repelManagementVo.getPageable());

        return PagingVo.builder()
                .data(page.getContent().stream().map(DeviceLibrary::setConfigName).collect(Collectors.toList())).page(repelManagementVo.getPage())
                .size(repelManagementVo.getSize()).total((int)page.getTotalElements())
                .models(deviceLibraries.stream().map(DeviceLibrary::getModel).collect(Collectors.toSet()))
                .names(deviceLibraries.stream().map(DeviceLibrary::getName).collect(Collectors.toSet()))
                .build();
    }

    @Override
    public DeviceRepelDetail findByBillIdDeviceRepelDetail(Integer repelId) {
        return repelDetailService.findDeviceRepelDetail(repelId);
    }

    @Override
    public RepelFieldingPrompt judgeFieldingIsNotNormal(List<RepelFieldingVo> repelFieldingVoList) {
        RepelFieldingPrompt repelFieldingPrompt=new RepelFieldingPrompt();
        StringBuilder stringBuilder=new StringBuilder();
        StringBuilder message=new StringBuilder();
        message.append("以下列装信息：");
        deviceRepelService.findNotEndDeviceRepel().forEach(
                deviceRepel -> {
                    stringBuilder.append(",").append(deviceRepel.getFielding());
                }
        );
        AtomicBoolean falg= new AtomicBoolean(false);
        repelFieldingVoList.forEach(repelFieldingVo -> {
            if (stringBuilder.indexOf(","+repelFieldingVo.getId()+",")!=-1){
               message.append("(").append(repelFieldingVo.getModel()).append("-")
                       .append(repelFieldingVo.getName()).append(")");
                falg.set(true);
            }
        });
        message.append("已经存在于未完成的清退任务中,是否继续发起");
        repelFieldingPrompt.setNotPrompt(falg.get());
        repelFieldingPrompt.setInformation(message.toString());
        return repelFieldingPrompt;
    }

    @Override
    public Map<String, List<FileRet>> findByTaskIdToFileMapList(Integer taskId) {
        TaskBto taskBto= taskService.get(taskId);
        return repelDetailService.findByIdToFileMapList(taskBto.getBillId());
    }

    private Specification<DeviceLibrary> getRepelDeviceSpecificationIn(RepelManagementVo repelManagementVo) {
        PredicateBuilder<DeviceLibrary> predicateBuilder = getPredicateBuilder(repelManagementVo);
        //unitId为空，默认查询当前单位
        predicateBuilder.eq("lifeStatus", com.tykj.dev.config.base.DeviceLifeStatus.SEND_BACK_IN.id);
        Units units= unitsService.findById(repelManagementVo.getUnitId());
        predicateBuilder.eq("ownUnit",units.getName());
        return predicateBuilder.build();

    }

    private Specification<DeviceLibrary> getRepelDeviceSpecification(RepelManagementVo repelManagementVo) {
        PredicateBuilder<DeviceLibrary> predicateBuilder = getPredicateBuilder(repelManagementVo);
        //unitId为空，默认查询当前单位
        predicateBuilder.eq("lifeStatus", com.tykj.dev.config.base.DeviceLifeStatus.SEND_BACK.id);
        Units units= unitsService.findById(repelManagementVo.getUnitId());
        predicateBuilder.eq("ownUnit",units.getName());
        return predicateBuilder.build();

    }

    private Specification<DeviceLibrary> getClearedSpecification(RepelManagementVo repelManagementVo) {
        PredicateBuilder<DeviceLibrary> predicateBuilder = getPredicateBuilder(repelManagementVo);
        //unitId为空，默认查询当前单位
        List<Integer> ids= repelDetailService.findYearAndUnitToDeviceList(new Date(repelManagementVo.getTime()),new Date(repelManagementVo.getEndTime()),repelManagementVo.getUnitId());

        predicateBuilder.in("id",repelDetailService.findYearAndUnitToDeviceList(new Date(repelManagementVo.getTime()),new Date(repelManagementVo.getEndTime()),repelManagementVo.getUnitId()));
        return predicateBuilder.build();

    }

    private PredicateBuilder<DeviceLibrary> getPredicateBuilder(RepelManagementVo repelManagementVo) {
        PredicateBuilder<DeviceLibrary> predicateBuilder = Specifications.and();
        if (repelManagementVo != null) {
            if (repelManagementVo.getModel() != null) {
                predicateBuilder.eq("model", repelManagementVo.getModel());
            }
            if (repelManagementVo.getName() != null) {
                predicateBuilder.eq("name", repelManagementVo.getName());
            }
            if (repelManagementVo.getSecretLevel() != null) {
                predicateBuilder.eq("secretLevel", repelManagementVo.getSecretLevel());
            }
            if (repelManagementVo.getMatchingRange() != null) {
                predicateBuilder.eq("matchingRange", repelManagementVo.getMatchingRange());
            }
            if (repelManagementVo.getStorageType() != null) {
                predicateBuilder.eq("storageType", repelManagementVo.getStorageType());
            }
            if (repelManagementVo.getManageStatus() != null) {
                predicateBuilder.eq("manageStatus", repelManagementVo.getManageStatus());
            }
            if (repelManagementVo.getInvisibleRange() != null) {
                predicateBuilder.eq("invisibleRange", repelManagementVo.getInvisibleRange());
            }
            if (repelManagementVo.getTime()!=null){
                predicateBuilder.gt("updateTime",new Date(repelManagementVo.getTime()));
            }
            if (repelManagementVo.getEndTime()!=null){
                predicateBuilder.lt("updateTime",new Date(repelManagementVo.getEndTime()));
            }
            if (repelManagementVo.getModelDim()!=null){
                predicateBuilder.like("model","%"+repelManagementVo.getModelDim()+"%");
            }
            if (repelManagementVo.getNameDim()!=null){
                predicateBuilder.like("name","%"+repelManagementVo.getNameDim()+"%");
            }
            if (repelManagementVo.getSeqDim()!=null){
                predicateBuilder.like("seqNumber","%"+repelManagementVo.getSeqDim()+"%");
            }
            if (repelManagementVo.getContent() != null) {
                Class<DeviceLibrary> deviceLibraryEntity = DeviceLibrary.class;
                Field[] declaredFields = deviceLibraryEntity.getDeclaredFields();
                PredicateBuilder<DeviceLibrary> p = Specifications.or();
                for (Field field : declaredFields) {
                    if (field.getType().equals(String.class) && field.getAnnotation(Transient.class) == null) {
                        p.like(field.getName(), "%" + repelManagementVo.getContent() + "%");
                    }
                }
                predicateBuilder.predicate(p.build());
            }
        }
        return predicateBuilder;
    }

    private List<DeviceLibrary> findInvoleDevice(String involeDevice){
        if (involeDevice!=null && !involeDevice.equals("")&& !involeDevice.equals(",")) {
            List<String> idStringList = Arrays.asList(involeDevice.split(","));
            List<String> idListString = idStringList.stream().filter(list2->!list2.equals("")).collect(Collectors.toList());
            System.out.println(idListString);
            List<Integer> devIds = idListString.stream().map(Integer::parseInt).collect(Collectors.toList());
            return deviceLibraryDao.getDeviceLibraryEntitiesByIdIn(devIds).stream().map(DeviceLibrary::setConfigName).collect(Collectors.toList());
        }else {
            return new ArrayList<>();
        }
    }
}
