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

import com.tykj.dev.config.cache.ConfigCache;
import com.tykj.dev.config.swagger.AutoDocument;
import com.tykj.dev.device.file.service.FilesUtil;
import com.tykj.dev.device.library.repository.DeviceLibraryDao;
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.DeviceLibrarySelectVo;
import com.tykj.dev.device.library.subject.vo.DeviceLogUserVo;
import com.tykj.dev.device.packing.repository.PackingLibraryDao;
import com.tykj.dev.device.packing.repository.PackingLogDao;
import com.tykj.dev.device.packing.service.PackingLibraryService;
import com.tykj.dev.device.packing.service.PackingLogService;
import com.tykj.dev.device.packing.subject.domin.PackingLibrary;
import com.tykj.dev.device.packing.subject.domin.PackingLog;
import com.tykj.dev.device.packing.subject.vo.*;
import com.tykj.dev.device.repair.repository.RepairDetailDao;
import com.tykj.dev.device.repair.subject.domin.RepairDetail;
import com.tykj.dev.device.task.service.TaskLogService;
import com.tykj.dev.device.task.service.TaskService;
import com.tykj.dev.device.user.read.service.MessageService;
import com.tykj.dev.device.user.read.subject.bto.MessageBto;
import com.tykj.dev.device.user.subject.service.UserPublicService;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.misc.base.ResultObj;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.*;
import com.tykj.dev.socket.MyWebSocket;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
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.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

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

@RestController
@Api(tags = "列装管理模块", description = "列装管理接口")
@AutoDocument
@RequestMapping("/packing")
@Validated
@Slf4j
public class PackingController {

    @Autowired
    PackingLibraryService packingLibraryService;

    @Autowired
    TaskService taskService;

    @Autowired
    UserUtils userUtils;

    @Autowired
    UserPublicService userPublicService;

    @Autowired
    TaskLogService taskLogService;

    @Autowired
    MyWebSocket myWebSocket;

    @Autowired
    PackingLibraryDao packingLibraryDao;

    @Autowired
    DeviceLibraryService deviceLibraryService;

    @Autowired
    MessageService messageService;

    @Autowired
    PackingLogDao packingLogDao;

    @Autowired
    PackingLogService packingLogService;

    @Autowired
    ConfigCache configCache;

    @Autowired
    DeviceLibraryDao deviceLibraryDao;

    @Autowired
    private RepairDetailDao repairDetailDao;

    @Autowired
    private DeviceLogService deviceLogService;
    @Autowired
    @Qualifier("taskExecutor")
    Executor executor;

    @ApiOperation(value = "查询列装详情", notes = "可以通过这个接口查询列装详情")
    @GetMapping(value = "/detail/{billId}")
    public ResponseEntity selectDetail(@PathVariable("billId") @Min(value = 1,message = "billId不能小于1") int billId) {
        PackingDetailVo packingDetailVo = new PackingDetailVo();
        //获取taskBto
//        TaskBto taskBto = taskService.get(billId, BusinessEnum.PACKING.id);
        //获取列装主件
        PackingLibrary packingLibraryEntity = packingLibraryService.getOne(billId);
//        packingLibraryEntity.setUserA(userPublicService.getOne(packingLibraryEntity.getUseraId()).getName());
//        packingLibraryEntity.setUserB(userPublicService.getOne(packingLibraryEntity.getUserbId()).getName());
        packingDetailVo.setPackingLibrary(packingLibraryEntity.setConfigName());
        //获取所有配件
        List<PackingLibrary> packingLibraryEntities = packingLibraryService.selectAllPart(billId);
        packingDetailVo.setParts(packingLibraryEntities);
        //获取业务日志
        List<DeviceLogUserVo> deviceLogUserVos = packingLogDao.getAllByPackingId(billId).stream().map(PackingLog::toVo).sorted(Comparator.comparing(DeviceLogUserVo::getCreateTime).reversed()).collect(Collectors.toList());
        packingDetailVo.setDeviceLogUserVos(deviceLogUserVos);
        return ResultUtil.success(packingDetailVo);
    }
    @ApiOperation(value = "添加列装型号")
    @PostMapping("/add/model")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity addModel(@RequestBody @Validated AddModel addModel){
        if (packingLibraryService.modelIsExist(addModel.getModel())){
            Map<String,Object> map = new HashMap<>();
            map.put("error","型号"+addModel.getModel()+"已存在");
            return ResponseEntity.ok(map);
        }
        PackingLibrary packingLibrary = new PackingLibrary();
        BeanUtils.copyProperties(addModel,packingLibrary);
        packingLibrary.setIsRoot(1);
        packingLibrary.setName("");
        packingLibrary.setPackingStatus(2);
        //设置排序 赋值为null
        packingLibrary.setShowOrder(null);
        PackingLibrary packingLibrary1 = packingLibraryService.addEntity(packingLibrary);
        String message = "添加列装型号:"+addModel.getModel();
        //添加列装日志
        PackingLog packingLog = new PackingLog();
        packingLog.setRemark(message);
        packingLog.setPackingId(packingLibrary1.getId());
        packingLogService.add(packingLog);
        //发送阅知信息
        List<Integer> userIds = userPublicService.findOtherUser(userUtils.getCurrentUserId());
        MessageBto messageBto = new MessageBto(0,1,message,userIds,0);
        messageBto.setRecord(packingLibrary1.getId().toString());
        messageService.add(messageBto);
        //更新型号和排序号的对应map
        packingLibraryService.getSortMap();
        return ResponseEntity.ok(packingLibraryService.getOne(packingLibrary1.getId()));
    }
//    @ApiOperation(value = "添加列装型号")
//    @PostMapping("/add/model")
//    @Transactional(rollbackFor = Exception.class)
//    public ResponseEntity addModel(@RequestBody @Validated AddModel addModel){
//        if (packingLibraryService.modelIsExist(addModel.getModel())){
//            Map<String,Object> map = new HashMap<>();
//            map.put("error","型号"+addModel.getModel()+"已存在");
//            return ResponseEntity.ok(map);
//        }
//        PackingLibrary packingLibrary = new PackingLibrary();
//        BeanUtils.copyProperties(addModel,packingLibrary);
//        packingLibrary.setIsRoot(1);
//        packingLibrary.setName("");
//        packingLibrary.setPackingStatus(2);
//        packingLibrary.setShowOrder(99999);
//        PackingLibrary packingLibrary1 = packingLibraryService.addEntity(packingLibrary);
//        List<PackingLibrary> packingLibraries1 = packingLibraryService.getInsertList(new SelectPack()).stream().sorted(Comparator.comparing(PackingLibrary::getModel,Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
//        int order = 9999;
//        for (int i=1;i<=packingLibraries1.size();i++){
//            PackingLibrary packingLibrary2 = packingLibraries1.get(i-1);
//            if (packingLibrary2.getId().equals(packingLibrary1.getId())){
//                packingLibrary2.setShowOrder(i);
//                packingLibraryService.update(packingLibrary2);
//                order = i;
//                break;
//            }
//        }
//        for (PackingLibrary p:packingLibraries1) {
//            if(p.getShowOrder()!=null){
//                if (!p.getId().equals(packingLibrary1.getId()) && p.getShowOrder() >= order){
//                    p.setShowOrder(p.getShowOrder()+1);
//                    packingLibraryService.update(p);
//                }
//            }
//
//        }
////        TaskBto taskBto = new TaskBto(StatusEnum.END.id, "列装业务", null, ".", packingLibrary1.getId(), 1, userUtils.getCurrentUnitId(), 0, null, Collections.singletonList(userUtils.getCurrentUserId()));
////        TaskBto saveEntity = taskService.start(taskBto);
//        String message = "添加列装型号:"+addModel.getModel();
////        //添加业务日志
////        TaskLogBto taskLogBto2 = new TaskLogBto(saveEntity.getId(), message, null);
////        taskLogService.addLog(taskLogBto2);
//        //添加列装日志
//        PackingLog packingLog = new PackingLog();
//        packingLog.setRemark(message);
//        packingLog.setPackingId(packingLibrary1.getId());
//        packingLogService.add(packingLog);
//        //发送阅知信息
//        List<Integer> userIds = userPublicService.findOtherUser(userUtils.getCurrentUserId());
//        MessageBto messageBto = new MessageBto(0,1,message,userIds,0);
//        messageBto.setRecord(packingLibrary1.getId().toString());
//        messageService.add(messageBto);
//        packingLibraryService.setOrder(packingLibraryService.getInsertList(new SelectPack()));
//        //更新型号和排序号的对应map
//        packingLibraryService.getSortMap();
//        return ResponseEntity.ok(packingLibraryService.getOne(packingLibrary1.getId()));
//    }

    @ApiOperation(value = "添加列装装备")
    @PostMapping("/add")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity addPack(@RequestBody @Validated AddPack addPack){
        //相同名称的同级列装
        if (packingLibraryService.hasSamePack(addPack.getPartParentId(),addPack.getType(),addPack.getStyle(),addPack.getName(),addPack.getSecretLevel(),addPack.getInvisibleRange())) {
//            if (packingLibraryService.nameIsExist(addPack.getModel(), addPack.getName())) {
//                Map<String, Object> map = new HashMap<>();
//                map.put("error", "型号" + addPack.getModel() + "下名称为" + addPack.getName() + "的装备已存在");
//                return ResponseEntity.ok(map);
//            }
            //同级列装是否有同级范围的
            Boolean matchingRangeIsExist = packingLibraryService.matchingRangeIsExist(addPack.getPartParentId(), addPack.getMatchingRange(), addPack.getType(), addPack.getStyle(), addPack.getName(), addPack.getSecretLevel(), addPack.getInvisibleRange());
            if (matchingRangeIsExist) {
                Map<String, Object> map = new HashMap<>();
                map.put("error", "型号" + addPack.getModel() + "下配用范围为" + configCache.getMatchingRangeMap().get(addPack.getMatchingRange()) + "的该装备已存在");
                return ResponseEntity.ok(map);
            }
        }
        PackingLibrary packingLibrary = addPack.toDo();
        PackingLibrary packingLibrary1 = packingLibraryService.getOne(addPack.getPartParentId());
//        TaskBto taskBto = new TaskBto(StatusEnum.END.id, "列装业务", null, ".", packingLibrary1.getId(), 1, userUtils.getCurrentUnitId(), 0, null, Collections.singletonList(userUtils.getCurrentUserId()));
//        TaskBto saveEntity = taskService.start(taskBto);
        if (packingLibrary1.getIsRoot()==1){
            //不是配件
            packingLibrary.setIsPart(0);
            String message = "添加列装型号"+addPack.getModel()+"下的装备:"+addPack.getName();
//            //添加业务日志
//            TaskLogBto taskLogBto2 = new TaskLogBto(saveEntity.getId(), message, null);
//            taskLogService.addLog(taskLogBto2);
            //发送阅知信息
            List<Integer> userIds = userPublicService.findOtherUser(userUtils.getCurrentUserId());
            MessageBto messageBto = new MessageBto(0,1,message,userIds,0);
            messageBto.setRecord(packingLibrary1.getId().toString());
            messageService.add(messageBto);
            //添加列装日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark(message);
            packingLog.setPackingId(packingLibrary1.getId());
            packingLogService.add(packingLog);
        }
        else {
            //是配件
            packingLibrary.setIsPart(1);
            String message = "添加列装型号"+addPack.getModel()+"下的装备附件:"+addPack.getName();
//            //添加业务日志
//            TaskLogBto taskLogBto2 = new TaskLogBto(saveEntity.getId(), message, null);
//            taskLogService.addLog(taskLogBto2);
            //发送阅知信息
            List<Integer> userIds = userPublicService.findOtherUser(userUtils.getCurrentUserId());
            MessageBto messageBto = new MessageBto(0,1,message,userIds,0);
            messageBto.setRecord(packingLibrary1.getId().toString());
            messageService.add(messageBto);
            //添加列装日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark(message);
            packingLog.setPackingId(packingLibrary1.getId());
            packingLogService.add(packingLog);
        }
        PackingLibrary packingLibrary2 = packingLibraryService.addEntity(packingLibrary);
        //添加列装日志
        PackingLog packingLog = new PackingLog();
        packingLog.setRemark("添加列装");
        packingLog.setPackingId(packingLibrary2.getId());
        packingLogService.add(packingLog);
        return ResponseEntity.ok(packingLibrary2);
    }

    @ApiOperation(value = "删除列装")
    @PostMapping("/delete/{id}")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity deleteById(@PathVariable("id") int id){
        packingLibraryService.deleteAll(id);
        return ResponseEntity.ok("删除成功");
    }

    @ApiOperation(value = "清空列装回收站")
    @PostMapping("/clean")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity clean(@RequestBody List<Integer> ids){
        packingLibraryService.cleanAll(ids);
        return ResponseEntity.ok("删除成功");
    }

    @ApiOperation(value = "退装恢复列装")
    @PostMapping("/remove")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity remove(@RequestBody List<Integer> ids){
        //父级目录存在的装备id
        List<Integer> list = new ArrayList<>();

        for (Integer id : ids) {
            //先判断是不是目录
            PackingLibrary packingLibrary = packingLibraryDao.findById(id).get();
            if (packingLibrary.getIsRoot() == 1){
                list.add(id);
            }else {
                PackingLibrary byDeleteTagAndId = packingLibraryDao.findByDeleteTagAndIdAndPackingStatus(0, packingLibrary.getPartParentId(),2);
                if (byDeleteTagAndId == null&&!ids.contains(packingLibrary.getPartParentId())){
                    Map<String,Object> map = new HashMap<>();
                    map.put("error","该型号装备的父装备或者目录不存在");
                    return ResponseEntity.ok(map);
                }else {
                    list.add(id);
                }
            }
        }
        packingLibraryService.removeAll(list);
        return ResponseEntity.ok("恢复成功");
    }

    @ApiOperation(value = "查询父子结构列装")
    @PostMapping("/select")
    public ResponseEntity selectPack(@RequestBody SelectPack selectPack){
        Map<String,Object> map = new HashMap<>();
        List<PackingLibrary> resultList = getAllPackingExceptNull(selectPack);
        AtomicInteger sortNum = new AtomicInteger();
        List<PackingLibrary> orderNumbers = setOrderNumber(sortNum, resultList);
//        Page<PackingLibrary> packingLibraries = PageUtil.getPerPage(selectPack.getPage(), selectPack.getSize(), resultList, selectPack.getPageable());
        Page<PackingLibrary> packingLibraries = PageUtil.getPerPage(selectPack.getPage(), selectPack.getSize(), orderNumbers, selectPack.getPageable());
        map.put("pages",packingLibraries);
        List<String> models = new ArrayList<>(resultList.stream().filter(packingLibrary -> packingLibrary.getIsRoot() == 1).map(PackingLibrary::getModel).collect(Collectors.toList()));
        //去重
        models = models.stream().distinct().collect(Collectors.toList());
        map.put("models",models);
        map.put("names",resultList.stream().map(PackingLibrary::getName).collect(Collectors.toSet()));
        return ResultUtil.success(map);
    }

//    @ApiOperation(value = "查询父子结构列装")
//    @PostMapping("/select")
//    public ResponseEntity selectPack(@RequestBody SelectPack selectPack){
//        List<PackingLibrary> resultList;
//        if (selectPack.getContent()==null&&selectPack.getModel()==null&&selectPack.getName()==null&&selectPack.getSecretLevel()==null&&selectPack.getStatus()==null){
//            resultList = packingLibraryService.setOrder(packingLibraryService.getInsertList(selectPack));
//        }
//        else {
//            resultList = packingLibraryService.getInsertList(selectPack);
//        }
//        Page<PackingLibrary> packingLibraries = PageUtil.getPerPage(selectPack.getPage(), selectPack.getSize(), resultList, selectPack.getPageable());
//        Map<String,Object> map = new HashMap<>();
//        map.put("pages",packingLibraries);
//        List<String> models = new ArrayList<>();
////        for (PackingLibrary p : resultList){
////            if (p.getIsRoot()==1){
////                models.add(p.getModel());
////            }
////        }
//
//        models.addAll(resultList.stream().filter(packingLibrary -> packingLibrary.getIsRoot() == 1).map(PackingLibrary::getModel).collect(Collectors.toList()));
//        //去重
//        models = models.stream().distinct().collect(Collectors.toList());
//        map.put("models",models);
//        map.put("names",resultList.stream().map(PackingLibrary::getName).collect(Collectors.toSet()));
//        return ResultUtil.success(map);
//    }

    @ApiOperation(value = "根据型号查询所有装备附件")
    @PostMapping("/selectByModel")
    public ResponseEntity selectByModel(@RequestBody PackingLibrarySelectVo packingLibrarySelectVo){
        List<PackingLibrary> packingLibraryEntities = packingLibraryService.getList(packingLibrarySelectVo);
        return ResponseEntity.ok(packingLibraryService.setAllotNum(packingLibraryEntities));
    }

    @ApiOperation(value = "批量配发获取序列号")
    @PostMapping("/getAllotSeqs/{num}")
    public ResponseEntity getAllotSeqs(@RequestBody List<Integer> ids,@PathVariable("num") int num){
        List<String> strings = new ArrayList<>();
        List<List<Integer>> deviceIds = new ArrayList<>();
        List<Integer> devIds = new ArrayList<>();
        AllotSeqs allotSeqs1 = new AllotSeqs();
        ids.forEach(integer -> {
            AllotSeqs allotSeqs = packingLibraryService.getAllotAutoSeqs(integer,num);
            strings.add(allotSeqs.getStrings().get(0));
            deviceIds.add(allotSeqs.getIds());
            devIds.addAll(allotSeqs.getIds());
        });
        allotSeqs1.setIdLists(deviceIds);
        allotSeqs1.setIds(devIds);
        allotSeqs1.setStrings(strings);
        return ResponseEntity.ok(allotSeqs1);
    }

    @ApiOperation(value = "获取批量配发最大数量")
    @PostMapping("/getMaxAllotNum")
    public ResponseEntity getMaxAllotNum(@RequestBody List<Integer> ids){
        //输出集合
        List<AllotMaxNum> allotMaxNums = new ArrayList<>();
        //筛选出当前单位在库的装备
        DeviceLibrarySelectVo deviceLibrarySelectVo = new DeviceLibrarySelectVo();
        deviceLibrarySelectVo.setLifeStatus(Collections.singletonList(2));
        long l = System.currentTimeMillis();
        List<DeviceLibrary> deviceLibraries = deviceLibraryService.getList(deviceLibrarySelectVo);
        System.out.println("查询在库时间"+(System.currentTimeMillis()-l));
        //转为列装id的map
        Map<Integer,List<DeviceLibrary>> map = deviceLibraries.stream().collect(groupingBy(DeviceLibrary::getPackingId));
        ids.forEach(integer -> {
            //创建返回对象
            AllotMaxNum allotMaxNum = new AllotMaxNum();
            allotMaxNum.setId(integer);
            //map里value的集合大小为最大可配发数量
            if (!map.containsKey(integer)){
                //设置最大配发数量为0
                allotMaxNum.setMaxNum(0);
            }else {
                allotMaxNum.setMaxNum(map.get(integer).size());
            }
//            allotMaxNum.setMaxNum(size);
            allotMaxNums.add(allotMaxNum);
        });
        return ResponseEntity.ok(allotMaxNums);
    }

    @ApiOperation(value = "批量配发设置区间")
    @PostMapping("/getAllotSeqs/{id}/{num}")
    public ResponseEntity getAllotSeqs(@PathVariable("id") int id,@PathVariable("num") int num,@RequestBody List<Integer> existIds){
        //获取可配发装备，排除已经生成了序列号在批量配发中的装备，按序列号排序
        List<DeviceLibrary> deviceLibraries = packingLibraryService.getAllotDevSeqs(id).stream()
                .filter(deviceLibrary -> !existIds.contains(deviceLibrary.getId()))
                .sorted(Comparator.comparing(DeviceLibrary::getSeqNumber))
                .collect(Collectors.toList());
        if (deviceLibraries.size()<num){
            return ResponseEntity.ok(ResultUtil.success("该装备最大可配发数量为"+deviceLibraries.size()+"小于填写数量"));
        }
        else {
            //获取前num个装备
            List<DeviceLibrary> deviceLibraryList = deviceLibraries.subList(0,num);
            List<Integer> ids = deviceLibraryList.stream().map(DeviceLibrary::getId).collect(Collectors.toList());
            List<String> seqs = deviceLibraryList.stream().map(DeviceLibrary::getSeqNumber).collect(Collectors.toList());
            Map<String,Object> map = new HashMap<>();
            map.put("ids",ids);
            map.put("seqs",StringSplitUtil.stringListToString(DeviceSeqUtil.getContinuousSeqs(seqs)));
            return ResponseEntity.ok(map);
        }
    }

    @ApiOperation(value = "判断序列号区间是否存在")
    @PostMapping("/seqsExist/{id}/{num}/{seq}")
    public ResponseEntity seqsExist(@PathVariable("id") int id,@PathVariable("num") int num,@PathVariable("seq") String seq){
        List<DeviceLibrary> deviceLibraries = packingLibraryService.getAllDevSeqs(id);
        List<String> existSeqs = deviceLibraries.stream().map(DeviceLibrary::getSeqNumber).collect(Collectors.toList());
        List<String> inputSeqs = DeviceSeqUtil.selectDeviceSeqs(seq);
        List<String> hasApplySeqs = deviceLibraries.stream()
                .filter(deviceLibrary -> deviceLibrary.getApplyTaskId()!=null)
                .map(DeviceLibrary::getSeqNumber)
                .collect(Collectors.toList());
        if (inputSeqs.size()!=num){
            return ResponseEntity.ok("序列号区间总数为"+inputSeqs.size()+",与装备数量不匹配");
        }
        else {
            Set<String> seqSet = new HashSet<>(inputSeqs);
            if (seqSet.size()!=inputSeqs.size()){
                List<String> strings = new ArrayList<>();
                Set<String> sameSeqs = new HashSet<>();
                for (String s : inputSeqs){
                    if (strings.contains(s)){
                        sameSeqs.add(s);
                    }
                    strings.add(s);
                }
                return ResponseEntity.ok("序列号"+ StringSplitUtil.stringListToString(new ArrayList<>(sameSeqs))+"重复");
            }
            else {
                if (existSeqs.containsAll(inputSeqs)) {
                    hasApplySeqs.retainAll(inputSeqs);
                    if (hasApplySeqs.size() == 0) {
                        return ResponseEntity.ok("ok");
                    } else {
                        StringBuffer stringBuffer = new StringBuffer();
                        hasApplySeqs.forEach(s -> stringBuffer.append(s).append(","));
                        stringBuffer.deleteCharAt(stringBuffer.length() - 1);
                        return ResponseEntity.ok("该型号序列号为" + stringBuffer.toString() + "的装备已经发过申请");
                    }
                } else {
                    existSeqs.retainAll(inputSeqs);
                    inputSeqs.removeAll(existSeqs);
                    StringBuffer stringBuffer = new StringBuffer();
                    inputSeqs.forEach(s -> stringBuffer.append(s).append(","));
                    stringBuffer.deleteCharAt(stringBuffer.length() - 1);
                    return ResponseEntity.ok("该型号序列号为" + stringBuffer.toString() + "的装备不存在");
                }
            }
        }
    }

    @ApiOperation(value = "判断序列号区间不存在")
    @PostMapping("/seqsNotExist/{id}/{num}/{seq}")
    public ResponseEntity seqsNotExist(@PathVariable("id") int id,@PathVariable("num") int num,@PathVariable("seq") String seq){
        List<DeviceLibrary> deviceLibraries = deviceLibraryDao.findAll();
        List<String> existSeqs = deviceLibraries.stream().map(DeviceLibrary::getSeqNumber).collect(Collectors.toList());
        List<String> inputSeqs = DeviceSeqUtil.selectDeviceSeqs(seq);
        if (inputSeqs.size()>0&&inputSeqs.size()!=num){
            return ResponseEntity.ok("序列号区间总数为"+inputSeqs.size()+",与装备数量不匹配");
        }
        else {
            if (inputSeqs.isEmpty()||Collections.disjoint(existSeqs,inputSeqs)){
                return ResponseEntity.ok("ok");
            }
            else {
                existSeqs.retainAll(inputSeqs);
                StringBuffer stringBuffer = new StringBuffer();
                existSeqs.forEach(s -> stringBuffer.append(s).append(","));
                stringBuffer.deleteCharAt(stringBuffer.length()-1);
                return ResponseEntity.ok("该型号序列号为"+stringBuffer.toString()+"的装备已存在");
            }
        }
    }

    @ApiOperation(value = "编辑列装型号")
    @PostMapping("/update/model")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity updateModel(@RequestBody PackingModelEdit packingModelEdit){
        Integer userId = userUtils.getCurrentUserId();
        PackingLibrary packingLibrary = packingLibraryService.getOne(packingModelEdit.getPackingId());
        if (!packingLibrary.getModel().equals(packingModelEdit.getModel()) && packingLibraryService.modelIsExist(packingModelEdit.getModel())) {
            Map<String, Object> map = new HashMap<>();
            map.put("error", "型号" + packingModelEdit.getModel() + "已存在");
            return ResponseEntity.ok(map);
        }

        packingLibrary.setShowOrder(packingModelEdit.getShowOrder());
        if (packingLibrary.getIsRoot() == 1) {
            if (packingModelEdit.getModel() != null && !packingModelEdit.getModel().equals(packingLibrary.getModel())) {
                //判断该列装下有没有入库装备  有装备则进行装备的型号的修改
                    //更新装备
                    long l2 = System.currentTimeMillis();
                    List<DeviceLibrary> storagePackingDevices = deviceLibraryService.findAllByModel(packingLibrary.getModel());
                    if (storagePackingDevices.size()>0){
                        deviceLibraryService.batchUpdateDevices(packingLibrary.getModel(),packingModelEdit.getModel());
                        //添加装备日志
                        String remark = "将原型号"+packingLibrary.getModel()+"修改型号为"+packingModelEdit.getModel();
                        List<Integer> deviceIds = storagePackingDevices.stream().map(DeviceLibrary::getId).collect(Collectors.toList());
                        List<DeviceLog> logDtos=new ArrayList<>();
                        deviceIds.forEach(integer -> {
                            logDtos.add(new DeviceLogDto(integer,remark,null,userId,null).toDo());
                        });
                        executor.execute(()->{
                            long start  = System.currentTimeMillis();
                            deviceLogService.saveAllLog(logDtos);
                            log.info("saveAllLog时间：{}", System.currentTimeMillis() - start);
                        });
                        List<RepairDetail> allByModel = repairDetailDao.findAllByModel(packingLibrary.getModel());
                        List<Integer> ids = allByModel.stream().map(RepairDetail::getDeviceId).collect(Collectors.toList());
                        if (ids.size()>0){
                            repairDetailDao.updateModel(packingModelEdit.getModel(),ids);
                        }
                    }
                    log.info("batchUpdateDevices时间：{}", System.currentTimeMillis() - l2);
//                }
                packingLibrary.setModel(packingModelEdit.getModel());
                packingLibrary.setName(packingModelEdit.getModel());
                packingLibraryService.changeAllModel(packingLibrary.getId(), packingModelEdit.getModel());
                //添加列装日志
                PackingLog packingLog = new PackingLog();
                packingLog.setRemark("将原型号"+packingLibrary.getModel()+"修改型号为"+packingModelEdit.getModel());
                packingLog.setPackingId(packingLibrary.getId());
                packingLogService.add(packingLog);
            }
            BeanUtils.copyProperties(packingModelEdit, packingLibrary);
            packingLibraryService.update(packingLibrary);
            //发送阅知信息
            List<Integer> userIds = userPublicService.findOtherUser(userUtils.getCurrentUserId());
            MessageBto messageBto = new MessageBto(0, 1, "修改列装型号目录", userIds, 0);
            messageService.add(messageBto);
        } else {
            throw new ApiException("传入的列装id不是型号");
        }
        //更新缓存
        packingLibraryService.getSortMap();
        if (packingModelEdit.getShowOrder() != null){
            //重新排序
            List<PackingLibrary> allPackingExceptNull = getAllPackingExceptNull(new SelectPack());
            AtomicInteger sortNum = new AtomicInteger();
            List<PackingLibrary> orderNumbers = setOrderNumber(sortNum, allPackingExceptNull);
            orderNumbers.forEach(packingLibrary1 -> {
                if (packingLibrary1.getId().equals(packingModelEdit.getPackingId())){
                    packingModelEdit.setSeqOrderNumber(packingLibrary1.getSeqOrderNumber());
                }
            });
        }
        return ResponseEntity.ok(ResponseEntity.ok(packingModelEdit));
    }
//    @ApiOperation(value = "编辑列装型号")
//    @PostMapping("/update/model")
//    @Transactional(rollbackFor = Exception.class)
//    public ResponseEntity updateModel(@RequestBody PackingModelEdit packingModelEdit){
//        PackingLibrary packingLibrary = packingLibraryService.getOne(packingModelEdit.getPackingId());
//        if (!packingLibrary.getModel().equals(packingModelEdit.getModel())&&packingLibraryService.modelIsExist(packingModelEdit.getModel())){
//            Map<String,Object> map = new HashMap<>();
//            map.put("error","型号"+packingModelEdit.getModel()+"已存在");
//            return ResponseEntity.ok(map);
//        }
//        //判断该列装下有没有入库装备  有装备则进行装备的型号的修改
//        //通过型号查询装备
//        if (!packingLibrary.getModel().equals(packingModelEdit.getModel())){
//            long l = System.currentTimeMillis();
//            List<DeviceLibrary> storagePackingDevices = deviceLibraryService.findAllByModel(packingLibrary.getModel());
//            log.info("findAllByModel时间：{}",System.currentTimeMillis()-l);
//            if(storagePackingDevices.size()>0){
//                //取出所有的装备id
//                List<Integer> ids = storagePackingDevices.stream().map(DeviceLibrary::getId).collect(Collectors.toList());
//                //更新装备
//                long l2 = System.currentTimeMillis();
//                executor.execute(()->{
//                    deviceLibraryService.batchUpdateDevices(packingModelEdit.getModel(),ids);
//                });
//                log.info("batchUpdateDevices时间：{}",System.currentTimeMillis()-l2);
//            }
//        }
//        //如果排序字段为空
//        if (packingModelEdit.getShowOrder() == null){
//            packingLibrary.setShowOrder(packingModelEdit.getShowOrder());
//            packingLibraryService.update(packingLibrary);
//        }else {
//
////        else {
//            List<PackingLibrary> packingLibraries = new ArrayList<>();
//            if (packingLibrary.getShowOrder() == null){
//                int maxShowOrder = packingLibraryDao.maxShowOrder();
//                List<Integer> showOrders = packingLibraryDao.selectShowOrders(packingModelEdit.getShowOrder(), maxShowOrder);
//                //先判断是否在数据库中
//                List<Integer> allShowOrders = packingLibraryDao.selectAllShowOrders();
//                if(!allShowOrders.contains(packingModelEdit.getShowOrder())){
//                    //直接更新
//                    packingLibrary.setShowOrder(packingModelEdit.getShowOrder());
//                }else {
//
//                    //排序全部都加1
//                    packingLibraries = packingLibraryDao.findByShowOrderIn(showOrders);
//                    packingLibraryDao.updateShowOrders(packingLibraries);
//                    //将传入的进行更新
//                    packingLibrary.setShowOrder(packingModelEdit.getShowOrder());
//                    //所有的
////                for (int i = packingModelEdit.getShowOrder(); i < maxShowOrder; i++) {
////                    String model=" ";
////                    if (packingLibraryDao.findByShowOrderAndModelNot(i,model)!=null){
////                        PackingLibrary packingLibrary1 = packingLibraryDao.findByShowOrderAndModelNot(i,model);
////                        packingLibrary1.setShowOrder(i+1);
////                        packingLibraries.add(packingLibrary1);
////                        model=packingLibrary1.getModel();
////                    }
////                    else {
////                        break;
////                    }
////                }
//                }
//
//            }else if (packingLibrary.getShowOrder()>=packingModelEdit.getShowOrder()){
//                String model=" ";
//                for (int i = packingModelEdit.getShowOrder();i<packingLibrary.getShowOrder();i++){
//                    if (packingLibraryDao.findByShowOrderAndModelNot(i,model)!=null){
//                        PackingLibrary packingLibrary1 = packingLibraryDao.findByShowOrderAndModelNot(i,model);
//                        packingLibrary1.setShowOrder(i+1);
////                      packingLibrary1.setShowOrder(packingModelEdit.getShowOrder());
//                        packingLibraries.add(packingLibrary1);
//                        model=packingLibrary1.getModel();
//                    }
//                    else {
//                        break;
//                    }
//                }
//            }
//            else if(packingLibrary.getShowOrder()<packingModelEdit.getShowOrder()){
//                for (int i = packingLibrary.getShowOrder()+1;i<=packingModelEdit.getShowOrder();i++){
//                    if (packingLibraryDao.findByShowOrder(i)!=null){
//                        PackingLibrary packingLibrary1 = packingLibraryDao.findByShowOrder(i);
//                        packingLibrary1.setShowOrder(i-1);
//                        packingLibraries.add(packingLibrary1);
//                    }
//                    else {
//                        break;
//                    }
//                }
//            }
//            else{
//                packingLibrary.setShowOrder(packingLibrary.getShowOrder());
//            }
//            if (packingLibraries.size()>0) {
//                packingLibraryDao.saveAll(packingLibraries);
//            }
//            if (packingLibrary.getIsRoot()==1){
//                if (packingModelEdit.getModel()!=null&&!packingModelEdit.getModel().equals(packingLibrary.getModel())){
//                    packingLibrary.setModel(packingModelEdit.getModel());
//                    packingLibrary.setName(packingModelEdit.getModel());
//                    packingLibraryService.changeAllModel(packingLibrary.getId(),packingModelEdit.getModel());
//                }
//                BeanUtils.copyProperties(packingModelEdit,packingLibrary);
//                packingLibraryService.update(packingLibrary);
//                //发送阅知信息
//                List<Integer> userIds = userPublicService.findOtherUser(userUtils.getCurrentUserId());
//                MessageBto messageBto = new MessageBto(0,1,"修改列装型号目录",userIds,0);
//                messageService.add(messageBto);
//            }
//            else {
//                throw new ApiException("传入的列装id不是型号");
//            }
//        }
//
////        }
//        //更新缓存
//        packingLibraryService.getSortMap();
//        return ResponseEntity.ok(ResponseEntity.ok(packingModelEdit));
//    }

    @ApiOperation(value = "编辑列装装备")
    @PostMapping("/update/device")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity updateDevice(@RequestBody @Validated PackingLibraryUpdateVo packingLibraryUpdateVo){
        PackingLibrary packingLibrary = packingLibraryService.getOne(packingLibraryUpdateVo.getPackingId());
        if (!packingLibraryUpdateVo.getMatchingRange().equals(packingLibrary.getMatchingRange())&&packingLibraryService.matchingRangeIsExist(packingLibrary.getPartParentId(),packingLibraryUpdateVo.getMatchingRange(),packingLibraryUpdateVo.getType(),packingLibraryUpdateVo.getStyle(),packingLibraryUpdateVo.getName(),packingLibraryUpdateVo.getSecretLevel(),packingLibraryUpdateVo.getInvisibleRange())){
            throw new ApiException("该型号下已存在配用范围为"+configCache.getMatchingRangeMap().get(packingLibraryUpdateVo.getMatchingRange())+"的相同装备");
        }
        //复制相同的字段
        if (packingLibraryUpdateVo.getName()!=null&&!packingLibraryUpdateVo.getName().equals(packingLibrary.getName())){
            if (packingLibraryService.nameIsExist1(packingLibrary.getModel(),packingLibraryUpdateVo.getName(),packingLibrary.getPartParentId(),packingLibrary.getMatchingRange())){
                throw new ApiException("该型号下已存在配用范围为"+configCache.getMatchingRangeMap().get(packingLibraryUpdateVo.getMatchingRange())+"的相同名称装备");
            }
            //添加列装日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark("将名称从"+packingLibrary.getName()+"改为"+packingLibraryUpdateVo.getName());
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setName(packingLibraryUpdateVo.getName());
            deviceLibraryDao.upDateName(packingLibrary.getName(),packingLibrary.getId());
        }
        if (packingLibraryUpdateVo.getApplyType()!=null&&!packingLibraryUpdateVo.getApplyType().equals(packingLibrary.getApplyType())){
            //添加列装应用类型日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark("将应用类型从"+configCache.getApplyTypeMap().getOrDefault(packingLibrary.getApplyType(),"空")+"改为"+configCache.getApplyTypeMap().get(packingLibraryUpdateVo.getApplyType()));
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setApplyType(packingLibraryUpdateVo.getApplyType());
        }
        if (packingLibraryUpdateVo.getSecretLevel()!=null&&!packingLibraryUpdateVo.getSecretLevel().equals(packingLibrary.getSecretLevel())){
            //添加列装密级日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark("将密级从"+configCache.getSecretLevelMap().getOrDefault(packingLibrary.getSecretLevel(),"空")+"改为"+configCache.getSecretLevelMap().get(packingLibraryUpdateVo.getSecretLevel()));
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setSecretLevel(packingLibraryUpdateVo.getSecretLevel());
        }
        if (packingLibraryUpdateVo.getMatchingRange()!=null&&!packingLibraryUpdateVo.getMatchingRange().equals(packingLibrary.getMatchingRange())){
            //添加列装配用范围日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark("将配用范围从"+configCache.getMatchingRangeMap().getOrDefault(packingLibrary.getMatchingRange(),"空")+"改为"+configCache.getMatchingRangeMap().get(packingLibraryUpdateVo.getMatchingRange()));
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setMatchingRange(packingLibraryUpdateVo.getMatchingRange());
            deviceLibraryDao.upDateMatchingRange(packingLibrary.getMatchingRange(),packingLibrary.getId());
        }
        if (packingLibraryUpdateVo.getInvisibleRange()!=null&&!packingLibraryUpdateVo.getInvisibleRange().equals(packingLibrary.getInvisibleRange())){
            //添加列装可见范围日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark("将可见范围从"+configCache.getInvisibleRangeMap().getOrDefault(packingLibrary.getInvisibleRange(),"空")+"改为"+configCache.getInvisibleRangeMap().get(packingLibraryUpdateVo.getInvisibleRange()));
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setInvisibleRange(packingLibraryUpdateVo.getInvisibleRange());
        }
        if (packingLibraryUpdateVo.getType()!=null&&!packingLibraryUpdateVo.getType().equals(packingLibrary.getType())){
            //添加列装形态日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark("将形态从"+configCache.getStyleMap().getOrDefault(packingLibrary.getType(),"空")+"改为"+configCache.getStyleMap().get(packingLibraryUpdateVo.getType()));
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setType(packingLibraryUpdateVo.getType());
        }
        if (packingLibraryUpdateVo.getNature()!=null&&!packingLibraryUpdateVo.getNature().equals(packingLibrary.getNature())){
            //添加列装性质日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark("将列装性质从"+configCache.getNatureMap().getOrDefault(packingLibrary.getNature(),"空")+"改为"+configCache.getNatureMap().get(packingLibraryUpdateVo.getNature()));
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setNature(packingLibraryUpdateVo.getNature());
        }
        if (packingLibraryUpdateVo.getStyle()!=null&&!packingLibraryUpdateVo.getStyle().equals(packingLibrary.getStyle())){
            //添加列装日志
            PackingLog packingLog = new PackingLog();
            String s1= packingLibrary.getStyle()==1?"装备":"附件";
            String s2= packingLibraryUpdateVo.getStyle()==1?"装备":"附件";
            packingLog.setRemark("将类型从"+s1+"改为"+s2);
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setStyle(packingLibraryUpdateVo.getStyle());
        }
        if (packingLibraryUpdateVo.getProdUnit()!=null&&!packingLibraryUpdateVo.getProdUnit().equals(packingLibrary.getProdUnit())){
            //添加列装日志
            PackingLog packingLog = new PackingLog();
            String origin = packingLibrary.getProdUnit()==null?"无":packingLibrary.getProdUnit();
            packingLog.setRemark("将生产单位从"+origin+"改为"+packingLibraryUpdateVo.getProdUnit());
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setProdUnit(packingLibraryUpdateVo.getProdUnit());
        }
        if (packingLibraryUpdateVo.getPrice()!=null&&!packingLibraryUpdateVo.getPrice().equals(packingLibrary.getPrice())){
            //添加列装日志
            PackingLog packingLog = new PackingLog();
            String origin = packingLibrary.getPrice()==null?"无":packingLibrary.getPrice();
            packingLog.setRemark("将价格从"+origin+"改为"+packingLibraryUpdateVo.getPrice());
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setPrice(packingLibraryUpdateVo.getPrice());
        }
        if (packingLibraryUpdateVo.getImageUrl()!=null&&!packingLibraryUpdateVo.getImageUrl().equals(packingLibrary.getImageUrl())){
            //添加列装日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark("更新设备图片");
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setImageUrl(packingLibraryUpdateVo.getImageUrl());
            packingLibrary.setImageName(packingLibraryUpdateVo.getImageName());
        }
        if (packingLibraryUpdateVo.getFileUrl()!=null&&!packingLibraryUpdateVo.getFileUrl().equals(packingLibrary.getFileUrl())){
            //添加列装日志
            PackingLog packingLog = new PackingLog();
            if ("".equals(packingLibraryUpdateVo.getFileUrl())){
                packingLog.setRemark("删除列装文件");
            }
            else {
                packingLog.setRemark("更新列装文件");
            }
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setFileUrl(packingLibraryUpdateVo.getFileUrl());
            packingLibrary.setFileName(packingLibraryUpdateVo.getFileName());
        }
        if (packingLibraryUpdateVo.getFileList()!=null&&!FilesUtil.stringFileToList(packingLibraryUpdateVo.getFileList()).equals(packingLibrary.getFileDb())){
            //添加列装日志
            PackingLog packingLog = new PackingLog();
            packingLog.setRemark("更新列装设备文件");
            packingLog.setPackingId(packingLibrary.getId());
            packingLogService.add(packingLog);
            packingLibrary.setFileDb(FilesUtil.stringFileToList(packingLibraryUpdateVo.getFileList()));
        }

        packingLibraryService.update(packingLibrary);
        //发送阅知信息
        List<Integer> userIds = userPublicService.findOtherUser(userUtils.getCurrentUserId());
        MessageBto messageBto = new MessageBto(0,1,"修改列装装备信息",userIds,0);
        messageService.add(messageBto);
        return ResponseEntity.ok("编辑成功");
    }

    @ApiOperation(value = "获取列装名称")
    @GetMapping("/getName/{id}")
    public ResponseEntity getPackName(@PathVariable("id") int id){
        PackingLibrary packingLibrary = packingLibraryService.getOne(id);
        return ResponseEntity.ok(packingLibrary.getName());
    }

    @ApiOperation(value = "获取列装日志")
    @GetMapping("/getLogs/{id}")
    public ResponseEntity getPackingLogs(@PathVariable("id") int id){
        List<DeviceLogUserVo> deviceLogUserVos = packingLogDao.getAllByPackingId(id).stream().map(PackingLog::toVo).sorted(Comparator.comparing(DeviceLogUserVo::getCreateTime).reversed()).collect(Collectors.toList());
        return ResponseEntity.ok(deviceLogUserVos);
    }

    @ApiOperation(value = "撤销列装装备")
    @PostMapping("/concle")
    public ResponseEntity concle(@RequestBody ConcleVo concleVo){
        List<PackingLibrary> packingLibraries = concleVo.getPackingLibraries();
        packingLibraries.add(concleVo.getPackingLibrary1());
        //返回父子结构
        Map<Integer, PackingLibrary> nodeCollect =
                packingLibraries.stream().collect(Collectors.toMap(PackingLibrary::getId, packingLibrary -> packingLibrary));
        return ResponseEntity.ok(GetTreeUtils.parseTreeFromDown(
                packingLibraries,
                PackingLibrary::getId,
                packingLibrary -> Optional.ofNullable(nodeCollect.get(packingLibrary.getPartParentId())),
                PackingLibrary::addChildNode
        ));
    }


    /**
     * 设置排序
     * @param sortNum 数字
     * @param packingLibraries 列装集合
     * @return
     */
    private List<PackingLibrary> setOrderNumber(AtomicInteger sortNum,List<PackingLibrary> packingLibraries) {
        packingLibraries.forEach(
                packingLibrary -> {
                    packingLibrary.setSeqOrderNumber(sortNum.incrementAndGet());
                }
        );
        return packingLibraries;
    }

    /**
     * 获取所有列装(除去只有列装目录的)
     */
    public List<PackingLibrary> getAllPackingExceptNull(SelectPack selectPack){
        List<PackingLibrary> resultList;
        resultList = packingLibraryService.getInsertList(selectPack);
//        Map<String,Object> map = new HashMap<>();
        //进行过滤 退装的目录下面 回收站
        List<Integer> statuses = new ArrayList<>(Arrays.asList(3, 4));
        //先过滤出child为空的
        List<PackingLibrary> childs = resultList.stream().filter(packingLibrary -> packingLibrary.getChilds() == null || packingLibrary.getChilds().size() == 0).collect(Collectors.toList());
        //取出不为空的
        resultList.removeAll(childs);
        childs.forEach(packingLibrary -> {
            List<PackingLibrary> in = packingLibraryDao.findAllByPartParentIdAndPackingStatusIn(packingLibrary.getId(), statuses);
            if (in == null || in.size() == 0) {
                resultList.add(packingLibrary);
            }
        });
        resultList.sort(Comparator.comparing(PackingLibrary::getShowOrder,Comparator.nullsLast(Integer::compareTo)).thenComparing(Comparator.comparing(PackingLibrary::getModel)));
        return resultList;
    }
}
