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

import com.tykj.dev.config.base.DeviceLifeStatus;
import com.tykj.dev.device.library.repository.DeviceLibraryDao;
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.sendback.entity.domain.AgainStorageBill;
import com.tykj.dev.device.sendback.entity.vo.TransitionOfLifeVo;
import com.tykj.dev.device.sendback.repository.AgainStorageBillDao;
import com.tykj.dev.device.sendback.service.AgainStorageBillService;
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.entity.SecurityUser;
import com.tykj.dev.device.user.subject.entity.User;
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.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName AgainStorageBillServiceImpl.java
 * @Description 直接改变装备的状态记录业务
 * @createTime 2021年03月16日 17:07:00
 */
@Service
@Slf4j
public class AgainStorageBillServiceImpl implements AgainStorageBillService {
    @Autowired
    DeviceLibraryDao deviceLibraryDao;

    @Autowired
    AgainStorageBillDao againStorageBillDao;

    @Autowired
    TaskService taskService;

    @Autowired
    DeviceLogService deviceLogService;

    @Autowired
    MessageService messageService;
    @Autowired
    UserService userService;

    @Override
    public void againPutInStorage(TransitionOfLifeVo transitionOfLifeVo, SecurityUser securityUser) {
        List<DeviceLibrary> deviceLibraries=  deviceLibraryDao.getDeviceLibraryEntitiesByIdIn(transitionOfLifeVo.getIds());
        AgainStorageBill againStorageBill= againStorageBillDao.save(new AgainStorageBill(StringUtils.ListToString(transitionOfLifeVo.getIds()),transitionOfLifeVo.getType()));
        String typeName;
        switch (transitionOfLifeVo.getType()){
            case 0:
                deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.IN_LIBRARY.id,transitionOfLifeVo.getIds());
                typeName="重新入库";
                break;

            case 1:
                deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.TO_BE_SCRAPPED.id,transitionOfLifeVo.getIds());
                typeName="转为待报废设备";
                break;

            case 2:
                deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.TO_BE_DESTROYED.id,transitionOfLifeVo.getIds());
                typeName="转为待销毁设备";
                break;

            case 3:
                deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.REPEL.id,transitionOfLifeVo.getIds());
                typeName="转为待退役设备";
                break;

                default:
                    throw new ApiException(ResponseEntity.status(500).body("[生命状态转换] 为找到对应的type"));

        }
        TaskBto taskBto=againStorageTask(securityUser.getCurrentUserInfo().getUnitsId(),againStorageBill.getId(),securityUser.getCurrentUserInfo().getUserId(),typeName);
        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),securityUser.getUsername()+"执行了"+typeName,gainThisUser(securityUser.getCurrentUserInfo().getUserId(),securityUser.getCurrentUserInfo().getUnitsId())));
        devLogAdd(deviceLibraries,typeName,securityUser.getCurrentUserInfo().getUserId());
    }

    @Override
    public AgainStorageBill findByid(Integer taskId) {
        TaskBto taskBto=taskService.get(taskId);
        Optional<AgainStorageBill> againStorageBillOptional = againStorageBillDao.findById(taskBto.getBillId());
        if (againStorageBillOptional.isPresent()){
            AgainStorageBill againStorageBill=againStorageBillOptional.get();
            List<DeviceLibrary> deviceLibraries = deviceLibraryDao.getDeviceLibraryEntitiesByIdIn(StringUtils.stringToList(againStorageBill.getDevIds()));
            deviceLibraries.forEach(DeviceLibrary::setConfigName);
            againStorageBill.setDeviceLibraries(deviceLibraries);
            return againStorageBill;
        }else {
            throw new ApiException(ResponseEntity.status(500).body("[重新入库] 没有找到对应的bill-id"));
        }

    }

    /**
     * 重新入库任务发起
     * 这里应为重新入库直接完结所有发起task任务为完结状态
     */
    private TaskBto againStorageTask(Integer unitId, Integer againStorageId , Integer userId , String typeName){
        List<Integer> list=new ArrayList<>();
        list.add(userId);
       return taskService.start(new TaskBto(StatusEnum.END.id, typeName, null, ".", againStorageId, BusinessEnum.AGAINSTORAGE.id, unitId, 0, null, list));
    }

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

    private List<Integer> gainThisUser(Integer userId,Integer unitId){
        return userService.findAllByUnite(unitId).stream().filter(user -> !user.getUserId().equals(userId)).map(User::getUserId).collect(Collectors.toList());
    }
    /**
     * 异步添加装备日志
     * @param deviceLibraries
     * @param remark
     * @param userId
     */
    public void devLogAdd(List<DeviceLibrary> deviceLibraries,String remark,Integer userId){
        List<DeviceLog> logDtos=new ArrayList<>();
        deviceLibraries.forEach(
                deviceLibrary -> {
                    logDtos.add(new DeviceLogDto(deviceLibrary.getId(),remark,null,userId).toDo());

                }
        );
        log.info("调用异步添加装备日志");
        CompletableFuture.runAsync(() -> {
            deviceLogService.saveAllLog(logDtos);
        });

    }
}
