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

import com.fasterxml.jackson.core.type.TypeReference;
import com.tykj.dev.device.file.entity.FileRet;
import com.tykj.dev.device.file.service.FilesUtil;
import com.tykj.dev.device.library.service.DeviceLibraryCacheService;
import com.tykj.dev.device.library.service.DeviceLibraryService;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.device.repair.service.RepairDetailService;
import com.tykj.dev.device.repair.subject.vo.BillVo;
import com.tykj.dev.device.repair.subject.vo.ClearRepairVo;
import com.tykj.dev.device.repair.subject.vo.ClearTaskVo;
import com.tykj.dev.device.sendback.entity.domain.SuspensionBill;
import com.tykj.dev.device.sendback.entity.vo.CityConfirmRequest;
import com.tykj.dev.device.sendback.entity.vo.ProvinceConfirmRequest;
import com.tykj.dev.device.sendback.service.SuspensionBillBusinessService;
import com.tykj.dev.device.sendback.service.SuspensionBillService;
import com.tykj.dev.device.task.service.TaskService;
import com.tykj.dev.device.task.subject.bto.TaskBto;
import com.tykj.dev.device.user.cache.UnitsCache;
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.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.StatusEnum;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.JacksonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName SuspensionBillBusinessService.java
 * @Description TODO
 * @createTime 2021年09月02日 16:41:00
 */
@Service
public class SuspensionBillBusinessServiceimpl implements SuspensionBillBusinessService {

    @Autowired
    TaskService taskService;
    @Autowired
    DeviceLibraryCacheService deviceLibraryCacheService;

    @Autowired
    SuspensionBillService suspensionBillService;

    @Autowired
    DeviceLibraryService deviceLibraryService;

    @Autowired
    RepairDetailService repairDetailService;

    @Autowired
    AreaService areaService;

    @Autowired
    MessageService messageService;

    @Autowired
    UserService userService;

    @Autowired
    UnitsService unitsService;

    @Autowired
    UnitsCache unitsCache;
     /**
      * 功能描述: <br>
      * 调用维修模块的接口 输入：装备id、以及相关字段 输出：根据设备组合成一个 维修业务的集合列表
      * 根据输出集合 生成对应的中止任务，根据设备的
      * @return:
      * @since: 1.0.0
      * @Author:zjm
      * @Date:
      */

    @Override
    public void initiateSuspensionBill(List<Integer> libraryList, Units units, User user) {
//        List<ClearTaskVo> clearTaskVo =new ArrayList<>();
//        clearTaskVo.add(new ClearTaskVo(1,));
        Map<Integer, ClearTaskVo> clearTaskVo = repairDetailService.getClearTaskVo(libraryList);

        Units parentUnit = unitsService.findUnitAreaId(areaService.findByIdTosuperiorArea(units.getAreaId()).getId());
        String title= "["+units.getName()+"]-中止任务";
        clearTaskVo.values().forEach(
                clearTaskVo1 -> {
                    String files = "";
                    if (clearTaskVo1.getRepairSendBill().getSendFiles()!=null&& !"".equals(clearTaskVo1.getRepairSendBill().getSendFiles())){
                        files=clearTaskVo1.getRepairSendBill().getSendFiles();
                    }
                    if (clearTaskVo1.getRepairSendBill().getReceiveFiles()!=null&& !"".equals(clearTaskVo1.getRepairSendBill().getReceiveFiles())){
                        files=clearTaskVo1.getRepairSendBill().getReceiveFiles();
                    }
                    SuspensionBill suspensionBill=new SuspensionBill(title,"",units.getUnitId(),parentUnit.getUnitId(),null,null,null,null,"",null,null,null,null,null,null,null,null,null,null,null);
                    //保存中止业务信息
                    suspensionBill.setBillVos(JacksonUtil.toJSon(clearTaskVo1.getBillVos()));
                    suspensionBill.setRelatedTaskId(clearTaskVo1.getTaskId());
                    suspensionBill.setFileRets(files);
                    suspensionBill.setBusinessType(clearTaskVo1.getBusinessType());
                    suspensionBill= suspensionBillService.saveSuspensionBill(suspensionBill);
                    suspensionBill.setNum("NO:第" + LocalDateTime.now().getYear() + "ZZ" + suspensionBill.getId());
                    //生成代办任务信息
                    createTaskBto(user.getUserId(),title,suspensionBill.getId(),units.getUnitId());
                    deviceLibraryService.upDateLockStatus(1,clearTaskVo1.getBillVos().stream().map(BillVo::getDevicesId).collect(Collectors.toList()));
                }
        );

    }

    @Override
    public void initiateSuspensionBill1(List<Integer> libraryList,SecurityUser securityUser) {

        if (securityUser.getCurrentUserInfo().getUnits().getLevel()==3){
            Units parentUnit = unitsService.findUnitAreaId(areaService.findByIdTosuperiorArea(securityUser.getCurrentUserInfo().getUnits().getAreaId()).getId());
           initiateSuspensionBill(libraryList,parentUnit,securityUser.getCurrentUserInfo());
        }else {
            initiateSuspensionBill(libraryList,securityUser.getCurrentUserInfo().getUnits(),securityUser.getCurrentUserInfo());
        }
    }

    @Override
    public void initiateSuspensionBill2(List<Integer> libraryList, SecurityUser securityUser) {
        Map<Integer, ClearTaskVo> clearTaskVo = repairDetailService.getClearTaskVo(libraryList);
        String title= "[直属单位]-中止任务";
        clearTaskVo.values().forEach(
                clearTaskVo1 -> {
                    List<FileRet> list=new ArrayList<>();
                    list.addAll(clearTaskVo1.getRepairSendBill().getReceiveFileList());
                    list.addAll(clearTaskVo1.getRepairSendBill().getSendFileList());
                    SuspensionBill suspensionBill=new SuspensionBill(title,"",securityUser.getCurrentUserInfo().getUnitsId(),securityUser.getCurrentUserInfo().getUnitsId(),securityUser.getCurrentUserInfo().getUserId(),securityUser.getCurrentUserInfo().getName(),null,null,"",null,null,null,null,null,null,null,null,null,null,null);
                    //保存中止业务信息
                    suspensionBill.setBillVos(JacksonUtil.toJSon(clearTaskVo1.getBillVos()));
                    suspensionBill.setRelatedTaskId(clearTaskVo1.getTaskId());
                    suspensionBill.setFileRets(FilesUtil.stringFileToList(list));
                    suspensionBill.setBusinessType(clearTaskVo1.getBusinessType());
                    suspensionBill= suspensionBillService.saveSuspensionBill(suspensionBill);
                    suspensionBill.setNum("NO:第" + LocalDateTime.now().getYear() + "ZZ" + suspensionBill.getId());
                    //生成代办任务信息
                    createTaskBto(securityUser.getCurrentUserInfo().getUserId(),title,suspensionBill.getId(),securityUser.getCurrentUserInfo().getUnits().getUnitId());
                    deviceLibraryService.upDateLockStatus(1,clearTaskVo1.getBillVos().stream().map(BillVo::getDevicesId).collect(Collectors.toList()));
                }
        );

    }

    @Override
    public void cityConfirm(CityConfirmRequest cityConfirmRequest, SecurityUser securityUser) {
        TaskBto taskBto= taskService.get(cityConfirmRequest.getTaskId());
        SuspensionBill suspensionBill = suspensionBillService.findByIdToSuspensionBill(taskBto.getBillId());
        suspensionBill.setSenderDes(cityConfirmRequest.getDes());
        suspensionBill.setSendUserId(securityUser.getCurrentUserInfo().getUserId());
        suspensionBill.setSenderUserName(securityUser.getCurrentUserInfo().getName());
        suspensionBill= suspensionBillService.saveSuspensionBill(suspensionBill);
        taskBto.setOwnUnit(suspensionBill.getReceiveUnitId());
        taskBto= taskService.addInvolveUser(taskBto,securityUser.getCurrentUserInfo().getUserId());
        taskService.moveToSpecial(taskBto,StatusEnum.SUSPENSION1501,0);
    }

    @Override
    public void provinceConfirm(ProvinceConfirmRequest provinceConfirmRequest,SecurityUser securityUser) {
        Map<String,String> map=new HashMap<>();
        TaskBto taskBto= taskService.get(provinceConfirmRequest.getTaskId());
        SuspensionBill suspensionBill = suspensionBillService.findByIdToSuspensionBill(taskBto.getBillId());
        suspensionBill.setReceiveUserId(securityUser.getCurrentUserInfo().getUserId());
        suspensionBill.setReceiveDes(provinceConfirmRequest.getDes());
        suspensionBill.setBillVos(JacksonUtil.toJSon(provinceConfirmRequest.getBillVoList()));
        suspensionBillService.saveSuspensionBill(suspensionBill);
        taskService.moveToEnd(taskBto);
        //调用维修提供的接口 改变设备的状态以及所在。

        suspensionBill.getBillVoList().forEach(
                billVo -> {
                  DeviceLibrary deviceLibrary = deviceLibraryService.getOne(billVo.getDevicesId());
                    map.put(deviceLibrary.getOwnUnit(),null);
                }
        );
        repairDetailService.setDevicesOwnUnit(JacksonUtil.readValue(suspensionBill.getBillVos(), new TypeReference<List<BillVo>>() {
        }));
        //给相关人员发阅读
        List<Integer> userId=new ArrayList<>();
        map.keySet().forEach(
                name->{
                   Units units= unitsService.findbyName(name);
                   userId.addAll(userService.findAllByUnite(units.getUnitId()).stream().map(User::getUserId).collect(Collectors.toList()));
                }
        );
        deviceLibraryService.upDateLockStatus(0,provinceConfirmRequest.getBillVoList().stream().map(BillVo::getDevicesId).collect(Collectors.toList()));
        userId.remove(securityUser.getCurrentUserInfo().getUserId());
        messageService.add(new MessageBto(taskBto.getId(), BusinessEnum.SUSPENSION.id, securityUser.getCurrentUserInfo().getName()+"已处理维修中止业务，其中由本单位设备请查看详情", userId, suspensionBill.getId().toString()));
    }

    @Override
    public SuspensionBill findByTaskId(Integer taskId) {
        TaskBto taskBto = taskService.get(taskId);
        SuspensionBill suspensionBill= suspensionBillService.findByIdToSuspensionBill(taskBto.getBillId());
        suspensionBill.setBillVoList(JacksonUtil.readValue(suspensionBill.getBillVos(), new TypeReference<List<BillVo>>() {
        }));
        suspensionBill.setFileSet(FilesUtil.stringFileToList(suspensionBill.getFileRets()));
        suspensionBill.setIsEnd(true);
        Map<Integer,BillVo> billVoMap = suspensionBill.getBillVoList().stream().collect(Collectors.toMap(BillVo::getDevicesId,billVo -> billVo));
        ClearRepairVo clearRepairVo = repairDetailService.underRepair(new ArrayList<>(billVoMap.keySet()));
        if (clearRepairVo.getRepairingList().size()!=0){
            clearRepairVo.getRepairingList().forEach(
                    repairDetail -> {
                        if (billVoMap.containsKey(repairDetail.getDeviceId())){
                            BillVo billVo=billVoMap.get(repairDetail.getDeviceId());
                            billVo.setDeviceStatusDescription("等待接收-["+repairDetail.getOwnUnit()+"]送修给["+repairDetail.getLocationUnit()+"]");
                            billVoMap.put(repairDetail.getDeviceId(),billVo);
                        }else {
                            throw new ApiException("[中止任务] billVoMap未找到对应key："+repairDetail.getDeviceId());
                        }
                    }
            );
            suspensionBill.setISNotCommitDes("存在等待接收入库的设备");
            suspensionBill.setIsEnd(false);
        }
        if (clearRepairVo.getExceptionList().size()!=0){
            clearRepairVo.getExceptionList().forEach(
                    repairDetail -> {
                        if (billVoMap.containsKey(repairDetail.getDeviceId())){
                            BillVo billVo=billVoMap.get(repairDetail.getDeviceId());
                            billVo.setDeviceStatusDescription("设备已送往"+repairDetail.getLocationUnit());
                            billVoMap.put(repairDetail.getDeviceId(),billVo);
                        }else {
                            throw new ApiException("[中止任务] billVoMap未找到对应key："+repairDetail.getDeviceId());
                        }
                    }
            );
            suspensionBill.setISNotCommitDes("存在设备所在单位是省外");
            suspensionBill.setIsEnd(false);
        }
        if (clearRepairVo.getEndRepairList().size()!=0){
            clearRepairVo.getEndRepairList().forEach(
                    repairDetail -> {
                        if (billVoMap.containsKey(repairDetail.getDeviceId())){
                            BillVo billVo=billVoMap.get(repairDetail.getDeviceId());
                            billVo.setDeviceStatusDescription("设备在省内单位可中止");
                            billVoMap.put(repairDetail.getDeviceId(),billVo);
                        }else {
                            throw new ApiException("[中止任务] billVoMap未找到对应key："+repairDetail.getDeviceId());
                        }
                    }
            );
        }
        suspensionBill.setBillVoList(new ArrayList<>(billVoMap.values()));
        suspensionBill.setRelatedUnitName(unitsService.findById(suspensionBill.getReceiveUnitId()).getName());
        suspensionBill.setSenderUnitName(unitsService.findById(suspensionBill.getSendUnitId()).getName());
        return suspensionBill;
    }

//
//    private void updateBillVoMapValue(List<RepairDetail> repairDetails,Map<Integer,BillVo> billVoMap,){
//        repairDetails.forEach(
//                repairDetail -> {
//                    if (billVoMap.containsKey(repairDetail.getDeviceId())){
//                        BillVo billVo=billVoMap.get(repairDetail.getDeviceId());
//                        billVo.setDeviceStatusDescription("等待接收-["+repairDetail.getOwnUnit()+"]送修给["+repairDetail.getLocationUnit()+"]");
//                        billVoMap.put(repairDetail.getDeviceId(),billVo);
//                    }else {
//                        throw new ApiException("[中止任务] billVoMap未找到对应key："+repairDetail.getDeviceId());
//                    }
//                }
//        );
//    }


    /**
     *
     */
    private TaskBto createTaskBto(Integer userId,String title,Integer billId,Integer unitId){
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SUSPENSION1500.id, title, null, ".", billId, BusinessEnum.SUSPENSION.id, unitId, 1, "", list));
    }

}
