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

import com.fasterxml.jackson.core.type.TypeReference;
import com.tykj.dev.config.cache.ConfigCache;
import com.tykj.dev.config.swagger.AutoDocument;
import com.tykj.dev.device.allot.service.AllotBackBillService;
import com.tykj.dev.device.allot.service.AllotBillService;
import com.tykj.dev.device.allot.subject.domin.AllotBackBill;
import com.tykj.dev.device.allot.subject.domin.AllotBill;
import com.tykj.dev.device.allot.subject.vo.*;
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.vo.FileVo;
import com.tykj.dev.device.library.subject.vo.ScriptSaveVo;
import com.tykj.dev.device.packing.service.PackingLibraryService;
import com.tykj.dev.device.packing.subject.domin.PackingLibrary;
import com.tykj.dev.device.task.repository.TaskDao;
import com.tykj.dev.device.task.service.TaskLogService;
import com.tykj.dev.device.task.service.TaskService;
import com.tykj.dev.device.task.subject.bto.TaskBto;
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.dao.UserDao;
import com.tykj.dev.device.user.subject.entity.User;
import com.tykj.dev.device.user.subject.service.AreaService;
import com.tykj.dev.device.user.subject.service.UnitsService;
import com.tykj.dev.device.user.subject.service.UserPublicService;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.misc.base.BusinessEnum;
import com.tykj.dev.misc.base.ResultObj;
import com.tykj.dev.misc.base.StatusEnum;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.*;
import com.tykj.dev.rfid.service.InputOutputDeviceService;
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.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author dengdiyi
 */
@RestController
@RequestMapping(value = "/allot")
@AutoDocument
@Api(tags = "装备配发模块", description = "装备配发接口")
@Slf4j
public class AllotBillController {

    @Autowired
    private AllotBillService allotBillService;

    @Autowired
    private UserUtils userUtils;

    @Autowired
    private TaskService taskService;

    @Autowired
    private DeviceLibraryService deviceLibraryService;

    @Autowired
    private DeviceLogService deviceLogService;

    @Autowired
    private TaskLogService taskLogService;

    @Autowired
    private UserPublicService userPublicService;

    @Autowired
    private MyWebSocket myWebSocket;

    @Autowired
    private Snowflake snowflake;

    @Autowired
    private InputOutputDeviceService inputOutputDeviceService;

    @Autowired
    private MessageService messageService;

    @Autowired
    private UserDao userDao;

    @Autowired
    private AllotBackBillService allotBackBillService;

    @Autowired
    private DeviceLibraryDao deviceLibraryDao;

    @Autowired
    private UnitsService unitsService;

    @Autowired
    private AreaService areaService;

    @Autowired
    private UserPublicService userService;

    @Autowired
    private ConfigCache configCache;

    @Autowired
    private TaskDao taskDao;

    @Autowired
    private PackingLibraryService packingLibraryService;

    @ApiOperation(value = "导入二维码获取配发装备", notes = "可以通过这个接口导入二维码获取配发装备")
    @PostMapping(value = "/load")
    public ResponseEntity loadDevice(@RequestBody RfidVo rfidVo) {
        String unit = userUtils.getCurrentUserUnitName();
        List<DeviceLibrary> deviceLibraries = new ArrayList<>();
        rfidVo.getRfidResultList().forEach(s -> {
            List<DeviceLibrary> deviceLibraries1 = deviceLibraryDao.getAllByRfidCardId(s);
            if (deviceLibraries1.isEmpty()){
                throw new ApiException("系统中不存在rfid为"+s+"的装备");
            }
            else {
                if (!deviceLibraries1.get(0).getOwnUnit().equals(unit)){
                    throw new ApiException("rfid为"+s+"的装备不属于本单位");
                }
                else if (deviceLibraries1.get(0).getLifeStatus()!=2){
                    throw new ApiException("rfid为"+s+"的装备不在库");
                }
                else {
                    deviceLibraries.add(deviceLibraries1.get(0));
                }
            }
        });
        return ResponseEntity.ok(deviceLibraries);
    }

    @ApiOperation(value = "发起配发业务", notes = "可以通过这个接口发起配发任务")
    @PostMapping(value = "/addAllotBill")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity addAllotBill(@RequestBody @Validated AllotBillSaveVo allotBillSaveVo) {
        if (allotBillSaveVo.getAllotCheckDetail()!=null&&allotBillSaveVo.getAllotCheckDetail().length()>0) {
            deviceLibraryService.isInStockOrWaitRetired(StringSplitUtil.split(allotBillSaveVo.getAllotCheckDetail()));
        }
        //1.添加配发单
        AllotBill a = allotBillSaveVo.toDo();
        if (allotBillSaveVo.getTaskId()==null) {
            a.setSendUseraId(userUtils.getCurrentUserId());
        }
        AllotBill allotBillEntity;
        if (allotBillSaveVo.getTaskId()==null){
            allotBillEntity = allotBillService.addEntity(a);
        }
        else {
            AllotBill allotBill = allotBillService.getOne(taskService.get(allotBillSaveVo.getTaskId()).getBillId());
            MapperUtils.copyNoNullProperties(a,allotBill);
            allotBillEntity = allotBillService.update(allotBill);
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int year = calendar.get(Calendar.YEAR);
        String num = "NO:第" + year + "PF" + allotBillEntity.getId() + "号";
        allotBillEntity.setNum(num);
        //生成电子签章id
//        Long signId = snowflake.creatNextId();
        Long signId2 = snowflake.creatNextId();
        if (allotBillSaveVo.getLeftSignatureId()!=null) {
            allotBillEntity.setLeftSignatureId(allotBillSaveVo.getLeftSignatureId());
        }
        allotBillEntity.setRightSignatureId(signId2.toString());
        AllotBill allotBill = allotBillService.update(allotBillEntity);
        Integer billId = allotBillEntity.getId();
        Integer userId = userUtils.getCurrentUserId();
        String deviceIdDetail = allotBillEntity.getAllotCheckDetail();
        //2.发起任务
        List<Integer> userIds = new ArrayList<>();
        userIds.add(userId);
        userIds.add(0);
        TaskBto saveEntity;
        //纵向
        if (allotBillSaveVo.getAllotType()==1) {
            if (allotBillSaveVo.getTaskId() == null) {
                TaskBto taskBto = new TaskBto(StatusEnum.ALLOTING.id, "配发业务", null, ".", billId, 3, userPublicService.findUnitIdByName(allotBillSaveVo.getReceiveUnit()), 1, null, userIds);
                saveEntity = taskService.start(taskBto);
            } else {
                TaskBto taskBto = taskService.get(allotBillSaveVo.getTaskId());
                TaskBto taskBto1 = taskService.addInvolveUser(taskBto,userId);
                taskBto1.setOwnUnit(userPublicService.findUnitIdByName(allotBillSaveVo.getReceiveUnit()));
                saveEntity = taskService.moveToSpecial(taskBto1, StatusEnum.ALLOTING, 0);
            }
//            if (allotBillSaveVo.getIsSigned()==null||allotBillSaveVo.getIsSigned()!=1) {
            TaskBto taskBto2 = new TaskBto(StatusEnum.WAIT_UPLOAD_ALLOT_FILE.id, "配发业务", saveEntity.getId(), saveEntity.getNodeIdDetail() + saveEntity.getId() + ".", saveEntity.getBillId(), 3, userPublicService.findUnitIdByName(allotBillEntity.getSendUnit()), 0, null, Collections.singletonList(0));
            taskService.start(taskBto2);
//            }
        }
        else {
            TaskBto taskBto2 = new TaskBto(StatusEnum.WAIT_UPLOAD_CROSS_FILE.id, "配发业务", null, ".", billId, 3, userPublicService.findUnitIdByName(allotBillEntity.getSendUnit()), 1, "country", userIds);
            saveEntity = taskService.start(taskBto2);
        }
        List<FileVo> fileVoList = new ArrayList<>();
//        fileVoList.add(new FileVo("出库确认单", allotBillEntity.getFileName(), allotBillEntity.getFileUrl()));
        //存装备日志
        String[] strings = deviceIdDetail.split("x");
        List<Integer> ids = new ArrayList<>();
        //横纵向列装转换map
        Map<Integer,Integer> changeMap = new HashMap<>();
        for (String s : strings) {
            if (s.length() >= 2) {
                Integer id = Integer.parseInt(s.substring(0, s.length() - 1));
                ids.add(id);
                //改变装备状态
                DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id);
                if (allotBillSaveVo.getAllotType() == 1){
                    if (deviceLibraryEntity.getMatchingRange()!=1){
                        PackingLibrary packingLibrary = packingLibraryService.getOne(deviceLibraryEntity.getPackingId());
                        PackingLibrary packingLibrary1 = packingLibraryService.findSamePacking(packingLibrary.getPartParentId(),1);
                        if (packingLibrary1==null){
                            Map<String,Object> map = new HashMap<>();
                            map.put("error","序列号为"+deviceLibraryEntity.getSeqNumber()+"的装备所属列装不存在配用范围为省对下纵向的列装装备");
                            return ResponseEntity.ok(map);
                        }
                        else {
                            deviceLibraryEntity.setPackingId(packingLibrary1.getId());
                            deviceLibraryEntity.setMatchingRange(1);
                        }
//                        deviceLibraryEntity.setAllotType(2);
                        DeviceLogDto deviceLogDto = new DeviceLogDto(id, "纵向配发将配发类型由" + deviceLibraryEntity.getMatchingRangeName() + "改为"+configCache.getMatchingRangeMap().get(1), fileVoList);
                        deviceLogService.addLog(deviceLogDto);
                    }
                    deviceLibraryEntity.setLifeStatus(3);
                    deviceLibraryEntity.setManageStatus(0);
                }
                else {
                    if (deviceLibraryEntity.getMatchingRange()!=3){
                        if (changeMap.get(deviceLibraryEntity.getPackingId())!=null){
                            deviceLibraryEntity.setPackingId(changeMap.get(deviceLibraryEntity.getPackingId()));
                            deviceLibraryEntity.setMatchingRange(3);
                        }
                        else {
                            PackingLibrary packingLibrary = packingLibraryService.getOne(deviceLibraryEntity.getPackingId());
                            PackingLibrary packingLibrary1 = packingLibraryService.findSamePacking(packingLibrary.getPartParentId(), 3);
                            if (packingLibrary1 == null) {
                                Map<String, Object> map = new HashMap<>();
                                map.put("error", "序列号为" + deviceLibraryEntity.getSeqNumber() + "的装备所属列装不存在配用范围为省对下横向的列装装备");
                                return ResponseEntity.ok(map);
                            }
                            else {
                                changeMap.put(deviceLibraryEntity.getPackingId(),packingLibrary1.getId());
                                changeMap.put(packingLibrary1.getId(),deviceLibraryEntity.getPackingId());
                                deviceLibraryEntity.setPackingId(packingLibrary1.getId());
                                deviceLibraryEntity.setMatchingRange(3);
                            }
                        }
//                        deviceLibraryEntity.setAllotType(1);
                        DeviceLogDto deviceLogDto = new DeviceLogDto(id, "横向配发将配发类型由" + deviceLibraryEntity.getMatchingRangeName() + "改为"+configCache.getMatchingRangeMap().get(3), fileVoList);
                        deviceLogService.addLog(deviceLogDto);
                    }
                    deviceLibraryEntity.setLocationUnit(allotBillSaveVo.getReceiveUnit());
                    deviceLibraryEntity.setOwnUnit(allotBillSaveVo.getReceiveUnit());
                }
                deviceLibraryService.update(deviceLibraryEntity);
                DeviceLogDto deviceLogDto = new DeviceLogDto(id, "对" + allotBillEntity.getReceiveUnit() + "发起配发", fileVoList);
                deviceLogService.addLog(deviceLogDto);
            }
        }
        //添加出库白名单
        inputOutputDeviceService.addWhiteDevices(ids, userUtils.getCurrentUnitId(), 1);
        //发送阅知信息
        List<Integer> idList = userPublicService.findOtherUser(userId);
        if (allotBillSaveVo.getAllotType()==1) {
            idList.addAll(userDao.findAllByUnitsId(userPublicService.findUnitIdByName(allotBillEntity.getReceiveUnit())).stream()
                    .map(User::getUserId)
                    .collect(Collectors.toList()));
        }
        if (allotBillSaveVo.getSendUserbId()!=null) {
            List<Integer> idList1 = new ArrayList<>();
            idList1.add(allotBillSaveVo.getSendUserbId());
            MessageBto messageBto = new MessageBto(saveEntity.getId(), saveEntity.getBusinessType(), "被选为签发人", idList1, 1);
            messageService.add(messageBto);
        }
        MessageBto messageBto = new MessageBto(saveEntity.getId(),saveEntity.getBusinessType(),"对" + userPublicService.getAreaNameByUnitName(allotBillEntity.getReceiveUnit()) + "发起配发",idList,1);
        messageService.add(messageBto);
        log.info("[配发模块]:" + allotBillEntity.getSendUnit() + "对" + allotBillEntity.getReceiveUnit() + "发起配发");
        myWebSocket.sendMessage1();
        allotBill.setSenderUserA(userService.getOne(allotBill.getSendUseraId()).getName());
        allotBill.setSenderUserB(allotBill.getAgent());
        if (allotBill.getReceiveUseraId() != null) {
            allotBill.setReceiveUserA(userService.getOne(allotBill.getReceiveUseraId()).getName());
        }
        if (allotBill.getReceiveUserbId() != null) {
            allotBill.setReceiveUserB(userService.getOne(allotBill.getReceiveUserbId()).getName());
        }
        allotBill.setSendFileList(FilesUtil.stringFileToList(allotBill.getSendFiles()));
        allotBill.setReplyFileList(FilesUtil.stringFileToList(allotBill.getReplyFiles()));
        return ResponseEntity.ok(new ResultObj(allotBill, "发起成功"));
    }

    @ApiOperation(value = "配发审核", notes = "可以通过这个接口对配发审核")
    @PostMapping(value = "/allotConfirm")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity allotConfirm(@RequestBody @Validated AllotBillConfirmVo allotBillConfirmVo) {
        TaskBto taskBto = taskService.get(allotBillConfirmVo.getTaskId());
        //1.审核通过，改变装备状态，审核任务完成，发起新的配发接收任务
        if (allotBillConfirmVo.getStatus() == 0) {
            //更新账单状态
            AllotBill allotBillEntity = allotBillService.getOne(taskBto.getBillId());
            allotBillEntity.setAllotStatus(2);
            allotBillEntity.setSendTime(TimestampUtil.getCurrentTimestamp());
            allotBillService.update(allotBillEntity);
            //task推至下一阶段
            TaskBto taskBto1 = taskService.moveToNext(taskBto, allotBillEntity.getReceiveUseraId());
            taskBto1.setOwnUnit(userPublicService.findUnitIdByName(allotBillEntity.getReceiveUnit()));
            taskService.update(taskBto1);
            //获取装备信息
            String deviceIdDetail = allotBillEntity.getAllotCheckDetail();
            String[] strings = deviceIdDetail.split("x");
            List<Integer> ids = new ArrayList<>();
            for (String s : strings) {
                if (s.length() >= 2) {
                    Integer id = Integer.parseInt(s.substring(0, s.length() - 1));
                    ids.add(id);
                    //改变装备状态
                    DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id);
                    deviceLibraryEntity.setLifeStatus(3);
                    deviceLibraryEntity.setManageStatus(0);
                    //存装备日志
                    DeviceLogDto deviceLogDto = new DeviceLogDto(id, "审核成功并出库", null);
                    deviceLogService.addLog(deviceLogDto);
                    deviceLibraryService.update(deviceLibraryEntity);
                }
            }
            //添加出库白名单
            inputOutputDeviceService.addWhiteDevices(ids, userUtils.getCurrentUnitId(), 1);
            log.info("[配发模块]:配发审核成功并出库");
            myWebSocket.sendMessage1();
            return ResponseEntity.ok("审核成功");
        }
        //2.审核失败
        if (allotBillConfirmVo.getStatus() == 1) {
            //业务封存
            taskService.update(taskService.moveToArchive(taskBto));
            //更新账单状态
            AllotBill allotBillEntity = allotBillService.getOne(taskBto.getBillId());
            allotBillEntity.setAllotStatus(1);
            allotBillService.update(allotBillEntity);
            String deviceIdDetail = allotBillEntity.getAllotCheckDetail();
            String[] strings = deviceIdDetail.split("x");
            //添加装备日志
            for (String s : strings) {
                if (s.length() >= 2) {
                    Integer id = Integer.parseInt(s.substring(0, s.length() - 1));
                    DeviceLogDto deviceLogDto = new DeviceLogDto(id, "配发出库审核失败", null);
                    deviceLogService.addLog(deviceLogDto);
                }
            }
            log.info("[配发模块]:配发出库审核失败");
            myWebSocket.sendMessage1();
            return ResponseEntity.ok("配发审核失败");
        } else {
            return ResponseEntity.ok("status只能为0或1");
        }
    }

    @ApiOperation(value = "接收配发装备", notes = "可以通过这个接口接收配发装备")
    @PostMapping(value = "/receiveDevice")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity receiveDevice(@RequestBody @Validated AllotReceiveVo allotReceiveVo) {
        Integer userId = userUtils.getCurrentUserId();
        //获取当前任务
        TaskBto taskBto = taskService.get(allotReceiveVo.getTaskId());
        List<StatusEnum> statusEnums = Arrays.asList(StatusEnum.ALLOTING,StatusEnum.WAIT_SIGN);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(),statusEnums);
        AllotBill allotBillEntity = allotBillService.getOne(taskBto.getBillId());
        boolean sendbIsExist = allotBillEntity.getSendUserbId()!=null;
        List<FileVo> fileVoList = new ArrayList<>();
//        if (allotReceiveVo.getBillFileName()!=null&&allotReceiveVo.getBillFileUrl()!=null) {
//            fileVoList.add(new FileVo("配发单", allotReceiveVo.getBillFileName(), allotReceiveVo.getBillFileUrl()));
//        }
        if (allotReceiveVo.getReceiveFiles()!=null&&allotReceiveVo.getReceiveFiles().size()>0){
            allotReceiveVo.getReceiveFiles().forEach(fileRet -> {
                fileVoList.add(new FileVo("配发单", fileRet.getName(), fileRet.getPreviewPath()));
            });
            allotBillEntity.setReceiveFiles(FilesUtil.stringFileToList(allotReceiveVo.getReceiveFiles()));
        }
//        fileVoList.add(new FileVo("入库确认单", allotReceiveVo.getReceiveFileName(), allotReceiveVo.getReceiveFileUrl()));
        //更新账单状态
        allotBillEntity.setAllotStatus(5);
        BeanUtils.copyProperties(allotReceiveVo, allotBillEntity);
        allotBillEntity.setReceiveTime(TimestampUtil.getCurrentTimestamp());
        allotBillEntity.setReceiveUseraId(userId);
        if (allotReceiveVo.getSendUserbId()!=null){
            allotBillEntity.setSendUserbId(allotReceiveVo.getSendUserbId());
            allotBillEntity.setAgent(userPublicService.getOne(allotReceiveVo.getSendUserbId()).getName());
        }
        allotBillEntity.setBillFileName(allotReceiveVo.getBillFileName());
        allotBillEntity.setBillFileUrl(allotReceiveVo.getBillFileUrl());
        allotBillService.update(allotBillEntity);
        taskService.addInvolveUser(taskBto, userId);
//        //推至下一阶段
//        taskService.update(taskService.moveToNext(taskBto, allotReceiveVo.getReceiveUserbId()));
        if (allotReceiveVo.getStatus()==0) {
            taskService.moveToEnd(taskBto);
            //子任务完结
            taskService.moveAllSonNodeToEnd(taskBto.getId());
        }
        else {
            taskService.moveToNext(taskBto);
        }
        //生成上级上传单据任务
        List<Integer> userIds = new ArrayList();
        userIds.add(0);
//        TaskBto taskBto2 = new TaskBto(StatusEnum.WAIT_UPLOAD_ALLOT_FILE.id, "配发单据", taskBto.getId(), taskBto.getNodeIdDetail()+taskBto.getId()+".", taskBto.getBillId(), 3, userPublicService.findUnitIdByName(allotBillEntity.getSendUnit()), 0, null, userIds);
//        taskService.start(taskBto);
        //分隔装备id信息
        String deviceIdDetail = allotReceiveVo.getReceiveCheckDetail();
        String[] strings = deviceIdDetail.split("x");
        for (String s : strings) {
            if (s.length() >= 2) {
                //接收无误
                if ("1".equals(s.substring(s.length() - 1))) {
                    Integer id = Integer.parseInt(s.substring(0, s.length() - 1));
                    //改变装备状态
                    DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id);
//                    deviceLibraryEntity.setLifeStatus(0);
                    deviceLibraryEntity.setLocationUnit(userUtils.getCurrentUserUnitName());
                    deviceLibraryEntity.setLifeStatus(2);
                    deviceLibraryEntity.setOwnUnit(userUtils.getCurrentUserUnitName());
                    deviceLibraryEntity.setManageStatus(1);
                    //生产号
                    if(allotReceiveVo.getMap().get(id)!=null){
                        deviceLibraryEntity.setProdNumber(allotReceiveVo.getMap().get(id));
                    }
                    //存装备日志
                    DeviceLogDto deviceLogDto = new DeviceLogDto(id, "接收并发起入库", fileVoList);
                    deviceLogService.addLog(deviceLogDto);
                    deviceLibraryService.update(deviceLibraryEntity);
                }
                //接收缺失
                if ("0".equals(s.substring(s.length() - 1))) {
                    Integer id = Integer.parseInt(s.substring(0, s.length() - 1));
                    //改变装备状态
                    DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id);
                    deviceLibraryEntity.setLifeStatus(11);
                    //存装备日志
                    DeviceLogDto deviceLogDto = new DeviceLogDto(id, "接收入库丢失", fileVoList);
                    deviceLogService.addLog(deviceLogDto);
                    deviceLibraryService.update(deviceLibraryEntity);
                }
            }
        }
        //发送阅知信息
        List<Integer> ids = userPublicService.findOtherUser(userId);
        ids.addAll(userDao.findAllByUnitsId(userPublicService.findUnitIdByName(allotBillEntity.getSendUnit())).stream()
                .map(User::getUserId)
                .collect(Collectors.toList()));
        if (allotReceiveVo.getReceiveUserbId()!=null) {
            List<Integer> idList1 = new ArrayList<>();
            idList1.add(allotReceiveVo.getReceiveUserbId());
            MessageBto messageBto = new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "被选为经办人", idList1, 1);
            messageService.add(messageBto);
        }
        if (allotReceiveVo.getSendUserbId()!=null&&sendbIsExist) {
            List<Integer> idList1 = new ArrayList<>();
            idList1.add(allotReceiveVo.getSendUserbId());
            MessageBto messageBto = new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "被选为签发人", idList1, 1);
            messageService.add(messageBto);
        }
        String message = allotReceiveVo.getStatus()==0?"业务办结":"接收配发装备";
        MessageBto messageBto = new MessageBto(taskBto.getId(),taskBto.getBusinessType(),message,ids,1);
        messageService.add(messageBto);
        log.info("[配发模块]:接收并发起入库");
        myWebSocket.sendMessage1();
        return ResponseEntity.ok("配发接收入库");
    }

    @ApiOperation(value = "接收配发装备审核", notes = "可以通过这个接口对接收配发装备审核")
    @PostMapping(value = "/receiveConfirm")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity receiveConfirm(@RequestBody @Validated AllotReceiveConfirmVo allotReceiveConfirmVo) {
        //获取任务和账单
        TaskBto taskBto = taskService.get(allotReceiveConfirmVo.getTaskId());
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(),StatusEnum.ALLOTING);
        AllotBill allotBillEntity = allotBillService.getOne(taskBto.getBillId());
        String deviceIdDetail = allotBillEntity.getAllotCheckDetail();
        String[] strings = deviceIdDetail.split("x");
        //审核通过
//        if (allotReceiveConfirmVo.getStatus() == 0) {
//            //业务完结
//            taskService.update(taskService.moveToEnd(taskBto));
//            //更新账单
//            allotBillEntity.setAllotStatus(5);
//            allotBillService.update(allotBillEntity);
//            for (String s : strings) {
//                //改变接收无误的装备的状态
//                if (s.length() >= 2 && "1".equals(s.substring(s.length() - 1))) {
//                    Integer id = Integer.parseInt(s.substring(0, s.length() - 1));
//                    DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id);
//                    deviceLibraryEntity.setLifeStatus(2);
//                    deviceLibraryEntity.setOwnUnit(userUtils.getCurrentUserUnitName());
//                    deviceLibraryEntity.setManageStatus(1);
//                    DeviceLogDto deviceLogDto = new DeviceLogDto(id, "审核成功并入库", null);
//                    deviceLogService.addLog(deviceLogDto);
//                    deviceLibraryService.update(deviceLibraryEntity);
//                }
//            }
//            log.info("[配发模块]:审核成功并入库");
//            myWebSocket.sendMessage1();
//            return ResponseEntity.ok("审核成功");
//        }
        //拒绝接收
        if (allotReceiveConfirmVo.getStatus() == 1) {
            taskService.addInvolveUser(taskBto, userUtils.getCurrentUserId());
            //业务封存
            taskService.moveToEnd(taskBto);
            //更新账单状态
            AllotBill allotBillEntity2 = allotBillService.getOne(taskBto.getBillId());
            allotBillEntity2.setAllotStatus(4);
            allotBillService.update(allotBillEntity2);
            for (String s : strings) {
                //改变接收无误的装备的状态
                if (s.length() >= 2 && "1".equals(s.substring(s.length() - 1))) {
                    Integer id = Integer.parseInt(s.substring(0, s.length() - 1));
                    DeviceLibrary deviceLibraryEntity = deviceLibraryService.getOne(id);
                    deviceLibraryEntity.setLifeStatus(3);
                    deviceLibraryEntity.setLocationUnit(userUtils.getCurrentUserUnitName());
                    DeviceLogDto deviceLogDto = new DeviceLogDto(id, "拒绝接收配发装备", null);
                    deviceLogService.addLog(deviceLogDto);
                    deviceLibraryService.update(deviceLibraryEntity);
                }
            }
            //发送阅知信息
            List<Integer> ids = userPublicService.findOtherUser(userUtils.getCurrentUserId());
            ids.addAll(userDao.findAllByUnitsId(userPublicService.findUnitIdByName(allotBillEntity.getSendUnit())).stream()
                    .map(User::getUserId)
                    .collect(Collectors.toList()));
            MessageBto messageBto = new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"拒绝接收配发装备",ids);
            messageService.add(messageBto);
            //生成配发退回单
            AllotBackBill allotBackBill =new AllotBackBill();
            allotBackBill.setAllotBillId(taskBto.getBillId());
            allotBackBill.setSendUseraId(userUtils.getCurrentUserId());
            allotBackBill.setSendUnit(userUtils.getCurrentUserUnitName());
            allotBackBill.setReceiveUnit(allotBillEntity.getSendUnit());
            allotBackBill.setBackCheckDetail(allotBillEntity.getAllotCheckDetail());
            AllotBackBill allotBackBill1 = allotBackBillService.addEntity(allotBackBill);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(allotBackBill1.getCreateTime());
            int year = calendar.get(Calendar.YEAR);
            String num = "NO:第" + year + "TH" + allotBackBill1.getId() + "号";
            allotBackBill1.setNum(num);
            allotBackBillService.update(allotBackBill1);
            //生成配发退回子业务
            List<Integer> userIds = new ArrayList<>();
            userIds.add(userUtils.getCurrentUserId());
            userIds.add(0);
            TaskBto taskBto1 = new TaskBto(StatusEnum.ALLOT_BACKING.id, "配发退回业务", taskBto.getId(), taskBto.getNodeIdDetail() + taskBto.getId() + ".", allotBackBill1.getId(), BusinessEnum.ALLOT_BACK.id, userPublicService.findUnitIdByName(allotBillEntity.getSendUnit()), 1, null, userIds);
            TaskBto task = taskService.start(taskBto1);
            log.info("[配发模块]:配发入库审核失败");
            myWebSocket.sendMessage1();
            return ResponseEntity.ok(task);
        } else {
            return ResponseEntity.ok("status只能为0或1");
        }
    }

    @ApiOperation(value = "保存配发操作", notes = "可以通过这个接口保存配发操作")
    @PostMapping(value = "/saveAllotBill")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity saveAllotBill(@RequestBody AllotBillSaveVo allotBillSaveVo) {
        //第一次保存
        if (allotBillSaveVo.getTaskId()==null){
            Integer userId = userUtils.getCurrentUserId();
            //保存入库单
            List<Integer> userIds = new ArrayList<>();
            userIds.add(userId);
            AllotBill allotBill1 = allotBillSaveVo.toDo();
            allotBill1.setAllotStatus(0);
            allotBill1.setSendUseraId(userId);
            AllotBill allotBill = allotBillService.addEntity(allotBill1);
            //发起任务
            TaskBto taskBto = new TaskBto(StatusEnum.ALLOT_DRAFT.id, "配发业务", null, ".", allotBill.getId(), 3, userUtils.getCurrentUnitId(), 0, null, userIds);
            TaskBto taskBto1 = taskService.start(taskBto);
            //改变装备状态为待配发
//            if (allotBillSaveVo.getAllotCheckDetail()!=null){
//                Map<Integer,DeviceLibrary> map = deviceLibraryService.getAllDeviceMap();
//                StringSplitUtil.split(allotBillSaveVo.getAllotCheckDetail()).forEach(integer -> {
//                    if (map.get(integer)!=null){
//                        DeviceLibrary deviceLibrary = map.get(integer);
//                        deviceLibrary.setLifeStatus(21);
//                        deviceLibraryService.update(deviceLibrary);
//                    }
//                });
//            }
            Integer id = taskBto1.getId();
            myWebSocket.sendMessage1();
            return ResponseEntity.ok("保存成功"+id);
        }
        else {
            //更新账单
            TaskBto taskBto = taskService.get(allotBillSaveVo.getTaskId());
            AllotBill allotBill = allotBillService.getOne(taskBto.getBillId());
            AllotBill allotBill1 = allotBillSaveVo.toDo();
            allotBill1.setAllotStatus(0);
            MapperUtils.copyNoNullProperties(allotBill1,allotBill);
            allotBillService.update(allotBill);
            //改变装备状态为待配发
            return ResponseEntity.ok("更新成功"+taskBto.getId());
        }
    }

    @ApiOperation(value = "删除配发单草稿", notes = "可以通过这个接口删除配发单草稿")
    @PostMapping(value = "/deleteAllotBill/{taskId}")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity deleteAllotBill(@PathVariable("taskId") int taskId) {
        //任务封存
        TaskBto taskBto = taskService.get(taskId);
        TaskBto taskBto1 = taskService.addInvolveUser(taskBto,userUtils.getCurrentUserId());
        taskService.moveToArchive(taskBto1);
        //更改装备状态为在库
//        AllotBill allotBill = allotBillService.getOne(taskBto1.getBillId());
//        if (allotBill.getAllotCheckDetail()!=null){
//            Map<Integer,DeviceLibrary> map = deviceLibraryService.getAllDeviceMap();
//            StringSplitUtil.split(allotBill.getAllotCheckDetail()).forEach(integer -> {
//                if (map.get(integer)!=null){
//                    DeviceLibrary deviceLibrary = map.get(integer);
//                    deviceLibrary.setLifeStatus(2);
//                    deviceLibraryService.update(deviceLibrary);
//                }
//            });
//        }
        myWebSocket.sendMessage1();
        return ResponseEntity.ok("删除成功");
    }

    @ApiOperation(value = "申请电子签章", notes = "可以通过这个接口申请电子签章")
    @PostMapping(value = "/applySign/{taskId}/{userId}")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity applySign(@PathVariable("taskId") int taskId,@PathVariable("userId") int userId) {
        //推动任务
        TaskBto taskBto = taskService.get(taskId);
        taskService.moveToSpecial(taskBto,StatusEnum.SIGN_WAIT_CONFIRM,userId);
        myWebSocket.sendMessage1();
        return ResponseEntity.ok("申请成功");
    }

    @ApiOperation(value = "申请电子签章审核", notes = "可以通过这个接口申请电子签章审核")
    @PostMapping(value = "/applySignConfirm/{taskId}/{status}")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity applySignConfirm(@PathVariable("taskId") int taskId,@PathVariable("status") int status) {
        //推动任务
        TaskBto taskBto = taskService.get(taskId);
        AllotBill allotBill = allotBillService.getOne(taskBto.getBillId());
        if (status==1){
            taskService.moveToSpecial(taskBto,StatusEnum.WAIT_SIGN);
            if (allotBill.getAllotStatus()==0) {
                allotBill.setSendUserbId(userUtils.getCurrentUserId());
                allotBill.setAgent(userUtils.getCurrentName());
            }
            else {
                allotBill.setReceiveUserbId(userUtils.getCurrentUserId());
            }
            allotBillService.update(allotBill);
        }
        else {
            if (allotBill.getAllotStatus()==0) {
                taskService.moveToSpecial(taskBto, StatusEnum.ALLOT_DRAFT, taskBto.getCreateUserId());
            }
            else {
                taskService.moveToSpecial(taskBto, StatusEnum.ALLOTING, allotBill.getReceiveUseraId());
            }
        }
        myWebSocket.sendMessage1();
        return ResponseEntity.ok("申请成功");
    }

    @ApiOperation(value = "查询配发草稿详情", notes = "可以通过这个接口查询配发草稿详情")
    @PostMapping(value = "/selectAllotDetail/{taskId}")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity selectAllotDetail(@PathVariable("taskId") int taskId) {
        TaskBto taskBto = taskService.get(taskId);
        AllotBill allotBillEntity = allotBillService.getOne(taskBto.getBillId());
        if (allotBillEntity.getSendUseraId() != null) {
            allotBillEntity.setSenderUserA(userPublicService.getOne(allotBillEntity.getSendUseraId()).getName());
        }
        if (allotBillEntity.getSendUserbId() != null) {
            allotBillEntity.setSenderUserB(userPublicService.getOne(allotBillEntity.getSendUserbId()).getName());
        }
        if (allotBillEntity.getReceiveUseraId() != null) {
            allotBillEntity.setReceiveUserA(userPublicService.getOne(allotBillEntity.getReceiveUseraId()).getName());
        }
        if (allotBillEntity.getReceiveUserbId() != null) {
            allotBillEntity.setReceiveUserB(userPublicService.getOne(allotBillEntity.getReceiveUserbId()).getName());
        }
        if (allotBillEntity.getAllotCheckDetail()!=null){
            List<Integer> ids = StringSplitUtil.split(allotBillEntity.getAllotCheckDetail());
            List<DeviceLibrary> deviceLibraryList = new ArrayList<>();
            ids.forEach(integer -> deviceLibraryList.add(deviceLibraryService.getOne(integer)));
            allotBillEntity.setDeviceLibraries(deviceLibraryList);
        }
        allotBillEntity.setReplyFileList(FilesUtil.stringFileToList(allotBillEntity.getReplyFiles()));
        allotBillEntity.setApplyFileList(FilesUtil.stringFileToList(allotBillEntity.getApplyFiles()));
        if (allotBillEntity.getScriptJson()!=null){
            allotBillEntity.setScripts(JacksonUtil.readValue(allotBillEntity.getScriptJson(),new TypeReference<List<ScriptSaveVo>>() {}));
        }
        return ResponseEntity.ok(allotBillEntity);
    }

    @ApiOperation(value = "上传接收方配发单", notes = "可以通过这个接口上传送修单")
    @PostMapping(value = "/uploadAllotBill")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity uploadAllotBill(@RequestBody @Validated FileUploadVo fileUploadVo){
        TaskBto taskBto = taskService.get(fileUploadVo.getTaskId());
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(),StatusEnum.WAIT_UPLOAD_ALLOT_RECEIVE_FILE);
        Integer userId = userUtils.getCurrentUserId();
        taskService.addInvolveUser(taskBto,userId);
        taskService.moveToEnd(taskBto);
        taskService.moveAllSonNodeToEnd(taskBto.getId());
        AllotBill allotBill = allotBillService.getOne(taskBto.getBillId());
        allotBill.setBillFileName(fileUploadVo.getBillFileName());
        allotBill.setBillFileUrl(fileUploadVo.getBillFileUrl());
        if (fileUploadVo.getSendUserbId()!=null){
            allotBill.setSendUserbId(fileUploadVo.getSendUserbId());
            allotBill.setAgent(userPublicService.getOne(fileUploadVo.getSendUserbId()).getName());
        }
        if (fileUploadVo.getReceiveUserbId()!=null){
            allotBill.setReceiveUserbId(fileUploadVo.getReceiveUserbId());
            MessageBto messageBto = new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "被选为经办人", Collections.singletonList(fileUploadVo.getReceiveUserbId()), 1);
            messageService.add(messageBto);
        }
        List<FileVo> fileVoList = new ArrayList<>();
        if (fileUploadVo.getReceiveFiles()!=null&&fileUploadVo.getReceiveFiles().size()>0){
            fileUploadVo.getReceiveFiles().forEach(fileRet -> {
                fileVoList.add(new FileVo("配发单", fileRet.getName(), fileRet.getPreviewPath()));
            });
            allotBill.setReceiveFiles(FilesUtil.stringFileToList(fileUploadVo.getReceiveFiles()));
        }
//            fileVoList.add(new FileVo("配发单", allotBill.getBillFileName(), allotBill.getBillFileUrl()));
        allotBillService.update(allotBill);
        //添加装备日志
        List<Integer> deviceIds = StringSplitUtil.split(allotBill.getAllotCheckDetail());
        deviceIds.forEach(integer -> {
            //存装备日志
            DeviceLogDto deviceLogDto = new DeviceLogDto(integer, "上传配发单据", fileVoList);
            deviceLogService.addLog(deviceLogDto);
        });
        if (fileUploadVo.getSendUserbId()!=null) {
            List<Integer> idList1 = new ArrayList<>();
            idList1.add(fileUploadVo.getSendUserbId());
            MessageBto messageBto = new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "被选为签发人", idList1, 1);
            messageService.add(messageBto);
        }
        //发送阅知信息
        List<Integer> ids = userPublicService.findOtherUser(userId);
        ids.addAll(userDao.findAllByUnitsId(userPublicService.findUnitIdByName(allotBill.getSendUnit())).stream()
                .map(User::getUserId)
                .collect(Collectors.toList()));
        MessageBto messageBto = new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"业务办结",ids,1);
        messageService.add(messageBto);
        return ResponseEntity.ok("上传成功");
    }

    @ApiOperation(value = "上传发送方配发单", notes = "上传配发单")
    @PostMapping(value = "/uploadFile")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity uploadFile(@RequestBody @Validated com.tykj.dev.device.allot.subject.vo.FileVo fileVo){
        //获取task
        TaskBto taskBto = taskService.get(fileVo.getTaskId());
        taskService.addInvolveUser(taskBto,userUtils.getCurrentUserId());
        List<StatusEnum> statusEnums = new ArrayList<>();
        statusEnums.add(StatusEnum.WAIT_UPLOAD_CROSS_FILE);
        statusEnums.add(StatusEnum.WAIT_UPLOAD_ALLOT_FILE);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(),statusEnums);
        AllotBill allotBill = allotBillService.getOne(taskBto.getBillId());
        List<Integer> idList = new ArrayList<>();
        if (fileVo.getReceiveUseraId()!=null) {
            allotBill.setReceiveUseraId(fileVo.getReceiveUseraId());
            idList.add(fileVo.getReceiveUseraId());
        }
        if (fileVo.getReceiveUserbId()!=null) {
            allotBill.setReceiveUserbId(fileVo.getReceiveUserbId());
            idList.add(fileVo.getReceiveUserbId());
        }
        if (fileVo.getSendUserbId()!=null){
            allotBill.setSendUserbId(fileVo.getSendUserbId());
            allotBill.setAgent(userPublicService.getOne(fileVo.getSendUserbId()).getName());
            List<Integer> idList1 = new ArrayList<>();
            idList1.add(fileVo.getSendUserbId());
            MessageBto messageBto = new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "被选为签发人", idList1, 1);
            messageService.add(messageBto);
        }
        //保存账单
        allotBill.setSendFiles(FilesUtil.stringFileToList(fileVo.getAllotFiles()));
        allotBill.setAllotStatus(5);
        allotBill.setReceiveTime(TimestampUtil.getCurrentTimestamp());
        allotBillService.update(allotBill);
        List<Integer> ids = StringSplitUtil.split(allotBill.getAllotCheckDetail());
        //业务完结
        taskService.moveToEnd(taskBto);
        //主业务完结
        if (taskBto.getParentTaskId()!=null) {
            taskService.moveToEnd(taskService.get(taskBto.getParentTaskId()));
        }
        //装备日志
        List<FileVo> fileVoList = new ArrayList<>();
        fileVo.getAllotFiles().forEach(fileRet -> fileVoList.add(new FileVo("配发单", fileRet.getName(), fileRet.getPreviewPath())));
        ids.forEach(integer -> {
            DeviceLogDto deviceLogDto = new DeviceLogDto(integer, "上传配发单", fileVoList);
            deviceLogService.addLog(deviceLogDto);
            DeviceLibrary deviceLibrary = deviceLibraryService.getOne(integer);
            deviceLibrary.setLocationUnit(allotBill.getReceiveUnit());
            deviceLibrary.setLifeStatus(2);
            deviceLibrary.setOwnUnit(allotBill.getReceiveUnit());
            deviceLibrary.setManageStatus(1);
            deviceLibraryService.update(deviceLibrary);
        });
        if (idList.size()>0) {
            MessageBto messageBto = new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "被选为经办人", idList, 1);
            messageService.add(messageBto);
        }
        //发送阅知信息
        List<Integer> userIds = userPublicService.findOtherUser(userUtils.getCurrentUserId());
        userIds.addAll(userDao.findAllByUnitsId(userPublicService.findUnitIdByName(allotBill.getReceiveUnit())).stream()
                .map(User::getUserId)
                .collect(Collectors.toList()));
        MessageBto messageBto = new MessageBto(taskBto.getParentTaskId(),taskBto.getBusinessType(),"业务办结",userIds,1);
        messageService.add(messageBto);
        return ResponseEntity.ok("OK");
    }

    @ApiOperation(value = "上传发送方签发人", notes = "上传发送方签发人")
    @PostMapping(value = "/updateAgent")
    public ResponseEntity updateAgent(@RequestBody AgentVo agentVo){
        TaskBto taskBto = taskService.get(agentVo.getId());
        List<Integer> idList = new ArrayList<>();
        idList.add(agentVo.getSendUserbId());
        MessageBto messageBto = new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"被选为签发人",idList,1);
        messageService.add(messageBto);
        AllotBill allotBill = allotBillService.getOne(taskBto.getBillId());
        allotBill.setAgent(agentVo.getName());
        allotBill.setSendUserbId(agentVo.getSendUserbId());
        return ResponseEntity.ok(allotBillService.update(allotBill));
    }
}
