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

import com.tykj.dev.blockcha.subject.service.BlockChainUtil;
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.DeviceLog;
import com.tykj.dev.device.loss.entity.vo.LossAuditvo;
import com.tykj.dev.device.loss.entity.vo.RetrieveAuditvo;
import com.tykj.dev.device.loss.service.DeviceLossService;
import com.tykj.dev.device.loss.service.LossBillService;
import com.tykj.dev.device.loss.util.StringUtils;
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.Area;
import com.tykj.dev.device.user.subject.entity.SecurityUser;
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.AreaService;
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.DeviceLifeStatus;
import com.tykj.dev.misc.base.StatusEnum;
import com.tykj.dev.device.loss.entity.domain.DeviceLoss;
import com.tykj.dev.misc.utils.TaskDisposeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName LossBillServiceImpl.java
 * @Description TODO
 * @createTime 2021年01月30日 14:08:00
 */
@Service
public class LossBillServiceImpl implements LossBillService {

    @Autowired
    TaskService taskService;

    @Autowired
    DeviceLossService deviceLossService;

    @Autowired
    UnitsService unitsService;

    @Autowired
    BlockChainUtil blockChainUtil;

    @Autowired
    DeviceLibraryDao deviceLibraryDao;

    @Autowired
    DeviceLibraryService deviceLibraryService;

    @Autowired
    AreaService areaService;

    @Autowired
    DeviceLogService deviceLogService;

    @Autowired
    MessageService messageService;

    @Autowired
    UserService userService;

    @Override
    public void initiateLoss(DeviceLoss deviceLoss, SecurityUser securityUser) {
        deviceLibraryService.isInStockOrWaitRetired(deviceLoss.getDevIdsList());
        deviceLoss.setDevIds(StringUtils.ListToString(deviceLoss.getDevIdsList()));
        deviceLoss.setLossFile(FilesUtil.stringFileToList(deviceLoss.getFileRetList()));
        DeviceLoss deviceLossThis= deviceLossService.save(deviceLoss);
        Units units=unitsService.findById(deviceLoss.getUnitId());
        Area area=areaService.findByid(units.getAreaId());
        TaskBto taskBto;
        if (units.getLevel() == 1) {
            taskBto=end(deviceLossThis.getCreateUserId(), deviceLossThis.getId(), units.getName() + "丢失装备任务", units.getUnitId());
        } else if (units.getLevel()==2){
            Units parentUnits=unitsService.findUnitAreaId(area.getFatherId());
            taskBto= newLossCityTask(parentUnits.getUnitId(), deviceLossThis.getId(), units.getName() + "丢失装备任务",securityUser.getCurrentUserInfo().getUserId());
        }else {
            Units parentUnits=unitsService.findUnitAreaId(area.getFatherId());
            taskBto= newLossCountyTask(parentUnits.getUnitId(), deviceLossThis.getId(), units.getName() + "丢失装备任务",securityUser.getCurrentUserInfo().getUserId());
        }
        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"发起了装备丢失",gainThisUser(securityUser.getCurrentUserInfo().getUserId(),securityUser.getCurrentUserInfo().getUnitsId())));

        deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.LOSS.id,deviceLoss.getDevIdsList());
        devLogAdd(deviceLoss.getDevIdsList(),"装备报备丢失", deviceLoss.getCreateUserId());
    }



    @Override
    public void superiorAuditLoss(LossAuditvo lossAuditvo) {
        User user=userService.findByUser(lossAuditvo.getUserId());
        Units units=unitsService.findById(lossAuditvo.getUnitId());
        Area area=areaService.findByid(units.getAreaId());
        TaskBto taskBto=taskService.get(lossAuditvo.getTaskId());
        DeviceLoss deviceLoss=deviceLossService.findByDeviceLoss(taskBto.getBillId());

        if (units.getLevel()==1){

            TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(),StatusEnum.LOSS1301);
            deviceLoss.setProvinceUnitName(units.getName());
            deviceLoss.setProvinceDes(lossAuditvo.getDes());
            taskService.moveToEnd(taskBto);
        }else {
            TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(),StatusEnum.LOSS1300);
            Units parentUnits=unitsService.findUnitAreaId(area.getFatherId());
            deviceLoss.setCityUnitName(units.getName());
            deviceLoss.setCityDes(lossAuditvo.getDes());
            taskBto.setOwnUnit(parentUnits.getUnitId());
            taskService.moveToSpecial(taskBto,StatusEnum.LOSS1301,0);
        }
        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"审核了装备丢失业务",gainThisUser(user.getUserId(),user.getUnitsId())));
        deviceLossService.save(deviceLoss);

    }

    @Override
    public void initiateRetrieve(DeviceLoss deviceLoss,SecurityUser securityUser) {
        deviceLibraryService.isNotLoss(deviceLoss.getDevIdsList());
        deviceLoss.setDevIds(StringUtils.ListToString(deviceLoss.getDevIdsList()));
        deviceLoss.setLossFile(FilesUtil.stringFileToList(deviceLoss.getFileRetList()));
        DeviceLoss deviceLossThis= deviceLossService.save(deviceLoss);
        Units units=unitsService.findById(deviceLoss.getUnitId());
        Area area=areaService.findByid(units.getAreaId());
        TaskBto taskBto;
        if (units.getLevel() == 1) {
            taskBto= endRetrieve(deviceLossThis.getCreateUserId(), deviceLossThis.getId(), units.getName() + "找回装备任务", units.getUnitId());
            deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.IN_LIBRARY.id,deviceLoss.getDevIdsList());
        } else if (units.getLevel()==2){
            Units parentUnits=unitsService.findUnitAreaId(area.getFatherId());
            taskBto= newRetrieveCityTask(parentUnits.getUnitId(), deviceLossThis.getId(), units.getName() + "找回装备任务",securityUser.getCurrentUserInfo().getUserId());
        }else {
            Units parentUnits=unitsService.findUnitAreaId(area.getFatherId());
            taskBto= newRetrieveCountyTask(parentUnits.getUnitId(), deviceLossThis.getId(), units.getName() + "找回装备任务",securityUser.getCurrentUserInfo().getUserId());
        }
        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"发起装备找回业务",gainThisUser(securityUser.getCurrentUserInfo().getUserId(),securityUser.getCurrentUserInfo().getUnitsId())));
        devLogAdd(deviceLoss.getDevIdsList(),"装备找回上报", deviceLoss.getCreateUserId());
    }

    @Override
    public void superiorAuditRetrieve(RetrieveAuditvo retrieveAuditvo) {
        User user=userService.findByUser(retrieveAuditvo.getUserId());
        Units units=unitsService.findById(retrieveAuditvo.getUnitId());
        Area area=areaService.findByid(units.getAreaId());
        TaskBto taskBto=taskService.get(retrieveAuditvo.getTaskId());
        DeviceLoss deviceLoss=deviceLossService.findByDeviceLoss(taskBto.getBillId());
        if (units.getLevel()==1){
            TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(),StatusEnum.RETRIEVE1401);
            deviceLoss.setProvinceUnitName(units.getName());
            deviceLoss.setProvinceDes(retrieveAuditvo.getDes());
            taskService.moveToEnd(taskBto);
            if (retrieveAuditvo.getType()==1){
                deviceLoss.setBackStatus(2);
                deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.IN_LIBRARY.id,StringUtils.stringToList(deviceLoss.getDevIds()));
                addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"装备找回业务审核成功",gainThisUser(user.getUserId(),user.getUnitsId())));
            }else {
                User user1= userService.findByUser(taskBto.getCreateUserId());
                addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"装备找回业务审核不通过",findUnitId(user1.getUnitsId())));
                deviceLoss.setBackStatus(3);
            }
        }else {
            TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(),StatusEnum.RETRIEVE1400);
            Units parentUnits=unitsService.findUnitAreaId(area.getFatherId());
            deviceLoss.setCityUnitName(units.getName());
            deviceLoss.setCityDes(retrieveAuditvo.getDes());
            if (retrieveAuditvo.getType()==1){
                taskBto.setOwnUnit(parentUnits.getUnitId());
                taskService.moveToSpecial(taskBto,StatusEnum.RETRIEVE1401,0);
                addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"装备找回业务审核成功",gainThisUser(user.getUserId(),user.getUnitsId())));

            }else {
                taskService.moveToEnd(taskBto);
                deviceLoss.setBackStatus(3);
                User user1= userService.findByUser(taskBto.getCreateUserId());
                addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"装备找回业务审核不通过",findUnitId(user1.getUnitsId())));
            }

        }
        deviceLossService.save(deviceLoss);
    }


    private TaskBto newRetrieveCountyTask(Integer unitId, Integer lossId, String title,Integer userID){
        List<Integer> list=new ArrayList<>();
        list.add(userID);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.RETRIEVE1400.id, title, 0, ".", lossId, BusinessEnum.RETRIEVE.id, unitId, 1, "", list));
    }

    private TaskBto newRetrieveCityTask(Integer unitId, Integer lossId, String title,Integer userID){
        List<Integer> list=new ArrayList<>();
        list.add(userID);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.RETRIEVE1401.id, title, 0, ".", lossId, BusinessEnum.RETRIEVE.id, unitId, 1, "", list));
    }

    private TaskBto endRetrieve(Integer userId, Integer lossId, String title, Integer unitId){
        List<Integer> list=new ArrayList<>();
        list.add(userId);
       return taskService.start(new TaskBto(StatusEnum.END.id, title, 0, ".", lossId, BusinessEnum.RETRIEVE.id, unitId, 0, "", list));
    }


    private TaskBto newLossCountyTask(Integer unitId, Integer lossId, String title,Integer userID){
        List<Integer> list=new ArrayList<>();
        list.add(userID);
        list.add(0);
       return taskService.start(new TaskBto(StatusEnum.LOSS1300.id, title, 0, ".", lossId, BusinessEnum.LOSS.id, unitId, 1, "", list));
    }

    private TaskBto newLossCityTask(Integer unitId, Integer lossId, String title,Integer userID){
        List<Integer> list=new ArrayList<>();
        list.add(userID);
        list.add(0);
       return taskService.start(new TaskBto(StatusEnum.LOSS1301.id, title, 0, ".", lossId, BusinessEnum.LOSS.id, unitId, 1, "", list));
    }

    private TaskBto end(Integer userId, Integer lossId, String title, Integer unitId){
        List<Integer> list=new ArrayList<>();
        list.add(userId);
        return taskService.start(new TaskBto(StatusEnum.END.id, title, 0, ".", lossId, BusinessEnum.LOSS.id, unitId, 0, "", list));
    }



    private void devLogAdd(List<Integer> ids, String remark,Integer userId){
        List<DeviceLog> logDtos=new ArrayList<>();
        deviceLibraryDao.findAllById(ids).forEach(
                deviceLibrary -> logDtos.add(new DeviceLogDto(deviceLibrary.getId(), remark,null,userId).toDo())
        );
        CompletableFuture.runAsync(() -> 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().equals(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());
    }



}
