package com.foreverwin.mesnac.equip.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreverwin.mesnac.common.constant.Constants;
import com.foreverwin.mesnac.common.enums.HandleEnum;
import com.foreverwin.mesnac.common.helper.NextNumberHelper;
import com.foreverwin.mesnac.common.model.Message;
import com.foreverwin.mesnac.common.service.AnomalyService;
import com.foreverwin.mesnac.common.service.MessageService;
import com.foreverwin.mesnac.common.util.ActiveMQUtil;
import com.foreverwin.mesnac.common.util.StringUtil;
import com.foreverwin.mesnac.equip.mapper.ResourceInspectTaskMapper;
import com.foreverwin.mesnac.equip.mapper.ResourceRepairTaskMapper;
import com.foreverwin.mesnac.equip.model.ResourceInspectTask;
import com.foreverwin.mesnac.equip.model.ResourceInspectTaskSpare;
import com.foreverwin.mesnac.equip.model.ResourceRepairTask;
import com.foreverwin.mesnac.equip.service.ResourceInspectPlanService;
import com.foreverwin.mesnac.equip.service.ResourceInspectTaskSpareService;
import com.foreverwin.mesnac.equip.service.ResourceRepairTaskService;
import com.foreverwin.mesnac.listener.mapper.UsrMapper;
import com.foreverwin.mesnac.meapi.mapper.MessageTypeMapper;
import com.foreverwin.mesnac.meapi.mapper.NcCodeMapper;
import com.foreverwin.mesnac.meapi.mapper.NwaUserMapper;
import com.foreverwin.mesnac.meapi.mapper.UserGroupMapper;
import com.foreverwin.mesnac.meapi.model.DataField;
import com.foreverwin.mesnac.meapi.model.MessageType;
import com.foreverwin.mesnac.meapi.model.NwaUser;
import com.foreverwin.mesnac.meapi.model.UserGroup;
import com.foreverwin.mesnac.meapi.service.DataFieldListService;
import com.foreverwin.mesnac.meapi.service.NcCodeService;
import com.foreverwin.mesnac.meapi.service.NwaUserService;
import com.foreverwin.mesnac.meapi.service.ResrceService;
import com.foreverwin.modular.core.exception.BaseException;
import com.foreverwin.modular.core.exception.BusinessException;
import com.foreverwin.modular.core.util.CommonMethods;
import com.foreverwin.modular.core.util.FrontPage;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 设备报修任务表 服务实现类
 * </p>
 *
 * @author pavel.Liu
 * @since 2021-07-06
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ResourceRepairTaskServiceImpl extends ServiceImpl<ResourceRepairTaskMapper, ResourceRepairTask> implements ResourceRepairTaskService {

    @Autowired
    private NextNumberHelper nextNumberHelper;
    @Autowired
    private ResourceRepairTaskMapper resourceRepairTaskMapper;
    @Autowired
    private ResourceRepairTaskService resourceRepairTaskService;
    @Autowired
    private NcCodeService ncCodeService;
    @Autowired
    private ResourceInspectTaskSpareService resourceInspectTaskSpareService;
    @Autowired
    private ResrceService resrceService;
    @Autowired
    private NwaUserService nwaUserService;
    @Autowired
    private NwaUserMapper nwaUserMapper;
    @Autowired
    private DataFieldListService dataFieldListService;
    @Autowired
    private AnomalyService anomalyService;
    @Autowired
    private ResourceInspectTaskMapper resourceInspectTaskMapper;
    @Autowired
    private ResourceInspectPlanService resourceInspectPlanService;
    @Autowired
    private NcCodeMapper ncCodeMapper;
    @Autowired
    private MessageTypeMapper messageTypeMapper;
    @Autowired
    private UserGroupMapper userGroupMapper;
    @Autowired
    private UsrMapper usrMapper;
    @Autowired
    private ActiveMQUtil activeMQUtil;
    @Autowired
    private MessageService messageService;

    @Override
    public HashMap<String, Object> init() {
        HashMap<String, Object> hashMap = new HashMap<>();
        String site = CommonMethods.getSite();
        //原因分类
        DataField dealWay = new DataField();
        dealWay.setSite(site);
        dealWay.setDataField("REPAIR_DEAL_WAY");
        List<DataField> dealWayList = dataFieldListService.findDataFieldListById(dealWay);
        hashMap.put("REPAIR_DEAL_WAY",dealWayList);
        return hashMap;
    }

    @Override
    public IPage<ResourceRepairTask> selectPage(FrontPage<ResourceRepairTask> frontPage, ResourceRepairTask resourceRepairTask) {
        QueryWrapper<ResourceRepairTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(resourceRepairTask);
        return super.page(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<ResourceRepairTask> selectList(ResourceRepairTask resourceRepairTask) {
        QueryWrapper<ResourceRepairTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(resourceRepairTask);
        return super.list(queryWrapper);
    }

    @Override
    public void deleteRepairTaskList(ResourceRepairTask resourceRepairTask) {
        QueryWrapper<ResourceRepairTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(resourceRepairTask);
        super.remove(queryWrapper);
    }

    @Override
    public void saveRepairTask(ResourceRepairTask resourceRepairTask) {
        String site = resourceRepairTask.getSite();
        // 设备编号
        String resourceNo = resourceRepairTask.getResourceNo();
        String resourceHandle = HandleEnum.RESOURCE.getHandle(site, resourceNo);
        if ( resrceService.getById(resourceHandle) == null ){
            throw BusinessException.build("设备编号错误！！！");
        }
        // 不良代码
        String ncCodeNo = resourceRepairTask.getNcCodeNo();
        if (ncCodeNo != null && !ncCodeNo.equals("")){
            String[] ncSplit = ncCodeNo.split(",");
            for (int i = 0; i < ncSplit.length; i++) {
                String ncCodeHandle = HandleEnum.NC_CODE.getHandle(site, ncSplit[i]);
                if ( ncCodeService.getById(ncCodeHandle) == null ){
                    throw BusinessException.build("不良代码错误！！！");
                }
            }
            String ncCodeDescription = ncCodeMapper.findNcCodeDescriptionByNcCodeList(site,ncSplit);
            resourceRepairTask.setOther(ncCodeDescription);
        }

        // 维修单号、维修HANDLE
        List<String> nextNumber = nextNumberHelper.getNextNumber(site, Constants.RESOURCE_REPAIR_TASK, 1);
        resourceRepairTask.setRepairNo(nextNumber.get(0));
        resourceRepairTask.setHandle(HandleEnum.RESOURCE_REPAIR_TASK.getHandle(site,nextNumber.get(0)));
        // 默认新建状态
        resourceRepairTask.setStatus("401");
        // 创建人、创建时间
        String reportUser = resourceRepairTask.getReportUser();
        if (reportUser == null){
            throw BusinessException.build("提报人不能为空！！！");
        }
        //调用方法，关闭异常单的状态
        String objectBo = resourceRepairTask.getObjectBo();
        if (StringUtils.isNotBlank(objectBo)){
            anomalyService.anomalyReveseRepairShutDown(objectBo);
        }

        resourceRepairTask.setCreateUser(reportUser);
        resourceRepairTask.setCreatedDateTime(LocalDateTime.now());
        resourceRepairTaskService.save(resourceRepairTask);
        this.createAndSendMessage(resourceRepairTask);
    }

    @Override
    public List<ResourceRepairTask> findResourceRepairTaskList(ResourceRepairTask resourceRepairTask) {
        return resourceRepairTaskMapper.findResourceRepairTaskList(resourceRepairTask);
    }

    @Override
    public ResourceRepairTask selOrStartRepairTask(ResourceRepairTask resourceRepairTask) {
        String user = CommonMethods.getUser();
        String site = CommonMethods.getSite();
        // 根据HANDLE查询维修任务
        String handle = resourceRepairTask.getHandle();
        String stopMachine = resourceRepairTask.getStopMachine();
        ResourceRepairTask repairTask = resourceRepairTaskMapper.findResourceRepairTaskByHandleAndSite(site,handle);
        String statusBo = repairTask.getStatus();
        if (repairTask == null){
            throw BusinessException.build("维修任务查询失败！！！");
        }
        String status = resourceRepairTask.getStatus();
        if (statusBo.equals("301")){
            // 根据维修任务HANDEL查询备品清单
            ResourceInspectTaskSpare resourceInspectTaskSpare = new ResourceInspectTaskSpare();
            resourceInspectTaskSpare.setResourceInspectTaskBo(handle);
            List<ResourceInspectTaskSpare> spareList = resourceInspectTaskSpareService.selectList(resourceInspectTaskSpare);
            repairTask.setSpareList(spareList);
        }
        // 判断是否点击开始维修
        if (stopMachine != null && status.equals("501")){
            repairTask.setStatus("501");
            repairTask.setActualStartDate(LocalDateTime.now());
            repairTask.setRepairUsers(user);
            NwaUser userByUserName = nwaUserService.findUserByUserName(user);
            repairTask.setRepairUserName(userByUserName.getFullName());
            resourceRepairTaskService.updateById(repairTask);
            // 修改设备状态---若stopMachie=Y，则状态改为非预定停机
            /*if (stopMachine.equals("Y")){
                String resourceNo = repairTask.getResourceNo();
                resrceService.updateResourceStatus(site, resourceNo ,"5");
            }*/
        }
        return repairTask;
    }

    @Override
    public ResourceRepairTask saveOrUpdateTaskInfo(ResourceRepairTask resourceRepairTask) {
        // 状态、HANDLE
        String status = resourceRepairTask.getStatus();
        String handle = resourceRepairTask.getHandle();
        String user = CommonMethods.getUser();
        LocalDateTime now = LocalDateTime.now();
        ResourceRepairTask repairTask = resourceRepairTaskService.getById(handle);
        String site = repairTask.getSite();
        switch (status){
            case "301":
                List<ResourceInspectTaskSpare> spareList = resourceRepairTask.getSpareList();
                for (ResourceInspectTaskSpare spare:spareList) {
                    spare.setCreateUser(user);
                    spare.setHandle(HandleEnum.RESOURCE_INSPECT_TASK_SPARE.getHandle(site,UUID.randomUUID().toString()));
                    spare.setResourceInspectTaskBo(handle);
                    spare.setCreatedDateTime(now);
                }
                resourceInspectTaskSpareService.saveBatch(spareList);
                repairTask.setSpareList(spareList);
                // 完成时间、维修人员
                repairTask.setActualCompleteDate(now);
                String repairUsers = resourceRepairTask.getRepairUsers();
                String[] split = repairUsers.split(",");
                for (int i = 0; i < split.length; i++) {
                    NwaUser nwaUser = new NwaUser();
                    nwaUser.setUserName(split[i]);
                    if (nwaUserService.selectList(nwaUser).size() < 1){
                        throw BusinessException.build("用户编号" + split[i] + "不存在！");
                    }
                }
                repairTask.setRepairUsers(repairUsers);
                // 处理方式、处理方式描述、初步原因
                repairTask.setDealWay(resourceRepairTask.getDealWay());
                repairTask.setDealWayDescription(resourceRepairTask.getDealWayDescription());
                repairTask.setPreliminaryReason(resourceRepairTask.getPreliminaryReason());
                // 根本原因、根本原因描述、预防措施描述
                repairTask.setPrimaryReason(resourceRepairTask.getPrimaryReason());
                repairTask.setPrimaryReasonDescription(resourceRepairTask.getPrimaryReasonDescription());
                repairTask.setPrecautionMeasureDescription(resourceRepairTask.getPrecautionMeasureDescription());
                // 修改设备状态：判断维修前和维修结束的stopMachie字段是否修改
                /*String stopMachine = resourceRepairTask.getStopMachine();
                String stopMachineT = repairTask.getStopMachine();
                if (!stopMachine.equals(stopMachineT)){
                    String resourceNo = repairTask.getResourceNo();
                    resrceService.updateResourceStatus(site, resourceNo, stopMachineT.equals("N")?"301":"5");
                }*/

                // 创建点检任务：维修完成时，若当前设备当日有点检不通过的任务，则为设备创建新的点检任务；
                ResourceInspectTask resourceInspectTask = new ResourceInspectTask();
                resourceInspectTask.setSite(site);
                resourceInspectTask.setCategory(Constants.INSPECTION_TYPE_DM);
                LocalDate toDay = LocalDate.now();
                LocalDateTime startDate = LocalDateTime.parse(toDay + "T00:00:00");
                LocalDateTime endDate = LocalDateTime.parse(toDay.plusDays(1) + "T00:00:00");
                resourceInspectTask.setPlanStartDate(startDate);
                resourceInspectTask.setPlanCompleteDate(endDate);
                resourceInspectTask.setResrce(resourceRepairTask.getResourceNo());
                List<ResourceInspectTask> inspectTaskList = resourceInspectTaskMapper.getInspectTaskListByCondition(resourceInspectTask);
                Boolean bl = true;
                for (ResourceInspectTask inspectTask:inspectTaskList) {
                    if (Constants.RSESULT_OK.equals(inspectTask.getResult())){
                        bl = false;
                        break;
                    }
                }
                if (bl){
                    for (ResourceInspectTask inspectTask:inspectTaskList) {
                        // 查询到点检结果为NG的设备，创建新的当日点检任务
                        if (Constants.RSESULT_NG.equals(inspectTask.getResult())){
                            String taskNo = inspectTask.getTaskNo();
                            String taskStr = taskNo+now;
                            inspectTask.setTaskNo(taskStr);
                            inspectTask.setHandle(HandleEnum.RESOURCE_INSPECT_TASK.getHandle(site,taskStr));
                            inspectTask.setResult("");
                            inspectTask.setActualCompleteDate(null);
                            inspectTask.setExecutor("");
                            inspectTask.setCreatedDateTime(now);
                            inspectTask.setTaskCreateDate(inspectTask.getTaskCreateDate().plusMinutes(1));
                            inspectTask.setPlanStartDate(now);
                            inspectTask.setActualStartDate(null);
                            inspectTask.setStatus(Constants.INSPECTION_TASK_STATUS_NEW);
                            inspectTask.setModifyUser(null);
                            inspectTask.setModifiedDateTime(null);
                            resourceInspectTaskMapper.insert(inspectTask);
                            break;
                        }
                    }
                }
                break;
            case "302":
                // 取消代码、取消描述、取消时间、取消人员
                repairTask.setCancelCode(resourceRepairTask.getCancelCode());
                repairTask.setCancelDescription(resourceRepairTask.getCancelDescription());
                repairTask.setCancelDate(now);
                repairTask.setCancelUser(user);
                NwaUser userByUserName = nwaUserService.findUserByUserName(user);
                repairTask.setCancelUserName(userByUserName.getFullName());
                break;
            case "502":
                if (repairTask.getWaitStartDate() != null){
                    throw BusinessException.build("已有等待记录，不能再次进入等待状态！！！");
                }else {
                    repairTask.setWaitStartDate(now);
                    repairTask.setWaitDescription(resourceRepairTask.getWaitDescription());
                }
                break;
            case "501":
                // 结束时间、等待时长
                repairTask.setWaitEndDate(now);
                Duration betweenTime = Duration.between(repairTask.getWaitStartDate(), repairTask.getWaitEndDate());
                Long waitMinutes = betweenTime.toMinutes();
                double waitHours = waitMinutes.doubleValue()/60.00;
                repairTask.setWaitTime(waitHours);
                break;
        }
        // 状态、修改人、修改时间
        repairTask.setStatus(status);
        repairTask.setModifyUser(user);
        repairTask.setModifiedDateTime(now);
        resourceRepairTaskService.saveOrUpdate(repairTask);
        return repairTask;
    }

    @Override
    public ResourceRepairTask findResourceRepairTaskByHandleAndSite(String site, String handle) {
        ResourceRepairTask repairTask = resourceRepairTaskMapper.findResourceRepairTaskByHandleAndSite(site, handle);
        if (repairTask == null){
            throw BusinessException.build("未找到维修单数据！");
        }
        // 耗用备品
        ResourceInspectTaskSpare taskSpare = new ResourceInspectTaskSpare();
        taskSpare.setResourceInspectTaskBo(handle);
        List<ResourceInspectTaskSpare> spareList = resourceInspectTaskSpareService.selectList(taskSpare);
        if (spareList != null && spareList.size() > 0){
            repairTask.setSpareList(spareList);
        }
        // 维修用户的中文名称
        String repairUsers = repairTask.getRepairUsers();
        if (repairUsers != null && !repairUsers.equals("")){
            String[] split = repairUsers.split(",");
            if (split.length > 0){
                List<String> list = Arrays.asList(split);
                String userNameList = nwaUserMapper.getFullNameCommaByUserNameList(site, list);
                repairTask.setRepairUserName(userNameList);
            }
        }
        return repairTask;
    }

    @Override
    public Boolean updateResourceRepairTaskInfoByHandle(ResourceRepairTask resourceRepairTask) {
        // 记录日志
        String repairHandle = resourceRepairTask.getHandle();
        ResourceRepairTask byId = resourceRepairTaskService.getById(repairHandle);
        Integer cnt = resourceRepairTaskMapper.selRepairTaskLogByHandle(repairHandle);
        if (cnt < 1){
            resourceRepairTaskMapper.insertRepairTaskLog(byId);
        }
        String user = CommonMethods.getUser();
        String site = CommonMethods.getSite();
        String handle = resourceRepairTask.getHandle();
        // 备品信息，全删全增
        ResourceInspectTaskSpare resourceInspectTaskSpare = new ResourceInspectTaskSpare();
        resourceInspectTaskSpare.setResourceInspectTaskBo(handle);
        resourceInspectTaskSpareService.removeAll(resourceInspectTaskSpare);
        List<ResourceInspectTaskSpare> spareList = resourceRepairTask.getSpareList();
        for (ResourceInspectTaskSpare spare:spareList) {
            if (spare.getCreateUser() != null){
                spare.setModifyUser(user);
                spare.setModifiedDateTime(LocalDateTime.now());
            }else {
                spare.setCreateUser(user);
                spare.setCreatedDateTime(LocalDateTime.now());
            }
            spare.setResourceInspectTaskBo(handle);
            spare.setHandle(HandleEnum.RESOURCE_INSPECT_TASK_SPARE.getHandle(site,UUID.randomUUID().toString()));
        }
        resourceInspectTaskSpareService.saveBatch(spareList);
        return resourceRepairTaskService.updateById(resourceRepairTask);
    }

    @Override
    public void createAndSendMessage(ResourceRepairTask resourceRepairTask) {
        String site = CommonMethods.getSite();
        String user = CommonMethods.getUser();
        LocalDateTime now = LocalDateTime.now();
        Message message = new Message();
        message.setHandle(UUID.randomUUID().toString());
        message.setSite(site);
        message.setObjectBo(resourceRepairTask.getHandle());
        message.setType(Constants.REPAIR_TYPE);
        //根据用户组找到对应的消息内容
        MessageType messageType = messageTypeMapper.findMessageTypeByUserGroup(site,  resourceRepairTask.getAnother());
        if(messageType == null){
            throw new BaseException("根据发送的用户组找不到对应的消息类型，请维护。");
        }
        message.setMessageType(messageType.getMessageType());
        message.setSendUserGroup(resourceRepairTask.getAnother());
        //格式化消息内容
        String messageContent = this.formatMessage(resourceRepairTask, messageType.getMessageType(), site);
        message.setContent(messageContent);
        message.setResponseDateTime(LocalDateTime.now());

       // message.setUpUserGroup(message.getSendUserGroup()+"_SJ");
        //得到升级的时间和等级
        UserGroup customFieldByGroup = userGroupMapper.getCustomFieldByGroup(site, message.getSendUserGroup());
//        if(customFieldByGroup != null && !StringUtil.isBlank(customFieldByGroup.getMessageNoticeTime())){
//            message.setUpDateTime(message.getResponseDateTime().plusMinutes(Integer.parseInt(customFieldByGroup.getMessageNoticeTime())));
//        }else{
//            throw new BaseException("该用户组没有维护升级的时间，请维护。");
//        }

        if(customFieldByGroup != null && !StringUtil.isBlank(customFieldByGroup.getMessageNoticeLevel())){
            message.setGrade(Double.parseDouble(customFieldByGroup.getMessageNoticeLevel()));
        }else{
            throw new BaseException("该用户组没有维护等级，请维护。");
        }
//        MessageType messageTypeUp = messageTypeMapper.findMessageTypeByUserGroup(site, message.getUpUserGroup());
//        //得到升级的消息类型
//        if(messageTypeUp == null){
//            throw new BaseException("用户组"+message.getSendUserGroup()+"的升级用户没有维护消息类型");
//        }
//        message.setUpMessageType(messageTypeUp.getMessageType());
        message.setNode(Constants.RESOURCE_REPAIR_MESSAGE_REPORT);

        message.setStatus("Y");
        message.setCreatedUser(user);
        message.setCreatedDateTime(now);
        message.setModifiedUser(user);
        message.setModifiedDateTime(now);


        //发送消息
        List<NwaUser> nwaUsers  = nwaUserService.checkUserGroup(site,message.getSendUserGroup());
        if(nwaUsers != null && nwaUsers.size() <= 0){
            throw new BaseException("消息发送失败，发送的用户组下面没有用户");
        }
        List<String> customFieldByUserId = usrMapper.findCustomFieldByUserId(site, nwaUsers);
        if(customFieldByUserId != null && customFieldByUserId.size() <= 0){
            throw new BaseException("消息发送失败，发送的用户组下面的用户的自定义数据没有维护");
        }
        StringBuilder sendUsers = new StringBuilder();
        for (int i = 0; i < Objects.requireNonNull(customFieldByUserId).size(); i++) {
            if(i == (customFieldByUserId.size() - 1)){
                sendUsers.append(customFieldByUserId.get(i));
            }else{
                sendUsers.append(customFieldByUserId.get(i)).append("|");
            }
        }
        activeMQUtil.wechatSendMessage(sendUsers.toString(),message.getContent());
        messageService.saveOrUpdate(message);
    }

    @Override
    public String formatMessage(ResourceRepairTask resourceRepairTask, String messageType, String site) {
        /*
         * 找到对应的消息内容
         */
        MessageType messageTypeEntity = new MessageType();
        messageTypeEntity.setSite(site);
        messageTypeEntity.setMessageType(messageType);
        QueryWrapper<MessageType> messageTypeQueryWrapper = new QueryWrapper<MessageType>();
        messageTypeQueryWrapper.setEntity(messageTypeEntity);
        MessageType sendMessageType = messageTypeMapper.selectOne(messageTypeQueryWrapper);
        if(sendMessageType == null){
            throw new BaseException("维修提报找不到要发送的消息类型");
        }

        /**
         * 把消息内容中，对应的map的key替换为  resourceRepairTask中对应的字段（变量）
         */
        Map<String, String> replaceMessageMap = resourceRepairTaskMapper.findReplaceMessageByResourceRepairTask(resourceRepairTask);
        String messageBody = sendMessageType.getBody();
        //格式化之后的消息
        return com.foreverwin.mesnac.meapi.util.StringUtils.format(messageBody, replaceMessageMap);
    }


}