package com.tykj.dev.device.library.controller;

import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
import com.tykj.dev.config.cache.ConfigCache;
import com.tykj.dev.config.swagger.AutoDocument;
import com.tykj.dev.device.library.repository.DeviceLibraryDao;
import com.tykj.dev.device.library.repository.DeviceLogDao;
import com.tykj.dev.device.library.service.DeviceChangeService;
import com.tykj.dev.device.library.service.DeviceLibraryService;
import com.tykj.dev.device.library.service.DeviceLogService;
import com.tykj.dev.device.library.subject.Dto.DeviceLogDto;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.device.library.subject.domin.DeviceLog;
import com.tykj.dev.device.library.subject.vo.*;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.GetTreeUtils;
import com.tykj.dev.misc.utils.PageUtil;
import com.tykj.dev.misc.utils.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Min;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author dengdiyi
 */
@RestController
@RequestMapping(value = "/device")
@AutoDocument
@Api(tags = "装备管理模块", description = "装备管理接口")
@Validated
public class DeviceLibraryController {
    @Autowired
    private DeviceLibraryService deviceLibraryService;

    @Autowired
    private DeviceLibraryDao deviceLibraryDao;

    @Autowired
    private DeviceLogDao deviceLogDao;

    @Autowired
    private DeviceChangeService deviceChangeService;

    @Autowired
    private DeviceLogService deviceLogService;

    @Autowired
    private UserUtils userUtils;

    @Autowired
    private ConfigCache configCache;

    @ApiOperation(value = "修改装备备注", notes = "修改装备备注")
    @PostMapping("/setRecord")
    public ResponseEntity setRecord(@RequestBody Record record){
        DeviceLibrary deviceLibrary = deviceLibraryService.getOne(record.getId());
        deviceLibrary.setRecord(record.getRecord());
        deviceLibraryService.update(deviceLibrary);
        DeviceLogDto deviceLogDto = new DeviceLogDto(record.getId(), "将备注改为"+record.getRecord(), null);
        deviceLogService.addLog(deviceLogDto);
        return ResponseEntity.ok("修改成功");
    }

    @ApiOperation(value = "修改装备生命状态", notes = "修改装备生命状态")
    @PostMapping("/updateLifeStatus/{lifeStatus}")
    public ResponseEntity selectByIds(@RequestBody List<Integer> ids,@PathVariable("lifeStatus") int lifeStatus){
        List<DeviceLogDto> deviceLogDtos = new ArrayList<>();
        ids.forEach(integer -> {
            DeviceLibrary deviceLibrary = deviceLibraryService.getOne(integer);
            deviceLogDtos.add(new DeviceLogDto(integer, "将生命状态由" + configCache.getLifeStatusMap().get(deviceLibrary.getLifeStatus()) + "改为" + configCache.getLifeStatusMap().get(lifeStatus), null));
            deviceLibrary.setLifeStatus(lifeStatus);
            deviceLibraryService.update(deviceLibrary);
        });
        deviceLogService.addAllLog(deviceLogDtos);
        return ResponseEntity.ok("修改成功");
    }

    @ApiOperation(value = "根据装备id查询装备详情", notes = "根据装备id查询装备详情")
    @PostMapping("/selectByIds")
    public ResponseEntity selectByIds(@RequestBody DeviceSelectIdsVo deviceSelectIdsVo){
        List<DeviceLibrary> deviceLibraries = new ArrayList<>();
        deviceSelectIdsVo.getIds().forEach(integer -> deviceLibraries.add(deviceLibraryService.getOne(integer).setConfigName()));
        return ResponseEntity.ok(PageUtil.getPerPage(deviceSelectIdsVo.getPage(),deviceSelectIdsVo.getSize(),deviceLibraries, PageRequest.of(deviceSelectIdsVo.getPage(),deviceSelectIdsVo.getSize())));
    }

    @ApiOperation(value = "根据装备id查询装备详情", notes = "根据装备id查询装备详情")
    @PostMapping("/selectRepairDeviceByIds")
    public ResponseEntity selectByIds2(@RequestBody List<Detail> ids){
        List<DeviceLibrary> deviceLibraries = new ArrayList<>();
        ids.forEach(detail -> {
            DeviceLibrary d = deviceLibraryService.getOne(detail.getDeviceId());
            d.setDetailId(detail.getId());
            d.setRemark(detail.getRemark());
            d.setConfigName();
            deviceLibraries.add(d);
        });
        return ResponseEntity.ok(deviceLibraries);
    }

    @ApiOperation(value = "模糊查询装备分页", notes = "可以通过这个接口查询装备")
    @PostMapping("/selectDevicePage")
    public ResponseEntity selectDevicePage(@RequestBody DeviceLibrarySelectVo deviceLibrarySelectVo) {
        Page<DeviceLibrary> deviceLibraryEntities = deviceLibraryService.getPage(deviceLibrarySelectVo, deviceLibrarySelectVo.getPageable());
        deviceLibraryEntities.getContent().forEach(DeviceLibrary::setConfigName);
        return ResultUtil.success(deviceLibraryEntities);
    }

    @ApiOperation(value = "模糊查询装备列表", notes = "可以通过这个接口查询装备列表")
    @PostMapping("/selectDeviceList")
    public ResponseEntity selectDeviceList(@RequestBody DeviceLibrarySelectVo deviceLibrarySelectVo) {
        List<DeviceLibrary> deviceLibraryEntities = deviceLibraryService.getList(deviceLibrarySelectVo);
        deviceLibraryEntities.forEach(DeviceLibrary::setConfigName);
        return ResultUtil.success(deviceLibraryEntities);
    }

    @ApiOperation(value = "查询所有装备列表", notes = "可以通过这个接口查询所有装备列表")
    @PostMapping("/selectAllDeviceList")
    public ResponseEntity selectAllDeviceList(@RequestBody DeviceLibrarySelectVo deviceLibrarySelectVo) {
        List<DeviceLibrary> deviceLibraryEntities = deviceLibraryService.getAllList(deviceLibrarySelectVo);
        deviceLibraryEntities.forEach(DeviceLibrary::setConfigName);
        return ResultUtil.success(deviceLibraryEntities);
    }

    @ApiOperation(value = "查询检查装备列表", notes = "可以通过这个接口查询装备列表")
    @GetMapping("/selectCheckDeviceList")
    public ResponseEntity selectDeviceList() {
        String unit = userUtils.getCurrentUserUnitName();
        PredicateBuilder<DeviceLibrary> predicateBuilder = Specifications.and();
        predicateBuilder.eq("ownUnit", unit);
        List<DeviceLibrary> deviceLibraries = deviceLibraryDao.findAll(predicateBuilder.build());
        deviceLibraries.forEach(DeviceLibrary::setConfigName);
        List<DeviceLibrary> deviceLibraryEntities = deviceLibraries.stream()
                .filter(deviceLibrary -> deviceLibrary.getLocationUnit().equals(unit))
                .collect(Collectors.toList());
        deviceLibraries.removeAll(deviceLibraryEntities);
        Map<String,Object> map = new HashMap<>();
        map.put("stockDevices",deviceLibraryEntities);
        map.put("notInStockDevices",deviceLibraries);
        return ResultUtil.success(map);
    }

    @ApiOperation(value = "模糊查询可配发的在库装备列表", notes = "可以通过这个接口查询可配发装备")
    @PostMapping("/selectAllotDeviceList")
    public ResponseEntity selectAllotDeviceList(@RequestBody DeviceLibrarySelectVo deviceLibrarySelectVo) {
        List<DeviceLibrary> deviceLibraryEntities = deviceLibraryService.getAllotList(deviceLibrarySelectVo);
        return ResultUtil.success(deviceLibraryEntities);
    }

    @ApiOperation(value = "模糊查询核心装备分页", notes = "可以通过这个接口查询装备列表")
    @PostMapping("/core/feature/summary")
    public ResponseEntity selectCoreDevicePage(@RequestBody DeviceLibrarySelectVo deviceLibrarySelectVo) {
//        long strat = System.currentTimeMillis();
        Boolean hasModelDim = deviceLibrarySelectVo.getModelDim()!=null;
        Boolean hasNameDim = deviceLibrarySelectVo.getNameDim()!=null;
        Boolean hasSeqDim = deviceLibrarySelectVo.getSeqDim()!=null;
        Boolean hasLocationUnitDim = deviceLibrarySelectVo.getLocationUnitDim()!=null;
        Boolean hasOwnUnitDim = deviceLibrarySelectVo.getOwnUnitDim()!=null;
        Boolean hasLifeStatusDim = deviceLibrarySelectVo.getLifeStatusDim()!=null;
        Boolean hasUpdateTimeDim = deviceLibrarySelectVo.getUpdateTimeDim()!=null;
        Boolean hasRfidCardDim = deviceLibrarySelectVo.getRfidCardDim()!=null;
        SimpleDateFormat sdf =  new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
        List<DeviceLibrary> resultList = deviceLibraryService.getCoreDevicePage(deviceLibrarySelectVo);
        if (hasModelDim||hasLifeStatusDim||hasLocationUnitDim||hasNameDim||hasOwnUnitDim||hasSeqDim) {
            resultList = resultList.stream().filter(deviceLibrary -> {
                Boolean containModelDim = !hasModelDim||deviceLibrary.getModel().contains(deviceLibrarySelectVo.getModelDim());
                Boolean containNameDim = !hasNameDim||deviceLibrary.getName().contains(deviceLibrarySelectVo.getNameDim());
                Boolean containSeqDim = !hasSeqDim||deviceLibrary.getSeqNumber().contains(deviceLibrarySelectVo.getSeqDim());
                Boolean containLocationUnitDim = !hasLocationUnitDim||deviceLibrary.getLocationUnit().contains(deviceLibrarySelectVo.getLocationUnitDim());
                Boolean containOwnUnitDim = !hasOwnUnitDim||deviceLibrary.getOwnUnit().contains(deviceLibrarySelectVo.getOwnUnitDim());
                Boolean containLifeStatusDim = !hasLifeStatusDim||deviceLibrary.getLifeStatusName().contains(deviceLibrarySelectVo.getLifeStatusDim());
                Boolean containUpdateTimeDim = !hasUpdateTimeDim||sdf.format(deviceLibrary.getUpdateTime()).contains(deviceLibrarySelectVo.getUpdateTimeDim());
                Boolean containRfidCardDim = !hasRfidCardDim||(deviceLibrary.getRfidCardId()!=null&&deviceLibrary.getRfidCardId().contains(deviceLibrarySelectVo.getRfidCardDim()));
                return containModelDim&&containNameDim&&containSeqDim&&containLocationUnitDim&&containOwnUnitDim&&containLifeStatusDim&&containUpdateTimeDim&&containRfidCardDim;
            }).collect(Collectors.toList());
        }
//        List<DeviceVo> deviceVos = resultList.stream().map(DeviceLibrary::parseVo).collect(Collectors.toList());
        Page<DeviceLibrary> deviceLibraryEntities = PageUtil.getPerPage(deviceLibrarySelectVo.getPage(), deviceLibrarySelectVo.getSize(), resultList, deviceLibrarySelectVo.getPageable());
        Map<String,Object> map = new HashMap<>();
        Map<Integer,String> lifeStatusMap = configCache.getLifeStatusMap();
        Set<Integer> status = new HashSet<>();
        Set<String> models = new HashSet<>();
        Set<String> names = new HashSet<>();
        Set<String> ownUnits = new HashSet<>();
        Set<String> locationUnits = new HashSet<>();
        resultList.forEach(deviceVo -> {
            deviceVo.setConfigName();
            status.add(deviceVo.getLifeStatus());
            models.add(deviceVo.getModel());
            names.add(deviceVo.getName());
            ownUnits.add(deviceVo.getOwnUnit());
            locationUnits.add(deviceVo.getLocationUnit());
        });
        map.put("pages",deviceLibraryEntities);
        map.put("models",models);
        map.put("names",names);
        map.put("ownUnits",ownUnits);
        map.put("locationUnits",locationUnits);
        map.put("lifeStatus",status.stream().map(integer -> new LifeStatusVo(integer,lifeStatusMap.get(integer))).collect(Collectors.toList()));
//        System.out.println("时间："+(System.currentTimeMillis()-strat));
        return ResultUtil.success(map);
    }

    @ApiOperation(value = "模糊查询日常管理装备父子分页", notes = "可以通过这个接口查询装备列表")
    @PostMapping("/core/feature/summary/daily")
    public ResponseEntity selectDailyDevicePage(@RequestBody DeviceLibrarySelectVo deviceLibrarySelectVo) {
        Boolean hasModelDim = deviceLibrarySelectVo.getModelDim()!=null;
        Boolean hasNameDim = deviceLibrarySelectVo.getNameDim()!=null;
        Boolean hasSeqDim = deviceLibrarySelectVo.getSeqDim()!=null;
        Boolean hasLocationUnitDim = deviceLibrarySelectVo.getLocationUnitDim()!=null;
        Boolean hasOwnUnitDim = deviceLibrarySelectVo.getOwnUnitDim()!=null;
        Boolean hasLifeStatusDim = deviceLibrarySelectVo.getLifeStatusDim()!=null;
        Map<String,Object> map = new HashMap<>();
        List<DeviceLibrary> resultList = deviceLibraryService.getList(deviceLibrarySelectVo);
        resultList.forEach(DeviceLibrary::setConfigName);
        if (hasModelDim||hasLifeStatusDim||hasLocationUnitDim||hasNameDim||hasOwnUnitDim||hasSeqDim) {
            resultList = resultList.stream().filter(deviceLibrary -> {
                Boolean containModelDim = !hasModelDim||deviceLibrary.getModel().contains(deviceLibrarySelectVo.getModelDim());
                Boolean containNameDim = !hasNameDim||deviceLibrary.getName().contains(deviceLibrarySelectVo.getNameDim());
                Boolean containSeqDim = !hasSeqDim||deviceLibrary.getSeqNumber().contains(deviceLibrarySelectVo.getSeqDim());
                Boolean containLocationUnitDim = !hasLocationUnitDim||deviceLibrary.getLocationUnit().contains(deviceLibrarySelectVo.getLocationUnitDim());
                Boolean containOwnUnitDim = !hasOwnUnitDim||deviceLibrary.getOwnUnit().contains(deviceLibrarySelectVo.getOwnUnitDim());
                Boolean containLifeStatusDim = !hasLifeStatusDim||deviceLibrary.getLifeStatusName().contains(deviceLibrarySelectVo.getLifeStatusDim());
                return containModelDim&&containNameDim&&containSeqDim&&containLocationUnitDim&&containOwnUnitDim&&containLifeStatusDim;
            }).collect(Collectors.toList());
        }
        Map<Integer, DeviceLibrary> nodeCollect =
                resultList.stream().collect(Collectors.toMap(DeviceLibrary::getId, deviceLibraryEntity -> deviceLibraryEntity));
//        List<Comparator<DeviceVo>> comparators = new ArrayList<>();
//        if (deviceLibrarySelectVo.getOrders().size() > 0) {
//            for (CustomOrder c:deviceLibrarySelectVo.getOrders()) {
//                if ("model".equals(c.getCoulmn())){
//                    if ("ASC".equals(c.getDirection().toString())) {
//                        comparators.add(Comparator.comparing(DeviceVo::getModel,Comparator.nullsFirst(String::compareTo)));
//                    }
//                    else if ("DESC".equals(c.getDirection().toString())) {
//                        comparators.add(Comparator.comparing(DeviceVo::getModel,Comparator.nullsFirst(String::compareTo)).reversed());
//                    }
//                }
//                else if ("name".equals(c.getCoulmn())){
//                    if ("ASC".equals(c.getDirection().toString())) {
//                        comparators.add(Comparator.comparing(DeviceVo::getName,Comparator.nullsFirst(String::compareTo)));
//                    }
//                    else if ("DESC".equals(c.getDirection().toString())) {
//                        comparators.add(Comparator.comparing(DeviceVo::getName,Comparator.nullsFirst(String::compareTo)).reversed());
//                    }
//                }
//                else if ("seqNumber".equals(c.getCoulmn())){
//                    if ("ASC".equals(c.getDirection().toString())) {
//                        comparators.add(Comparator.comparing(DeviceVo::getSeqNumber,Comparator.nullsFirst(String::compareTo)));
//                    }
//                    else if ("DESC".equals(c.getDirection().toString())) {
//                        comparators.add(Comparator.comparing(DeviceVo::getSeqNumber,Comparator.nullsFirst(String::compareTo)).reversed());
//                    }
//                }
//            }
//        }
        List<DeviceLibrary> containList = GetTreeUtils.parseTreeFromDown(
                resultList,
                DeviceLibrary::getId,
                deviceLibraryEntity -> Optional.ofNullable(nodeCollect.get(deviceLibraryEntity.getPartParentId())),
                DeviceLibrary::addChildNode
        );
        Map<Integer,String> lifeStatusMap = configCache.getLifeStatusMap();
        Set<Integer> status = new HashSet<>();
        Set<String> models = new HashSet<>();
        Set<String> names = new HashSet<>();
        Set<String> ownUnits = new HashSet<>();
        Set<String> locationUnits = new HashSet<>();
        resultList.forEach(deviceVo -> {
            deviceVo.setConfigName();
            status.add(deviceVo.getLifeStatus());
            models.add(deviceVo.getModel());
            names.add(deviceVo.getName());
            ownUnits.add(deviceVo.getOwnUnit());
            locationUnits.add(deviceVo.getLocationUnit());
        });
        map.put("models",models);
        map.put("names",names);
        map.put("ownUnits",ownUnits);
        map.put("locationUnits",locationUnits);
        map.put("lifeStatus",status.stream().map(integer -> new LifeStatusVo(integer,lifeStatusMap.get(integer))).collect(Collectors.toList()));
        Page<DeviceLibrary> deviceLibraryEntities = PageUtil.getPerPage(deviceLibrarySelectVo.getPage(), deviceLibrarySelectVo.getSize(), containList, deviceLibrarySelectVo.getPageable());
        map.put("pages",deviceLibraryEntities);
        return ResultUtil.success(map);
    }

    @ApiOperation(value = "查询存在的装备名称", notes = "可以通过这个接口查询存在的装备名称")
    @GetMapping("/selectAllName")
    public ResponseEntity selectAllName() {
        return ResultUtil.success(deviceLibraryService.getAllName());
    }

    @ApiOperation(value = "查询在库的装备所有型号", notes = "可以通过这个接口查询在库的装备所有型号")
    @GetMapping("/select/libraray/models")
    public ResponseEntity selectLibraryModels() {
        return ResultUtil.success(deviceLibraryService.getAllInLibraryModels());
    }

    @ApiOperation(value = "模糊查询标签管理装备分页", notes = "可以通过这个接口查询装备列表")
    @PostMapping("/selectTagDevicePage")
    public ResponseEntity selectTagDevicePage(@RequestBody DeviceLibrarySelectVo deviceLibrarySelectVo) {
        Boolean hasModelDim = deviceLibrarySelectVo.getModelDim()!=null;
        Boolean hasNameDim = deviceLibrarySelectVo.getNameDim()!=null;
        Boolean hasSeqDim = deviceLibrarySelectVo.getSeqDim()!=null;
        Boolean hasSurfaceDim = deviceLibrarySelectVo.getSurfaceDim()!=null;
        Boolean hasLocationUnitDim = deviceLibrarySelectVo.getLocationUnitDim()!=null;
        Boolean hasOwnUnitDim = deviceLibrarySelectVo.getOwnUnitDim()!=null;
        Boolean hasLifeStatusDim = deviceLibrarySelectVo.getLifeStatusDim()!=null;
        Boolean hasUpdateTimeDim = deviceLibrarySelectVo.getUpdateTimeDim()!=null;
        Boolean hasCreateTimeDim = deviceLibrarySelectVo.getCreateTimeDim()!=null;
        SimpleDateFormat sdf =  new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
        List<DeviceLibrary> resultList = deviceLibraryService.getTagPage(deviceLibrarySelectVo, deviceLibrarySelectVo.getPageable());
        resultList.forEach(DeviceLibrary::setConfigName);
        if (hasModelDim||hasLifeStatusDim||hasLocationUnitDim||hasNameDim||hasOwnUnitDim||hasSeqDim) {
            resultList = resultList.stream().filter(deviceLibrary -> {
                Boolean containModelDim = !hasModelDim||deviceLibrary.getModel().contains(deviceLibrarySelectVo.getModelDim());
                Boolean containNameDim = !hasNameDim||deviceLibrary.getName().contains(deviceLibrarySelectVo.getNameDim());
                Boolean containSeqDim = !hasSeqDim||deviceLibrary.getSeqNumber().contains(deviceLibrarySelectVo.getSeqDim());
                Boolean containSurfaceDim = !hasSurfaceDim||(deviceLibrary.getRfidSurfaceId()!=null&&deviceLibrary.getRfidSurfaceId().contains(deviceLibrarySelectVo.getSurfaceDim()));
                Boolean containLocationUnitDim = !hasLocationUnitDim||deviceLibrary.getLocationUnit().contains(deviceLibrarySelectVo.getLocationUnitDim());
                Boolean containOwnUnitDim = !hasOwnUnitDim||deviceLibrary.getOwnUnit().contains(deviceLibrarySelectVo.getOwnUnitDim());
                Boolean containLifeStatusDim = !hasLifeStatusDim||deviceLibrary.getLifeStatusName().contains(deviceLibrarySelectVo.getLifeStatusDim());
                Boolean containUpdateTimeDim = !hasUpdateTimeDim||sdf.format(deviceLibrary.getUpdateTime()).contains(deviceLibrarySelectVo.getUpdateTimeDim());
                Boolean containCreateTimeDim = !hasCreateTimeDim||sdf.format(deviceLibrary.getCreateTime()).contains(deviceLibrarySelectVo.getCreateTimeDim());
                return containModelDim&&containNameDim&&containSeqDim&&containLocationUnitDim&&containOwnUnitDim&&containLifeStatusDim&&containUpdateTimeDim&&containCreateTimeDim&&containSurfaceDim;
            }).collect(Collectors.toList());
        }
        Page<DeviceLibrary> deviceLibraryEntities = PageUtil.getPerPage(deviceLibrarySelectVo.getPage(), deviceLibrarySelectVo.getSize(), resultList, deviceLibrarySelectVo.getPageable());
        Map<String,Object> map = new HashMap<>();
        Map<Integer,String> lifeStatusMap = configCache.getLifeStatusMap();
        Set<Integer> status = resultList.stream().map(DeviceLibrary::getLifeStatus).collect(Collectors.toSet());
        map.put("pages",deviceLibraryEntities);
        map.put("models",resultList.stream().map(DeviceLibrary::getModel).collect(Collectors.toSet()));
        map.put("names",resultList.stream().map(DeviceLibrary::getName).collect(Collectors.toSet()));
        map.put("ownUnits",resultList.stream().map(DeviceLibrary::getOwnUnit).collect(Collectors.toSet()));
        map.put("locationUnits",resultList.stream().map(DeviceLibrary::getLocationUnit).collect(Collectors.toSet()));
        map.put("lifeStatus",status.stream().map(integer -> new LifeStatusVo(integer,lifeStatusMap.get(integer))).collect(Collectors.toList()));
        return ResultUtil.success(map);
    }

    @ApiOperation(value = "模糊查询核心装备统计分页", notes = "可以通过这个接口查询装备列表")
    @PostMapping("/core/stat/summary")
    public ResponseEntity getDeviceStatisticsPage(@RequestBody DeviceLibrarySelectVo deviceLibrarySelectVo) {
        List<DeviceStatisticsVo> deviceStatisticsVoList = deviceLibraryService.getDeviceStatisticsPage(deviceLibrarySelectVo, deviceLibrarySelectVo.getPageable());
        Page<DeviceStatisticsVo> deviceStatisticsVos = PageUtil.getPerPage(deviceLibrarySelectVo.getPage(), deviceLibrarySelectVo.getSize(), deviceStatisticsVoList, deviceLibrarySelectVo.getPageable());
        Map<String,Object> map = new HashMap<>();
        map.put("pages",deviceStatisticsVos);
        map.put("models",deviceStatisticsVoList.stream().map(DeviceStatisticsVo::getModel).collect(Collectors.toSet()));
        map.put("names",deviceStatisticsVoList.stream().map(DeviceStatisticsVo::getName).collect(Collectors.toSet()));
        return ResultUtil.success(map);
    }

    @ApiOperation(value = "查询核心装备详情的详情", notes = "可以通过这个接口查询核心装备详情的详情")
    @GetMapping("/core/feature/detail/{id}")
    public ResponseEntity getDeviceDetail(@PathVariable("id") @Min(value = 1,message = "id不能小于1") int id) {
        DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id).setConfigName();
        DeviceDetailVo deviceDetailVo = new DeviceDetailVo();
        List<DeviceLibrary> libraryEntities = new ArrayList<>();
        //查询日志
        List<DeviceLogUserVo> deviceLogEntities = deviceLogDao.getAllByDeviceIdAndType(id, 0).stream()
                .map(DeviceLog::parse2Dto)
                .map(DeviceLogDto::toVo)
                .sorted(Comparator.comparing(DeviceLogUserVo::getCreateTime,Comparator.nullsLast(Date::compareTo)).reversed())
                .collect(Collectors.toList());
        //判断有没有维修新装备换新的情况
        List<DeviceLogUserVo> deviceLogUserVos = new ArrayList<>();
        List<Integer> integerList = deviceChangeService.getAllFatherDevice(id);
        if (integerList != null && integerList.size() > 0) {
            for (int i = integerList.size() - 1; i >= 0; i--) {
                deviceLogUserVos.addAll(deviceLogDao.getAllByDeviceIdAndType(integerList.get(i), 0).stream()
                        .map(DeviceLog::parse2Dto)
                        .map(DeviceLogDto::toVo)
                        .sorted(Comparator.comparing(DeviceLogUserVo::getCreateTime,Comparator.nullsLast(Date::compareTo)).reversed())
                        .collect(Collectors.toList()));
            }
        }
        deviceLogUserVos.addAll(deviceLogEntities);
        libraryEntities.add(deviceLibraryEntity);
        deviceDetailVo.setDeviceLogEntityList(deviceLogUserVos.stream().sorted(Comparator.comparing(DeviceLogUserVo::getCreateTime).reversed()).collect(Collectors.toList()));
        if (deviceLibraryEntity.getIsPart() == 0) {
            List<DeviceLibrary> partList = deviceLibraryDao.getAllByPartParentIdAndIsPart(id, 1);
            partList.forEach(DeviceLibrary::setConfigName);
            libraryEntities.addAll(partList);
            deviceDetailVo.setDeviceList(libraryEntities);
            return ResultUtil.success(deviceDetailVo);
        } else {
            if (deviceLibraryEntity.getPartParentId() == null) {
                deviceDetailVo.setDeviceList(libraryEntities);
                return ResultUtil.success(deviceDetailVo);
            }
            libraryEntities.add(deviceLibraryService.getOne(deviceLibraryEntity.getPartParentId()).setConfigName());
            deviceDetailVo.setDeviceList(libraryEntities);
            return ResultUtil.success(deviceDetailVo);
        }
    }

    @ApiOperation(value = "更新装备库", notes = "可以通过这个接口更新装备库")
    @PostMapping("/updateDeviceLibrary")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity updateDeviceLibrary(@RequestBody @Validated DeviceEditVo deviceEditVo) {
        DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(deviceEditVo.getDeviceId());
        //更新装备信息
        if (deviceEditVo.getUpdateVoList() != null) {
            DeviceLibraryUpdateVo libraryUpdateVo = deviceEditVo.getUpdateVoList();
            if (libraryUpdateVo.getInvisibleRange() != null) {
                deviceLibraryEntity.setInvisibleRange(libraryUpdateVo.getInvisibleRange());
            }
            if (libraryUpdateVo.getLifeStatus() != null && !libraryUpdateVo.getLifeStatus().equals(deviceLibraryEntity.getLifeStatus())) {
                //添加装备日志
                String remark = "将装备的生命状态由" + configCache.getLifeStatusMap().getOrDefault(deviceLibraryEntity.getLifeStatus(),"空") + "改为" + configCache.getLifeStatusMap().get(libraryUpdateVo.getLifeStatus());
                DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                deviceLogService.addLog(deviceLogDto);
                deviceLibraryEntity.setLifeStatus(libraryUpdateVo.getLifeStatus());
            }
            if (libraryUpdateVo.getLocationUnit() != null && !libraryUpdateVo.getLocationUnit().equals(deviceLibraryEntity.getLocationUnit())) {
                //添加装备日志
                String remark = "将装备的所在单位由" + deviceLibraryEntity.getLocationUnit() + "改为" + libraryUpdateVo.getLocationUnit();
                DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                deviceLogService.addLog(deviceLogDto);
                deviceLibraryEntity.setLocationUnit(libraryUpdateVo.getLocationUnit());
            }
            if (libraryUpdateVo.getManageStatus() != null) {
                deviceLibraryEntity.setManageStatus(libraryUpdateVo.getManageStatus());
            }
            if (libraryUpdateVo.getMatchingRange() != null && !libraryUpdateVo.getMatchingRange().equals(deviceLibraryEntity.getMatchingRange())) {
                //添加装备日志
                String remark = "将装备的配用范围由" + configCache.getMatchingRangeMap().getOrDefault(deviceLibraryEntity.getMatchingRange(),"空") + "改为" + configCache.getMatchingRangeMap().get(libraryUpdateVo.getMatchingRange());
                DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                deviceLogService.addLog(deviceLogDto);
                deviceLibraryEntity.setMatchingRange(libraryUpdateVo.getMatchingRange());
            }
            if (libraryUpdateVo.getModel() != null && !libraryUpdateVo.getModel().equals(deviceLibraryEntity.getModel())) {
                //添加装备日志
                String remark = "将装备的型号由" + deviceLibraryEntity.getModel() + "改为" + libraryUpdateVo.getModel();
                DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                deviceLogService.addLog(deviceLogDto);
                deviceLibraryEntity.setModel(libraryUpdateVo.getModel());
            }
            if (libraryUpdateVo.getName() != null && !libraryUpdateVo.getName().equals(deviceLibraryEntity.getName())) {
                //添加装备日志
                String remark = "将装备的名称由" + deviceLibraryEntity.getName() + "改为" + libraryUpdateVo.getName();
                DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                deviceLogService.addLog(deviceLogDto);
                deviceLibraryEntity.setName(libraryUpdateVo.getName());
            }
            if (libraryUpdateVo.getOwnUnit() != null && !libraryUpdateVo.getOwnUnit().equals(deviceLibraryEntity.getOwnUnit())) {
                //添加装备日志
                String remark = "将装备的所属单位由" + deviceLibraryEntity.getOwnUnit() + "改为" + libraryUpdateVo.getOwnUnit();
                DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                deviceLogService.addLog(deviceLogDto);
                deviceLibraryEntity.setOwnUnit(libraryUpdateVo.getOwnUnit());
            }
            if (libraryUpdateVo.getProdNumber() != null && !libraryUpdateVo.getProdNumber().equals(deviceLibraryEntity.getProdNumber())) {
                //添加装备日志
                String remark = "将装备生产序列号由" + deviceLibraryEntity.getProdNumber() + "改为" + libraryUpdateVo.getProdNumber();
                DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                deviceLogService.addLog(deviceLogDto);
                deviceLibraryEntity.setProdNumber(libraryUpdateVo.getProdNumber());
            }
            if (libraryUpdateVo.getSecretLevel() != null) {
                deviceLibraryEntity.setSecretLevel(libraryUpdateVo.getSecretLevel());
            }
            if (libraryUpdateVo.getSeqNumber() != null && !libraryUpdateVo.getSeqNumber().equals(deviceLibraryEntity.getSeqNumber())) {
                if (deviceLibraryDao.getAllBySeqNumber(libraryUpdateVo.getSeqNumber()).size()>0){
                    throw new ApiException("序列号"+libraryUpdateVo.getSeqNumber()+"已存在");
                }
                else {
                    String remark = "将装备序列号由" + deviceLibraryEntity.getSeqNumber() + "改为" + libraryUpdateVo.getSeqNumber();
                    DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                    deviceLogService.addLog(deviceLogDto);
                    deviceLibraryEntity.setSeqNumber(libraryUpdateVo.getSeqNumber());
                }
            }
            if (libraryUpdateVo.getStorageType() != null && !libraryUpdateVo.getStorageType().equals(deviceLibraryEntity.getStorageType())) {
                //添加装备日志
                String remark = "将装备的入库类型由" + configCache.getStorageTypeMap().getOrDefault(deviceLibraryEntity.getStorageType(),"空") + "改为" + configCache.getStorageTypeMap().get(libraryUpdateVo.getStorageType());
                DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                deviceLogService.addLog(deviceLogDto);
                deviceLibraryEntity.setStorageType(libraryUpdateVo.getStorageType());
            }
            if (libraryUpdateVo.getType() != null) {
                deviceLibraryEntity.setType(libraryUpdateVo.getType());
            }
            deviceLibraryService.update(deviceLibraryEntity);
        }
        //添加绑定配件
        if (deviceEditVo.getPartAddIdList() != null) {
            for (Integer id : deviceEditVo.getPartAddIdList()) {
                if (id > 0) {
                    DeviceLibrary d = deviceLibraryService.getOne(id);
                    if (deviceLibraryEntity.getIsPart() == 0 && d.getIsPart() == 1 && d.getPartParentId() == null) {
                        d.setPartParentId(deviceEditVo.getDeviceId());
                        deviceLibraryService.update(d);
                        //添加装备日志
                        String remark = "将序列号为" + d.getSeqNumber() + "的配件与序列号为" + deviceLibraryEntity.getSeqNumber() + "的装备绑定";
                        DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                        DeviceLogDto deviceLogDto2 = new DeviceLogDto(id, remark, null);
                        deviceLogService.addLog(deviceLogDto);
                        deviceLogService.addLog(deviceLogDto2);
                    }
                    if (deviceLibraryEntity.getIsPart() == 1 && d.getIsPart() == 0) {
                        deviceLibraryEntity.setPartParentId(id);
                        deviceLibraryService.update(deviceLibraryEntity);
                        //添加装备日志
                        String remark = "将序列号为" + deviceLibraryEntity.getSeqNumber() + "的配件与序列号为" + d.getSeqNumber() + "的装备绑定";
                        DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                        DeviceLogDto deviceLogDto2 = new DeviceLogDto(id, remark, null);
                        deviceLogService.addLog(deviceLogDto);
                        deviceLogService.addLog(deviceLogDto2);
                    }
                }
            }
        }
        //删除和配件的绑定
        if (deviceEditVo.getPartIdDeleteList() != null) {
            for (Integer id : deviceEditVo.getPartIdDeleteList()) {
                if (id > 0) {
                    DeviceLibrary d = deviceLibraryService.getOne(id);
                    if (d.getIsPart() == 1 && d.getPartParentId().equals(deviceEditVo.getDeviceId())) {
                        d.setPartParentId(null);
                        deviceLibraryService.update(d);
                        //添加装备日志
                        String remark = "将序列号为" + d.getRfidSurfaceId() + "的配件与序列号为" + deviceLibraryEntity.getRfidSurfaceId() + "的装备解绑";
                        DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                        DeviceLogDto deviceLogDto2 = new DeviceLogDto(id, remark, null);
                        deviceLogService.addLog(deviceLogDto);
                        deviceLogService.addLog(deviceLogDto2);
                    }
                    if (deviceLibraryEntity.getIsPart() == 1 && d.getIsPart() == 0 && deviceLibraryEntity.getPartParentId().equals(id)) {
                        deviceLibraryEntity.setPartParentId(null);
                        deviceLibraryService.update(deviceLibraryEntity);
                        //添加装备日志
                        String remark = "将序列号为" + deviceLibraryEntity.getRfidSurfaceId() + "的配件与序列号为" + d.getRfidSurfaceId() + "的装备解绑";
                        DeviceLogDto deviceLogDto = new DeviceLogDto(deviceEditVo.getDeviceId(), remark, null);
                        DeviceLogDto deviceLogDto2 = new DeviceLogDto(id, remark, null);
                        deviceLogService.addLog(deviceLogDto);
                        deviceLogService.addLog(deviceLogDto2);
                    }
                }
            }
        }
        return ResultUtil.success("更新成功");
    }

    @ApiOperation(value = "通过序列号查询配件", notes = "通过表面号查询配件")
    @GetMapping("/selectPart/{rfid}")
    public ResponseEntity selectPart(@PathVariable("rfid") String rfid) {
        List<DeviceLibrary> libraryEntities = deviceLibraryDao.getAllBySeqNumber(rfid);
        libraryEntities.forEach(DeviceLibrary::setConfigName);
        List<DeviceLibrary> deviceLibraryEntityList = libraryEntities.stream().filter(deviceLibraryEntity -> deviceLibraryEntity.getIsPart() == 1).collect(Collectors.toList());
        return ResultUtil.success(deviceLibraryEntityList);
    }

    @ApiOperation(value = "通过序列号查询装备", notes = "通过表面号查询装备")
    @GetMapping("/selectDevice/{rfid}")
    public ResponseEntity selectDevice(@PathVariable("rfid") String rfid) {
        List<DeviceLibrary> libraryEntities = deviceLibraryDao.getAllBySeqNumber(rfid);
        libraryEntities.forEach(DeviceLibrary::setConfigName);
        List<DeviceLibrary> deviceLibraryEntityList = libraryEntities.stream().filter(deviceLibraryEntity -> deviceLibraryEntity.getIsPart() == 0).collect(Collectors.toList());
        return ResultUtil.success(deviceLibraryEntityList);
    }

    @ApiOperation(value = "查询维修报废换新装备", notes = "查询装备")
    @GetMapping("/select/newChange/{id}")
    public ResponseEntity selectNewChangeDevice(@PathVariable("id") @Min(value = 1,message = "id不能小于1") int id) {
        DeviceLibrary deviceLibrary = deviceLibraryService.getOne(id);
        List<DeviceLibrary> deviceLibraries = deviceLibraryDao.getAllByTypeAndNameAndModel(deviceLibrary.getType(), deviceLibrary.getName(), deviceLibrary.getModel());
        deviceLibraries.forEach(DeviceLibrary::setConfigName);
        return ResultUtil.success(deviceLibraries.stream().filter(deviceLibrary1 -> !deviceLibrary1.getId().equals(id) && deviceLibrary1.getLifeStatus() == 2 && deviceLibrary1.getOwnUnit().equals(userUtils.getCurrentUserUnitName()) &&deviceLibrary1.getLocationUnit().equals(userUtils.getCurrentUserUnitName())).collect(Collectors.toList()));
    }
}
