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

import com.fasterxml.jackson.core.type.TypeReference;
import com.sun.org.apache.bcel.internal.generic.NEW;
import com.tykj.dev.config.base.DeviceLifeStatus;
import com.tykj.dev.device.apply.service.DeviceApplyBillService;
import com.tykj.dev.device.decommissioning.entity.DeviceDecommissioningDetail;
import com.tykj.dev.device.decommissioning.entity.vo.DecommissioningOrderOutData;
import com.tykj.dev.device.decommissioning.entity.vo.StorageDeviceDevommissiong;
import com.tykj.dev.device.decommissioning.service.DeviceDecommissioningBusinessService;
import com.tykj.dev.device.decommissioning.service.DeviceDecommissioningDetailService;
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.ScriptSaveVo;
import com.tykj.dev.device.task.service.TaskService;
import com.tykj.dev.device.task.subject.bto.TaskBto;
import com.tykj.dev.device.task.subject.domin.Task;
import com.tykj.dev.device.user.base.ret.MemberThat;
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.entity.Units;
import com.tykj.dev.device.user.subject.entity.User;
import com.tykj.dev.device.user.subject.service.UnitsService;
import com.tykj.dev.device.user.subject.service.UserService;
import com.tykj.dev.misc.base.BusinessEnum;
import com.tykj.dev.misc.base.StatusEnum;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.DeviceSeqUtil;
import com.tykj.dev.misc.utils.JacksonUtil;
import com.tykj.dev.misc.utils.StringUtils;
import com.tykj.dev.misc.utils.TaskDisposeUtil;
import jdk.nashorn.internal.ir.IfNode;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName DeviceDecommissioningBusinessServiceImpl.java
 * @Description TODO
 * @createTime 2021年03月29日 16:38:00
 */
@Service
@Slf4j
@SuppressWarnings("ALL")
public class DeviceDecommissioningBusinessServiceImpl implements DeviceDecommissioningBusinessService {

    @Autowired
    UserService userService;

    @Autowired
    UnitsService unitsService;

    @Autowired
    DeviceDecommissioningDetailService deviceDecommissioningDetailService;

    @Autowired
    DeviceLibraryDao deviceLibraryDao;

    @Autowired
    TaskService taskService;

    @Autowired
    DeviceLogService deviceLogService;

    @Autowired
    DeviceLibraryService deviceLibraryService;

    @Autowired
    MessageService messageService;
    @Autowired
    DeviceApplyBillService deviceApplyBillService;

    @Override
    public TaskBto saveDeviceDecommissioningDraft(Integer userId, DecommissioningOrderOutData decommissioningOrderOutData) {
        User user = userService.findByUser(userId);
        Units units = unitsService.findById(user.getUnitsId());
        DeviceDecommissioningDetail deviceDecommissioningDetail;
        TaskBto taskBto;
        List<ScriptSaveVo> scriptSaveVos = decommissioningOrderOutData.getScriptSaveVos();
        List<String> seqNumbers = new ArrayList<>();
        scriptSaveVos.forEach(
                scriptSaveVo -> {
                    if (scriptSaveVo.getSeqNumber() != null) {
                        seqNumbers.addAll(DeviceSeqUtil.selectDeviceSeqs(scriptSaveVo.getSeqNumber()));
                    }
                }
        );
        if (decommissioningOrderOutData.getTaskId()==null){
            deviceDecommissioningDetail = decommissioningOrderOutData.toDeviceDecommissioningDetail();
            if (decommissioningOrderOutData.getApplyId()!=null) {
                DeviceDecommissioningDetail deviceDestroyBill1 = deviceDecommissioningDetailService.findApplyId(decommissioningOrderOutData.getApplyId());
                if (deviceDestroyBill1 != null) {
                    deviceDecommissioningDetail.setId(deviceDestroyBill1.getId());
                }
            }
            deviceDecommissioningDetailService.saveDeviceDecommissioningDetail(deviceDecommissioningDetail);
            deviceDecommissioningDetail.setNum("NO:第" + LocalDateTime.now().getYear() + "QT" + deviceDecommissioningDetail.getId());
            taskBto= sendDraftTask(units.getUnitId(), deviceDecommissioningDetail.getId(),userId);
            deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());
            addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),user.getName()+"保存退役任务草稿",gainThisUser(userId,units.getUnitId())));
        }else {
            taskBto=taskService.get(decommissioningOrderOutData.getTaskId());
            deviceDecommissioningDetail = deviceDecommissioningDetailService.findDeviceDecommissioningDetail(taskBto.getBillId());
            deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());
            deviceDecommissioningDetail.setSendUserbId(decommissioningOrderOutData.getSendUserbId());
            deviceDecommissioningDetail.setSenderUserB(decommissioningOrderOutData.getSenderUserB());
        }
        deviceDecommissioningDetail.setOutboundFile(FilesUtil.stringFileToList(decommissioningOrderOutData.getOutboundFileList()));
        deviceDecommissioningDetail.setApplyNumber(decommissioningOrderOutData.getApplyNumber());
        deviceDecommissioningDetail.setReplayNumber(decommissioningOrderOutData.getReplayNumber());
        deviceDecommissioningDetail.setReplyFiles(FilesUtil.stringFileToList(decommissioningOrderOutData.getReplyFileList()));
        deviceDecommissioningDetail.setApplyFiles(FilesUtil.stringFileToList(decommissioningOrderOutData.getApplyFileList()));
        deviceDecommissioningDetail.setScripts(decommissioningOrderOutData.getScriptSaveVos());
        deviceDecommissioningDetail.setScriptJson(JacksonUtil.toJSon(decommissioningOrderOutData.getScriptSaveVos()));
        deviceDecommissioningDetailService.saveDeviceDecommissioningDetail(deviceDecommissioningDetail);
        taskBto.setRecordId(deviceDecommissioningDetail.getNum());
        return taskBto;
    }

    @Override
    public DeviceDecommissioningDetail provinceSendDecommissioning(Integer userId, DecommissioningOrderOutData decommissioningOrderOutData) {
            User user = userService.findByUser(userId);
            Units units = unitsService.findById(user.getUnitsId());
            DeviceDecommissioningDetail deviceDecommissioningDetail ;
            List<ScriptSaveVo> scriptSaveVos = decommissioningOrderOutData.getScriptSaveVos();
            List<String> seqNumbers = new ArrayList<>();
            scriptSaveVos.forEach(
                    scriptSaveVo -> {
                        if (scriptSaveVo.getSeqNumber() != null) {
                            seqNumbers.addAll(DeviceSeqUtil.selectDeviceSeqs(scriptSaveVo.getSeqNumber()));
                        }
                    }
            );
            deviceLibraryService.judgeSeqNumbersInNotEqualLifeStatus(seqNumbers,DeviceLifeStatus.REPEL.id);
            //判断是否为草稿 还是直接发起
            if (decommissioningOrderOutData.getTaskId()!=null){
                TaskBto taskBto= taskService.get(decommissioningOrderOutData.getTaskId());
                List<StatusEnum> statusEnums = new ArrayList<>();
                statusEnums.add(StatusEnum.DECOMMISSIONING_1250);
                statusEnums.add(StatusEnum.DECOMMISSIONING_1252);
                TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), statusEnums);
                deviceDecommissioningDetail=deviceDecommissioningDetailService.findDeviceDecommissioningDetail(taskBto.getBillId());
                taskBto= taskService.moveToSpecial(taskBto,StatusEnum.SEND_BACK_1210,"country");
                deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());
                if (decommissioningOrderOutData.getSendUserbId()!=null){
                    deviceDecommissioningDetail.setSendUserbId(decommissioningOrderOutData.getSendUserbId());
                }
                if (decommissioningOrderOutData.getSenderUserB()!=null){
                    deviceDecommissioningDetail.setSenderUserB(decommissioningOrderOutData.getSenderUserB());
                }
                addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),user.getName()+"发起退役任务,待上传回执单据",gainThisUser(userId,units.getUnitId())));
            }else {
                deviceDecommissioningDetail = decommissioningOrderOutData.toDeviceDecommissioningDetail();
                deviceDecommissioningDetailService.saveDeviceDecommissioningDetail(deviceDecommissioningDetail);
                TaskBto taskBto= sendOutSuperior(units.getUnitId(), deviceDecommissioningDetail.getId(),userId);
                addMessage(new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "发起退役任务,待上传回执单据", gainThisUser(user.getUserId(), user.getUnitsId())));
                deviceDecommissioningDetail.setNum("NO:第" + LocalDateTime.now().getYear() + "QT" + deviceDecommissioningDetail.getId());
                deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());
                deviceDecommissioningDetail.setSendUserbId(decommissioningOrderOutData.getSendUserbId());
                deviceDecommissioningDetail.setSenderUserB(decommissioningOrderOutData.getSenderUserB());

            }
            deviceDecommissioningDetail.setLeftSignatureId(decommissioningOrderOutData.getLeftSignatureId());
            deviceDecommissioningDetail.setApplyNumber(decommissioningOrderOutData.getApplyNumber());
            deviceDecommissioningDetail.setReplayNumber(decommissioningOrderOutData.getReplayNumber());
            deviceDecommissioningDetail.setReplyFiles(FilesUtil.stringFileToList(decommissioningOrderOutData.getReplyFileList()));
            deviceDecommissioningDetail.setApplyFiles(FilesUtil.stringFileToList(decommissioningOrderOutData.getApplyFileList()));
            deviceDecommissioningDetail.setDeviceIds(StringUtils.ListToString(decommissioningOrderOutData.getDevIds()));
            deviceDecommissioningDetail.setOutboundFile(FilesUtil.stringFileToList(decommissioningOrderOutData.getOutboundFileList()));
            deviceDecommissioningDetail.setScripts(decommissioningOrderOutData.getScriptSaveVos());
            deviceDecommissioningDetail.setScriptJson(JacksonUtil.toJSon(decommissioningOrderOutData.getScriptSaveVos()));
//            deviceDecommissioningDetail.setDeviceLibraryEntities(findInvoleDevice(deviceDecommissioningDetail.getDeviceIds()));
            deviceDecommissioningDetailService.saveDeviceDecommissioningDetail(deviceDecommissioningDetail);
            deviceLibraryDao.upDateSeqNumbersLeftStatus(DeviceLifeStatus.RETIRED.id,seqNumbers);
            devLogAdd(seqNumbers,"发了退役任务,状态转化为退役中",userId);
        if (decommissioningOrderOutData.getApplyId()!=null) {
            Optional<Task> billIdAndBusinessTypeNotBillStatus = taskService.findBillIdAndBusinessTypeNotBillStatus(decommissioningOrderOutData.getApplyId(), BusinessEnum.APPLY.id);
            taskService.moveToEnd(billIdAndBusinessTypeNotBillStatus.get().parse2Bto());
        }else {
            //2:退役申请，3:报废申请，4:销毁申请
            deviceApplyBillService.updateCompleteNum(2,scriptSaveVos);
        }
        return deviceDecommissioningDetail;
    }

    @Override
    public void receiptSingle(Integer taskId, StorageDeviceDevommissiong storageDeviceDevommissiong) {
        User user=userService.findByUser(storageDeviceDevommissiong.getUserId());
        TaskBto taskBto= taskService.get(taskId);
        List<StatusEnum> statusEnums = new ArrayList<>();
        statusEnums.add(StatusEnum.SEND_BACK_1210);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), statusEnums);
        DeviceDecommissioningDetail deviceDecommissioningDetail=deviceDecommissioningDetailService.findDeviceDecommissioningDetail(taskBto.getBillId());
        deviceDecommissioningDetail.setBillFile(FilesUtil.stringFileToList(storageDeviceDevommissiong.getFileRets()));
        List<String> seqNumbers=new ArrayList<>();
        JacksonUtil.readValue(deviceDecommissioningDetail.getScriptJson(), new TypeReference<List<ScriptSaveVo>>() {}).forEach(
                scriptSaveVo -> {
                    if (scriptSaveVo.getSeqNumber()!=null){
                        seqNumbers.addAll(DeviceSeqUtil.selectDeviceSeqs(scriptSaveVo.getSeqNumber()));
                    }
                }
        );
        deviceLibraryService.judgeSeqNumbersInNotEqualLifeStatus(seqNumbers,DeviceLifeStatus.RETIRED.id);
        if (storageDeviceDevommissiong.getUserBName()!=null) {
            deviceDecommissioningDetail.setReceiveUserB(storageDeviceDevommissiong.getUserBName());
        }
        if (storageDeviceDevommissiong.getUserB()!=null){
            deviceDecommissioningDetail.setReceiveUserbId(storageDeviceDevommissiong.getUserB());

        }
        if (storageDeviceDevommissiong.getUserA()!=null){
            deviceDecommissioningDetail.setReceiveUseraId(storageDeviceDevommissiong.getUserA());

        }
        if (storageDeviceDevommissiong.getUserAName()!=null) {
            deviceDecommissioningDetail.setReceiveUserA(storageDeviceDevommissiong.getUserAName());
        }
        if (storageDeviceDevommissiong.getSenderId()!=null){
            deviceDecommissioningDetail.setSendUserbId(storageDeviceDevommissiong.getSenderId());
        }
        if (storageDeviceDevommissiong.getSenderName()!=null){
            deviceDecommissioningDetail.setSenderUserB(storageDeviceDevommissiong.getSenderName());
        }
        taskBto=taskService.moveToEnd(taskBto);
        deviceDecommissioningDetail.setReceiveTime(new Date());
        deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());
        deviceLibraryDao.upDateSeqNumbersLeftStatusAndUnitNameAndLockStatus(DeviceLifeStatus.RETIRE.id,deviceDecommissioningDetail.getReceiveUnit(),0,seqNumbers);
        deviceDecommissioningDetailService.saveDeviceDecommissioningDetail(deviceDecommissioningDetail);
        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"退役任务回执单据上传成功任务结束",gainThisUser(user.getUserId(),user.getUnitsId())));
        devLogAdd(seqNumbers,"退役任务完成,状态转化为已退役",storageDeviceDevommissiong.getUserId());

    }

    @Override
    public void sealOfAudit(Integer userId, DecommissioningOrderOutData orderOutData) {
        DeviceDecommissioningDetail deviceDecommissioningDetail =new DeviceDecommissioningDetail();
        User user = userService.findByUser(orderOutData.getSendUserbId());
        Units units=unitsService.findById(user.getUnitsId());
        if (orderOutData.getTaskId()==null){
             deviceDecommissioningDetail = orderOutData.toDeviceDecommissioningDetail();
             deviceDecommissioningDetailService.saveDeviceDecommissioningDetail(deviceDecommissioningDetail);
             deviceDecommissioningDetail.setNum("NO:第" + LocalDateTime.now().getYear() + "QT" + deviceDecommissioningDetail.getId());
             TaskBto taskBto= sealOfAuditTask(units.getUnitId(), deviceDecommissioningDetail.getId(),orderOutData.getSendUserbId());
             deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());

        } else {
            TaskBto taskBto = taskService.get(orderOutData.getTaskId());
            List<StatusEnum> statusEnums = new ArrayList<>();
            statusEnums.add(StatusEnum.DECOMMISSIONING_1250);
            TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), statusEnums);
            deviceDecommissioningDetail = deviceDecommissioningDetailService.findDeviceDecommissioningDetail(taskBto.getBillId());
            taskBto = taskService.moveToSpecial(taskBto, StatusEnum.DECOMMISSIONING_1251, orderOutData.getSendUserbId());
            deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());

        }
        deviceDecommissioningDetail.setReceiveTime(new Date());
        deviceDecommissioningDetail.setApplyNumber(orderOutData.getApplyNumber());
        deviceDecommissioningDetail.setReplayNumber(orderOutData.getReplayNumber());
        deviceDecommissioningDetail.setReplyFiles(FilesUtil.stringFileToList(orderOutData.getReplyFileList()));
        deviceDecommissioningDetail.setApplyFiles(FilesUtil.stringFileToList(orderOutData.getApplyFileList()));
        deviceDecommissioningDetail.setScriptJson(JacksonUtil.toJSon(orderOutData.getScriptSaveVos()));
        deviceDecommissioningDetail.setScripts(orderOutData.getScriptSaveVos());
        deviceDecommissioningDetail.setSenderUserB(user.getName());
        deviceDecommissioningDetail.setSendUserbId(user.getUserId());
        deviceDecommissioningDetailService.saveDeviceDecommissioningDetail(deviceDecommissioningDetail);
        }

    @Override
    public void outSealOfAuditEnd(Integer taskId, Integer reviewTheResults) {
        TaskBto taskBto= taskService.get(taskId);
        DeviceDecommissioningDetail deviceDecommissioningDetail=deviceDecommissioningDetailService.findDeviceDecommissioningDetail(taskBto.getBillId());

        if (reviewTheResults==0){
            taskBto= taskService.moveToSpecial(taskBto,StatusEnum.DECOMMISSIONING_1252,0);
            deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());
        }else {
            deviceDecommissioningDetail.setSenderUserB(null);
            deviceDecommissioningDetail.setSendUserbId(null);
            taskBto = taskService.moveToSpecial(taskBto,StatusEnum.DECOMMISSIONING_1250,deviceDecommissioningDetail.getSendUseraId());
            deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());

        }
        deviceDecommissioningDetailService.saveDeviceDecommissioningDetail(deviceDecommissioningDetail);

    }

    @Override
    public void deleteDrafts(Integer taskId) {
      //删除 把task删除
        //并且涉及的装备改为在库
      TaskBto taskBto= taskService.get(taskId);
      DeviceDecommissioningDetail deviceDecommissioningDetail= deviceDecommissioningDetailService.findDeviceDecommissioningDetail(taskBto.getBillId());
      taskBto= taskService.moveToArchive(taskBto);
      deviceDecommissioningDetail.setDecommissioningStatus(taskBto.getBillStatus());
      deviceDecommissioningDetailService.saveDeviceDecommissioningDetail(deviceDecommissioningDetail);
    }

    /**
     * 发起调用电子签章确认任务
     */
    private TaskBto sealOfAuditTask(Integer unitId, Integer repelDetailId,Integer userId){
        List<Integer> list=new ArrayList<>();
        list.add(userId);
        return taskService.start(new TaskBto(StatusEnum.DECOMMISSIONING_1251.id, "退役设备任务", null, ".", repelDetailId, BusinessEnum.DECOMMISSIONING.id, unitId, 0, "", list));
    }

    /**
     * 省出库中办
     */
    private TaskBto sendOutSuperior(Integer unitId, Integer repelDetailId,Integer userId){
        List<Integer> list=new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1210.id, "退役设备任务", null, ".", repelDetailId, BusinessEnum.DECOMMISSIONING.id, unitId, 1, "country", list));
    }

    /**
     * 省出库中办
     */
    private TaskBto sendDraftTask(Integer unitId, Integer repelDetailId,Integer userId){
        List<Integer> list=new ArrayList<>();
        list.add(userId);
//        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.DECOMMISSIONING_1250.id, "退役设备任务", null, ".", repelDetailId, BusinessEnum.DECOMMISSIONING.id, unitId, 0, "", list));
    }

    /**
     * 异步添加装备日志
     */
    private void devLogAdd(List<String> seqNumbers, String remark, Integer userId){

        CompletableFuture.runAsync(() -> {

            List<DeviceLog> logDtos=new ArrayList<>();
            deviceLibraryDao.findAllBySeqNumberIn(seqNumbers).forEach(
                deviceLibrary -> {
                    logDtos.add(new DeviceLogDto(deviceLibrary.getId(),remark,null,userId).toDo());

                }
        );

            deviceLogService.saveAllLog(logDtos);
        });

    }

    private void addMessage(MessageBto messageBto){
        messageService.add(messageBto);
    }

    /**
     * 根据单位id查询用户 去除用户id
     * @param userId
     * @param unitId
     * @return
     */
    private List<Integer> gainThisUser(Integer userId,Integer unitId){
        return userService.findAllByUnite(unitId).stream().filter(user -> user.getUserId()!=userId).map(User::getUserId).collect(Collectors.toList());
    }

    /**
     * 根据单位id查询用户id集合
     * @param unitId
     * @return
     */
    private List<Integer> findUnitId(Integer unitId){
        return userService.findAllByUnite(unitId).stream().map(User::getUserId).collect(Collectors.toList());
    }

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


}
