package com.yunzhupaas.flowable.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.service.SuperServiceImpl;
import com.yunzhupaas.flowable.enums.NodeEnum;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.flowable.entity.*;
import com.yunzhupaas.flowable.mapper.CommentMapper;
import com.yunzhupaas.flowable.util.MsgUtil;
import com.yunzhupaas.flowable.util.ServiceUtil;
import com.yunzhupaas.flowable.util.TaskUtil;
import com.yunzhupaas.flowable.model.comment.CommentPagination;
import com.yunzhupaas.flowable.model.message.FlowMsgModel;
import com.yunzhupaas.flowable.model.task.FlowModel;
import com.yunzhupaas.flowable.model.task.TaskUserListModel;
import com.yunzhupaas.flowable.model.templatenode.nodejson.MsgConfig;
import com.yunzhupaas.flowable.model.templatenode.nodejson.NodeModel;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.flowable.service.CommentService;
import com.yunzhupaas.flowable.service.TaskService;
import com.yunzhupaas.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 流程评论
 *
 * @author 云筑产品开发平台组
 * @version V3.1.0
 * @copyright 深圳市乐程软件有限公司
 */
@Service
public class CommentServiceImpl extends SuperServiceImpl<CommentMapper, CommentEntity> implements CommentService {

    @Autowired
    private MsgUtil msgUtil;
    @Autowired
    private TaskUtil taskUtil;
    @Autowired
    private ServiceUtil serviceUtil;
    @Autowired
    private TaskService taskService;

    @Override
    public List<CommentEntity> getlist(CommentPagination pagination) {
        QueryWrapper<CommentEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CommentEntity::getTaskId, pagination.getTaskId());
        queryWrapper.lambda().isNull(CommentEntity::getDeleteMark);
        queryWrapper.lambda().orderByDesc(CommentEntity::getCreatorTime);
        Page<CommentEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
        IPage<CommentEntity> userIPage = this.page(page, queryWrapper);
        return pagination.setData(userIPage.getRecords(), page.getTotal());
    }

    @Override
    public List<CommentEntity> getList() {
        QueryWrapper<CommentEntity> queryWrapper = new QueryWrapper<>();
        return this.list(queryWrapper);
    }

    @Override
    public List<CommentEntity> getlist(List<String> idList) {
        List<CommentEntity> list = new ArrayList<>();
        if (!idList.isEmpty()) {
            QueryWrapper<CommentEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(CommentEntity::getId, idList);
            list.addAll(this.list(queryWrapper));
        }
        return list;
    }

    @Override
    public CommentEntity getInfo(String id) {
        QueryWrapper<CommentEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CommentEntity::getId, id);
        return this.getOne(queryWrapper);
    }

    @Override
    public void create(CommentEntity entity) throws WorkFlowException {
        entity.setCreatorTime(new Date());
        entity.setCreatorUserId(UserProvider.getUser().getUserId());
        entity.setId(RandomUtil.uuId());
        if (this.save(entity)) {
            this.sendMsg(entity);
        }
    }

    // 发送评论消息
    public void sendMsg(CommentEntity entity) throws WorkFlowException {
        FlowModel flowModel = new FlowModel();
        taskUtil.setFlowModel(entity.getTaskId(), flowModel);
        TaskEntity taskEntity = flowModel.getTaskEntity();
        List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
        TemplateNodeEntity start = nodeEntityList.stream()
                .filter(e -> e.getNodeType().equals(NodeEnum.start.getType())).findFirst().orElse(null);
        if (null == start) {
            return;
        }
        // 开始节点的评论配置
        NodeModel startNode = JsonUtil.getJsonToBean(start.getNodeJson(), NodeModel.class);
        MsgConfig commentMsgConfig = startNode.getCommentMsgConfig();
        if (commentMsgConfig.getOn() != 1 && commentMsgConfig.getOn() != 3) {
            return;
        }

        String text = entity.getText();

        // 不包含@{ 且 回复ID为空（不发消息）
        if (StringUtil.isBlank(text) || !text.contains("@{") && StringUtil.isBlank(entity.getReplyId())) {
            return;
        }

        List<String> userIds = new ArrayList<>();

        // 回复的人
        if (StringUtil.isNotEmpty(entity.getReplyId())) {
            CommentEntity reply = this.getInfo(entity.getReplyId());
            if (reply != null) {
                userIds.add(reply.getCreatorUserId());
            }
        }

        String regex = "@\\{([^}]*)\\}";

        Pattern pattern = Pattern.compile(regex);

        List<String> userNameList = new ArrayList<>();

        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            String group = matcher.group();
            userNameList.add(group.substring(2, group.length() - 1));
        }

        // 获取@的人的account
        List<String> accountList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userNameList)) {
            for (String userName : userNameList) {
                String[] split = userName.split("/");
                if (split.length >= 2) {
                    String account = split[split.length - 1];
                    accountList.add(account);
                }
            }
        }

        List<UserEntity> userList = serviceUtil.getUserByAccount(accountList.stream().distinct().collect(Collectors.toList()));

        List<String> ids = userList.stream().map(UserEntity::getId).collect(Collectors.toList());
        userIds.addAll(ids);

        // 过滤自己
        String userId = UserProvider.getLoginUserId();
        userIds = userIds.stream().filter(e -> !e.equals(userId)).distinct().collect(Collectors.toList());

        if (userIds.isEmpty()) {
            return;
        }

        List<OperatorEntity> operatorList = new ArrayList<>();
        List<CirculateEntity> circulateList = new ArrayList<>();

        List<String> userIdList = new ArrayList<>(userIds);

        TaskUserListModel model = taskService.getTaskUserList(taskEntity.getId());

        // 经办
        for (OperatorEntity operator : model.getOperatorList()) {
            String handleId = operator.getHandleId();
            if (userIdList.contains(handleId)) {
                operatorList.add(operator);
                userIdList.remove(handleId);
            }
        }

        // 抄送
        if (!userIdList.isEmpty()) {
            for (CirculateEntity circulate : model.getCirculateList()) {
                String circulateUserId = circulate.getUserId();
                if (userIdList.contains(circulateUserId)) {
                    circulateList.add(circulate);
                    userIdList.remove(circulateUserId);
                }
            }
        }

        // 发起人
        boolean startHandleId = false;
        if (!userIdList.isEmpty()) {
            if (userIdList.contains(taskEntity.getCreatorUserId())) {
                startHandleId = true;
            }
        }

        // 消息
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setNodeList(flowModel.getNodeEntityList());
        flowMsgModel.setCirculateList(circulateList);
        flowMsgModel.setFlowModel(flowModel);
        flowMsgModel.setTaskEntity(taskEntity);
        flowMsgModel.setOperatorList(operatorList);
        flowMsgModel.setStartHandId(startHandleId);
        flowMsgModel.setComment(true);
        flowMsgModel.setWait(false);
        msgUtil.message(flowMsgModel);
    }

    @Override
    public void update(String id, CommentEntity entity) {
        entity.setId(id);
        this.updateById(entity);
    }

    @Override
    public void delete(CommentEntity entity, boolean delComment) {
        if (entity != null) {
            UserInfo userInfo = UserProvider.getUser();
            if (delComment) {
                entity.setDeleteShow(1);
            } else {
                entity.setDeleteMark(1);
            }
            entity.setDeleteTime(new Date());
            entity.setDeleteUserId(userInfo.getUserId());
            this.updateById(entity);
        }
    }
}

