package com.yunzhupaas.flowable.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
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.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.common.collect.ImmutableList;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.entity.DictionaryDataEntity;
import com.yunzhupaas.base.entity.VisualdevEntity;
import com.yunzhupaas.base.service.SuperServiceImpl;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.flowable.entity.*;
import com.yunzhupaas.flowable.enums.NodeEnum;
import com.yunzhupaas.flowable.mapper.TemplateMapper;
import com.yunzhupaas.flowable.model.template.*;
import com.yunzhupaas.flowable.model.templatejson.FlowFormModel;
import com.yunzhupaas.flowable.model.templatejson.TemplateJsonExportModel;
import com.yunzhupaas.flowable.model.templatenode.TemplateNodeUpFrom;
import com.yunzhupaas.flowable.service.*;
import com.yunzhupaas.flowable.util.ServiceUtil;
import com.yunzhupaas.flowable.util.TaskUtil;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.RandomUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class TemplateServiceImpl extends SuperServiceImpl<TemplateMapper, TemplateEntity> implements TemplateService {

    @Autowired
    private TemplateJsonService templateJsonService;
    @Autowired
    private TemplateNodeService templateNodeService;
    @Autowired
    private ServiceUtil serviceUtil;
    @Autowired
    private DelegateService delegateService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private TaskUtil taskUtil;
    @Autowired
    private TriggerTaskService triggerTaskService;

    @Override
    public List<TemplateEntity> getList(TemplatePagination pagination) {
        QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
        String keyword = pagination.getKeyword();
        if (ObjectUtil.isNotEmpty(keyword)) {
            queryWrapper.lambda().and(t -> t.like(TemplateEntity::getEnCode, keyword).or().like(TemplateEntity::getFullName, keyword));
        }
        String category = pagination.getCategory();
        if (ObjectUtil.isNotEmpty(category)) {
            queryWrapper.lambda().eq(TemplateEntity::getCategory, category);
        }
        Integer type = pagination.getType();
        if (ObjectUtil.isNotEmpty(type)) {
            queryWrapper.lambda().eq(TemplateEntity::getType, type);
        }
        Integer enabledMark = pagination.getEnabledMark();
        if (ObjectUtil.isNotEmpty(enabledMark)) {
            queryWrapper.lambda().eq(TemplateEntity::getEnabledMark, enabledMark);
        }
        queryWrapper.lambda().orderByAsc(TemplateEntity::getSortCode).orderByDesc(TemplateEntity::getCreatorTime);
        Page<TemplateEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
        IPage<TemplateEntity> userPage = this.page(page, queryWrapper);
        return pagination.setData(userPage.getRecords(), page.getTotal());
    }

    @Override
    public List<TemplatePageVo> getSelector(TemplatePagination pagination) {
        // 流程权限
        List<String> flowId = new ArrayList<>();
        List<String> id = new ArrayList<>();
        String userId = UserProvider.getLoginUserId();
        if (StringUtil.isNotBlank(pagination.getDelegateUser())) {
            userId = pagination.getDelegateUser();
        }
        // 权限
        boolean commonUser = serviceUtil.isCommonUser(userId);
        // 是否委托列表
        if (ObjectUtil.equals(pagination.getIsDelegate(), 1)) {
            if (commonUser) {
                flowId.addAll(serviceUtil.getLaunchPermission(userId));
            }
        } else {
            if (ObjectUtil.equals(pagination.getIsAuthority(), 1)) {
                if (commonUser) {
                    flowId.addAll(serviceUtil.getLaunchPermission(userId));
                }
                // 委托
                List<DelegateEntity> delegateEntityList = delegateService.getByToUserId(userId, 0);
                for (DelegateEntity delegate : delegateEntityList) {
                    List<String> launchPermission = serviceUtil.getLaunchPermission(delegate.getUserId());
                    if (StringUtil.isNotEmpty(delegate.getFlowId())) {
                        launchPermission.retainAll(Arrays.asList(delegate.getFlowId().split(",")));
                    }
                    id.addAll(launchPermission);
                }
                flowId.addAll(id);
                flowId = flowId.stream().distinct().collect(Collectors.toList());
            }
        }

        MPJLambdaWrapper<TemplateEntity> wrapper = JoinWrappers.lambda(TemplateEntity.class)
                .selectAll(TemplateEntity.class)
                .eq(TemplateEntity::getEnabledMark, 1).ne(TemplateEntity::getType, 2)
                .eq(TemplateEntity::getStatus, 1);
        if (ObjectUtil.equals(pagination.getIsLaunch(), 1)) {
            wrapper.in(TemplateEntity::getShowType, 0, 1);
        }

        if (ObjectUtil.equals(pagination.getIsAuthority(), 1)) {
            if (commonUser) {
                List<String> finalFlowId = flowId;
                wrapper.and(t -> t.eq(TemplateEntity::getVisibleType, 1)
                        .or().in(!finalFlowId.isEmpty(), TemplateEntity::getId, finalFlowId)
                );
            }
        }

        //关键字（流程名称、流程编码）
        String keyWord = pagination.getKeyword();
        if (ObjectUtil.isNotEmpty(keyWord)) {
            wrapper.and(t -> t.like(TemplateEntity::getEnCode, keyWord).or().like(TemplateEntity::getFullName, keyWord));
        }
        //所属分类
        String category = pagination.getCategory();
        if (ObjectUtil.isNotEmpty(category)) {
            if (StringUtil.equals(category, "commonFlow")) {
                wrapper.leftJoin(CommonEntity.class, CommonEntity::getFlowId, TemplateJsonEntity::getId)
                        .eq(CommonEntity::getCreatorUserId, userId).isNotNull(CommonEntity::getFlowId);
            } else {
                wrapper.in(TemplateEntity::getCategory, category.split(","));
            }
        }
        wrapper.orderByAsc(TemplateEntity::getSortCode).orderByDesc(TemplateEntity::getCreatorTime);
        Page<TemplatePageVo> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
        IPage<TemplatePageVo> userPage = this.selectJoinListPage(page, TemplatePageVo.class, wrapper);

        List<TemplatePageVo> records = userPage.getRecords();
        // 设置常用流程标识
        List<CommonEntity> commonList = commonService.getCommonByUserId(userId);
        if (CollectionUtil.isNotEmpty(commonList)) {
            List<String> flowIds = commonList.stream().map(CommonEntity::getFlowId).distinct().collect(Collectors.toList());
            for (TemplatePageVo record : records) {
                if (flowIds.contains(record.getId())) {
                    record.setIsCommonFlow(true);
                }
            }
        }
        return pagination.setData(records, page.getTotal());
    }

    @Override
    public List<TemplateTreeListVo> getTreeCommon() {
        String userId = UserProvider.getLoginUserId();
        List<TemplateTreeListVo> vos = new ArrayList<>();
        List<CommonEntity> commonList = commonService.getCommonByUserId(userId);
        if (CollectionUtil.isEmpty(commonList)) {
            return vos;
        }
        List<String> flowIds = commonList.stream().map(CommonEntity::getFlowId).collect(Collectors.toList());
        List<TemplateEntity> templateList = this.getList(flowIds);

        if (CollectionUtil.isNotEmpty(templateList)) {
            TemplateTreeListVo allVo = new TemplateTreeListVo();
            allVo.setId(RandomUtil.uuId());
            allVo.setFullName("全部流程");
            List<TemplateTreeListVo> childrenList = this.getChildren(templateList);
            allVo.setChildren(childrenList);
            vos.add(allVo);

            Map<String, List<TemplateTreeListVo>> map = childrenList.stream().collect(Collectors.groupingBy(TemplateTreeListVo::getCategory));
            List<String> categoryIds = map.keySet().stream().collect(Collectors.toList());

            List<DictionaryDataEntity> dictionNameList = serviceUtil.getDictionName(categoryIds);
            for (DictionaryDataEntity dict : dictionNameList) {
                TemplateTreeListVo vo = new TemplateTreeListVo();
                vo.setId(dict.getId());
                vo.setFullName(dict.getFullName());
                vo.setChildren(map.get(dict.getId()));
                vos.add(vo);
            }
        }
        return vos;
    }

    public List<TemplateTreeListVo> getChildren(List<TemplateEntity> templates) {
        List<TemplateTreeListVo> resList = new ArrayList<>();
        for (TemplateEntity template : templates) {
            TemplateTreeListVo vo = JsonUtil.getJsonToBean(template, TemplateTreeListVo.class);
            resList.add(vo);
        }
        return resList;
    }

    @Override
    public List<TemplateTreeListVo> treeList(Integer formType) {
        List<DictionaryDataEntity> dictionList = serviceUtil.getDiList();

        TemplatePagination pagination = new TemplatePagination();
        List<TemplateEntity> list = getListAll(pagination, false);

        List<TemplateNodeEntity> startNodeList;
        // formType 1.系统表单  2.在线开发表单
        if (null != formType) {
            // 版本主键
            List<String> flowIds = list.stream().map(TemplateEntity::getFlowId).collect(Collectors.toList());
            startNodeList = templateNodeService.getList(flowIds, NodeEnum.start.getType());
        } else {
            startNodeList = new ArrayList<>();
        }
        List<String> formIds = startNodeList.stream().map(TemplateNodeEntity::getFormId).collect(Collectors.toList());
        List<VisualdevEntity> formList = serviceUtil.getFormList(formIds);

        List<TemplateTreeListVo> vos = new ArrayList<>();

        for (DictionaryDataEntity dict : dictionList) {
            TemplateTreeListVo vo = new TemplateTreeListVo();
            vo.setFullName(dict.getFullName());
            vo.setId(dict.getId());
            vo.setDisabled(true);
            if (CollectionUtil.isNotEmpty(list)) {
                List<TemplateEntity> childList = list.stream()
                        .filter(e -> dict.getId().equals(e.getCategory())).collect(Collectors.toList());

                if (null != formType) {
                    childList = childList.stream().filter(e -> {
                        // 是流程显示类型
                        if (ObjectUtil.equals(e.getShowType(), 1)) {
                            return false;
                        }
                        TemplateNodeEntity node = startNodeList.stream().filter(a -> a.getFlowId().equals(e.getFlowId())).findFirst().orElse(null);
                        if (null != node) {
                            VisualdevEntity form = formList.stream().filter(b -> b.getId().equals(node.getFormId())).findFirst().orElse(null);
                            if (null != form) {
                                return form.getType().equals(1);
                            }
                        }
                        return false;
                    }).collect(Collectors.toList());
                }

                if (CollectionUtil.isNotEmpty(childList)) {
                    childList = childList.stream()
                            .sorted(Comparator.comparing(TemplateEntity::getSortCode, Comparator.nullsLast(Comparator.naturalOrder())).thenComparing(TemplateEntity::getCreatorTime).reversed())
                            .collect(Collectors.toList());
                    vo.setNum(childList.size());
                    vo.setChildren(JsonUtil.getJsonToList(childList, TemplateTreeListVo.class));
                    vos.add(vo);
                }
            }
        }
        return vos;
    }

    @Override
    public List<TemplateTreeListVo> treeListWithPower() {
        List<TemplateTreeListVo> vos = new ArrayList<>();

        MPJLambdaWrapper<TemplateEntity> wrapper = JoinWrappers.lambda(TemplateEntity.class)
                .selectAll(TemplateEntity.class)
                .eq(TemplateEntity::getVisibleType, 2)
                .isNotNull(TemplateEntity::getFlowId);

        List<TemplateEntity> list = this.selectJoinList(TemplateEntity.class, wrapper);
        List<String> categoryList = list.stream().map(TemplateEntity::getCategory).collect(Collectors.toList());
        List<DictionaryDataEntity> dictionList = serviceUtil.getDictionName(categoryList);
        for (DictionaryDataEntity dict : dictionList) {
            TemplateTreeListVo vo = new TemplateTreeListVo();
            vo.setFullName(dict.getFullName());
            vo.setId(dict.getId());
            vo.setDisabled(true);
            if (CollectionUtil.isNotEmpty(list)) {
                List<TemplateEntity> childList = list.stream()
                        .filter(e -> dict.getId().equals(e.getCategory()))
                        .sorted(Comparator.comparing(TemplateEntity::getSortCode, Comparator.nullsLast(Comparator.naturalOrder())).thenComparing(TemplateEntity::getCreatorTime, Comparator.reverseOrder()))
                        .collect(Collectors.toList());

                if (CollectionUtil.isNotEmpty(childList)) {
                    vo.setNum(childList.size());
                    vo.setChildren(JsonUtil.getJsonToList(childList, TemplateTreeListVo.class));
                    vos.add(vo);
                }
            }
        }

        return vos;
    }

    @Override
    public List<TemplateEntity> getListAll(TemplatePagination pagination, boolean isPage) {
        // 定义变量判断是否需要使用修改时间倒序
        boolean flag = false;
        QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TemplateEntity::getEnabledMark, 1).eq(TemplateEntity::getStatus, 1);
        if (ObjectUtil.isNotEmpty(pagination.getType())) {
            flag = true;
            queryWrapper.lambda().eq(TemplateEntity::getType, pagination.getType());
        }
        if (ObjectUtil.isNotEmpty(pagination.getKeyword())) {
            flag = true;
            queryWrapper.lambda().like(TemplateEntity::getFullName, pagination.getKeyword());
        }
        if (ObjectUtil.isNotEmpty(pagination.getCategory())) {
            flag = true;
            queryWrapper.lambda().eq(TemplateEntity::getCategory, pagination.getCategory());
        }
        if (ObjectUtil.isNotEmpty(pagination.getTemplateIdList())) {
            queryWrapper.lambda().in(TemplateEntity::getId, pagination.getTemplateIdList());
        }
        queryWrapper.lambda().orderByAsc(TemplateEntity::getSortCode).orderByDesc(TemplateEntity::getCreatorTime);
        if (flag) {
            queryWrapper.lambda().orderByDesc(TemplateEntity::getLastModifyTime);
        }
        queryWrapper.lambda().select(
                TemplateEntity::getId, TemplateEntity::getEnCode,
                TemplateEntity::getFullName,
                TemplateEntity::getFlowId,
                TemplateEntity::getStatus, TemplateEntity::getShowType,
                TemplateEntity::getType, TemplateEntity::getIcon,
                TemplateEntity::getCategory, TemplateEntity::getIconBackground,
                TemplateEntity::getCreatorUserId, TemplateEntity::getSortCode,
                TemplateEntity::getEnabledMark, TemplateEntity::getCreatorTime
        );
        if (isPage) {
            Page<TemplateEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
            IPage<TemplateEntity> userPage = this.page(page, queryWrapper);
            return pagination.setData(userPage.getRecords(), page.getTotal());
        } else {
            return this.list(queryWrapper);
        }
    }

    @Override
    public List<TemplateEntity> getListByFlowIds(List<String> flowIds) {
        List<TemplateEntity> list = new ArrayList<>();
        List<TemplateJsonEntity> jsonEntityList = templateJsonService.listByIds(flowIds);
        if (CollectionUtil.isNotEmpty(jsonEntityList)) {
            List<String> templateIds = jsonEntityList.stream().map(TemplateJsonEntity::getTemplateId).distinct().collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(templateIds)) {
                QueryWrapper<TemplateEntity> wrapper = new QueryWrapper<>();
                wrapper.lambda().in(TemplateEntity::getId, templateIds).eq(TemplateEntity::getStatus, 1);
                list = this.list(wrapper);
            }
        }
        return list;
    }

    @Override
    public TemplateEntity getInfo(String id) throws WorkFlowException {
        QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TemplateEntity::getId, id);
        TemplateEntity templateEntity = this.getOne(queryWrapper);
        if (templateEntity == null) {
            throw new WorkFlowException(MsgCode.WF122.get());
        }
        return templateEntity;
    }

    @Override
    public boolean isExistByFullName(String fullName, String id) {
        QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TemplateEntity::getFullName, fullName);
        if (!StringUtils.isEmpty(id)) {
            queryWrapper.lambda().ne(TemplateEntity::getId, id);
        }
        return this.count(queryWrapper) > 0 ? true : false;
    }

    @Override
    public boolean isExistByEnCode(String enCode, String id) {
        QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TemplateEntity::getEnCode, enCode);
        if (!StringUtils.isEmpty(id)) {
            queryWrapper.lambda().ne(TemplateEntity::getId, id);
        }
        return this.count(queryWrapper) > 0 ? true : false;
    }

    @Override
    public void create(TemplateEntity entity, String flowXml, Map<String, Map<String, Object>> flowNodes) throws WorkFlowException {
        if (isExistByFullName(entity.getFullName(), entity.getId())) {
            throw new WorkFlowException(MsgCode.EXIST001.get());
        }
        if (isExistByEnCode(entity.getEnCode(), entity.getId())) {
            throw new WorkFlowException(MsgCode.EXIST002.get());
        }
        UserInfo userInfo = UserProvider.getUser();
        entity.setId(StringUtil.isNotEmpty(entity.getId()) ? entity.getId() : RandomUtil.uuId());
        entity.setCreatorUserId(userInfo.getUserId());
        entity.setCreatorTime(new Date());
        entity.setFlowId(null);
        entity.setEnabledMark(0);
        entity.setStatus(0);
        entity.setLastModifyUserId(null);
        entity.setLastModifyTime(null);
        this.setIgnoreLogicDelete().removeById(entity.getId());
        this.setIgnoreLogicDelete().saveOrUpdate(entity);
        this.clearIgnoreLogicDelete();
        TemplateNodeUpFrom from = new TemplateNodeUpFrom();
        from.setId(entity.getId());
        from.setFlowXml(flowXml);
        from.setFlowNodes(flowNodes);
        templateJsonService.create(from);
    }

    @Override
    public boolean update(String id, TemplateEntity entity) throws WorkFlowException {
        if (isExistByFullName(entity.getFullName(), id)) {
            throw new WorkFlowException(MsgCode.EXIST001.get());
        }
        if (isExistByEnCode(entity.getEnCode(), id)) {
            throw new WorkFlowException(MsgCode.EXIST002.get());
        }
        entity.setId(id);
        return this.updateById(entity);
    }

    @Override
    public void delete(TemplateEntity entity) throws WorkFlowException {
        if (entity != null) {
            if (ObjectUtil.equals(entity.getType(), 2)) {
                List<TemplateJsonEntity> list = templateJsonService.getList(entity.getId());
                List<String> flowIds = list.stream().map(TemplateJsonEntity::getId).collect(Collectors.toList());
                if (triggerTaskService.checkByFlowIds(flowIds)) {
                    throw new WorkFlowException(MsgCode.WF139.get());
                }
            } else {
                List<TaskEntity> taskList = taskUtil.getTaskByTemplate(entity.getId());
                if (CollectionUtil.isNotEmpty(taskList)) {
                    throw new WorkFlowException(MsgCode.WF124.get());
                }
            }
            this.removeById(entity.getId());
            List<String> idList = templateJsonService.getList(entity.getId()).stream().map(TemplateJsonEntity::getId).collect(Collectors.toList());
            templateJsonService.delete(idList);
        }
    }

    @Override
    public void copy(TemplateEntity entity) throws WorkFlowException {
        try {
            TemplateJsonEntity jsonEntity = StringUtil.isNotEmpty(entity.getFlowId()) ? templateJsonService.getInfo(entity.getFlowId()) : null;
            String formXml = jsonEntity != null ? jsonEntity.getFlowXml() : null;
            List<TemplateNodeEntity> list = jsonEntity != null ? templateNodeService.getList(jsonEntity.getId()) : new ArrayList<>();
            String copyNum = UUID.randomUUID().toString().substring(0, 5);
            entity.setFullName(entity.getFullName() + ".副本" + copyNum);
            entity.setEnCode(entity.getEnCode() + copyNum);
            entity.setId(null);
            Map<String, Map<String, Object>> flowNodes = new HashMap<>();
            for (TemplateNodeEntity nodeEntity : list) {
                flowNodes.put(nodeEntity.getNodeCode(), JsonUtil.stringToMap(nodeEntity.getNodeJson()));
            }
            this.create(entity, formXml, flowNodes);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new WorkFlowException(MsgCode.PRI006.get());
        }
    }

    @Override
    public TemplateExportModel export(String id) throws WorkFlowException {
        TemplateEntity entity = getInfo(id);
        TemplateExportModel exportModel = new TemplateExportModel();
        exportModel.setTemplate(entity);
        // 版本
        TemplateJsonEntity jsonEntity = templateJsonService.getInfo(entity.getFlowId());
        TemplateJsonExportModel versionModel = JsonUtil.getJsonToBean(jsonEntity, TemplateJsonExportModel.class);
        // 节点
        List<TemplateNodeEntity> list = templateNodeService.getList(entity.getFlowId());
        exportModel.setNodeList(list);
        exportModel.setFlowVersion(versionModel);
        return exportModel;
    }

    @Override
    public void importData(TemplateExportModel model, String type) throws WorkFlowException {
        TemplateEntity entity = model.getTemplate();
        TemplateJsonExportModel versionModel = model.getFlowVersion();
        if (null != entity) {
            entity.setFlowId(null);
            entity.setVersion(null);
            entity.setCreatorUserId(UserProvider.getLoginUserId());
            entity.setCreatorTime(new Date());
            entity.setLastModifyTime(null);
            entity.setLastModifyUserId(null);
            entity.setEnabledMark(0);

            List<String> errList = new ArrayList<>();
            // type: 0.当导入数据不存在，作为新数据导入；数据已存在，不做处理  1.当导入数据已存在，增加相同记录新数据，名称和编码自动增加随机码
            TemplateEntity templateEntity = checkImportEntity(entity, type, errList);

            if (!errList.isEmpty()) {
                StringJoiner joiner = new StringJoiner("；");
                joiner.add(String.join("、", errList) + "重复");
                if (StringUtil.isNotEmpty(joiner.toString())) {
                    throw new WorkFlowException(joiner.toString());
                }
            }
            Map<String, Map<String, Object>> flowNodes = new HashMap<>();
            for (TemplateNodeEntity nodeEntity : model.getNodeList()) {
                flowNodes.put(nodeEntity.getNodeCode(), JsonUtil.stringToMap(nodeEntity.getNodeJson()));
            }
            this.create(templateEntity, versionModel.getFlowXml(), flowNodes);
        }
    }

    @Override
    public List<TemplateEntity> getList(List<String> ids) {
        if (ids.isEmpty()) {
            return new ArrayList<>();
        }
        QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(TemplateEntity::getId, ids).eq(TemplateEntity::getStatus, 1);
        return this.list(queryWrapper);
    }

    @Override
    public List<TemplateEntity> getListOfHidden(List<String> ids) {
        if (ids.isEmpty()) {
            return new ArrayList<>();
        }
        QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(TemplateEntity::getId, ids).in(TemplateEntity::getStatus, 1, 2);
        return this.list(queryWrapper);
    }

    // 校验导入的实体
    public TemplateEntity checkImportEntity(TemplateEntity templateEntity, String type, List<String> errList) {
        TemplateEntity entity = JsonUtil.getJsonToBean(templateEntity, TemplateEntity.class);
        boolean skip = Objects.equals("0", type);
        int num = 0;
        QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TemplateEntity::getId, entity.getId());
        if (this.count(queryWrapper) > 0) {
            num++;
            if (skip) {
                errList.add("ID");
            }
        }
        queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TemplateEntity::getEnCode, entity.getEnCode());
        if (this.count(queryWrapper) > 0) {
            num++;
            if (skip) {
                errList.add("编码");
            }
        }
        queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TemplateEntity::getFullName, entity.getFullName());
        if (this.count(queryWrapper) > 0) {
            num++;
            if (skip) {
                errList.add("名称");
            }
        }
        if (num > 0 && !skip) {
            String copyNum = UUID.randomUUID().toString().substring(0, 5);
            entity.setFullName(entity.getFullName() + ".副本" + copyNum);
            entity.setEnCode(entity.getEnCode() + copyNum);
        }
        entity.setId(RandomUtil.uuId());
        return entity;
    }

    @Override
    public FlowByFormModel getFlowByFormId(String formId, Boolean start) {
        FlowByFormModel res = new FlowByFormModel();
        List<TemplateByFormModel> resList = new ArrayList<>();

        QueryWrapper<TemplateNodeEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(TemplateNodeEntity::getFormId, formId);
        // start 传true 仅发起节点   false 全部节点
        start = null == start || start;
        if (start) {
            wrapper.lambda().eq(TemplateNodeEntity::getNodeType, NodeEnum.start.getType());
        }
        List<TemplateNodeEntity> nodeList = templateNodeService.list(wrapper);
        if (CollectionUtil.isEmpty(nodeList)) {
            return res;
        }
        List<String> flowIds = nodeList.stream().map(TemplateNodeEntity::getFlowId).distinct().collect(Collectors.toList());
        if (CollectionUtil.isEmpty(flowIds)) {
            return res;
        }
        List<TemplateJsonEntity> versionList = templateJsonService.listByIds(flowIds);
        if (CollectionUtil.isEmpty(versionList)) {
            return res;
        }
        // 获取启用版本
        versionList = versionList.stream().filter(e -> e.getState().equals(1))
                .sorted(Comparator.comparing(TemplateJsonEntity::getCreatorTime).reversed()).collect(Collectors.toList());
        // 获取流程
        List<String> templateIds = versionList.stream().map(TemplateJsonEntity::getTemplateId).distinct().collect(Collectors.toList());
        List<TemplateEntity> templateList = CollectionUtil.isNotEmpty(templateIds) ? this.listByIds(templateIds) : new ArrayList<>();
        // 获取权限流程
        String loginUserId = UserProvider.getLoginUserId();
        List<String> templatePermissionIds = serviceUtil.getLaunchPermission(loginUserId);
        //是否普通用户
        boolean commonUser = serviceUtil.isCommonUser(loginUserId);
        for (TemplateJsonEntity jsonEntity : versionList) {
            TemplateByFormModel model = new TemplateByFormModel();
            model.setId(jsonEntity.getId());

            TemplateEntity template = templateList.stream()
                    .filter(e -> ObjectUtil.equals(e.getId(), jsonEntity.getTemplateId())).findFirst().orElse(null);
            if (null == template || !ObjectUtil.equals(template.getStatus(), 1)) {
                continue;
            }
            if (commonUser && ObjectUtil.equals(template.getVisibleType(), 2)) {
                // 带权限
                if (templatePermissionIds.contains(jsonEntity.getId())) {
                    model.setFullName(template.getFullName());
                    resList.add(model);
                }
            } else {
                model.setFullName(template.getFullName());
                resList.add(model);
            }
        }
        res.setList(resList);
        res.setIsConfig(true);
        return res;
    }

    @Override
    public List<UserEntity> getSubFlowUserList(String flowId, TemplatePagination pagination) throws WorkFlowException {
        TemplateEntity template = this.getInfo(flowId);
        return serviceUtil.getLaunchUserByTemplateId(template, pagination);
    }

    @Override
    public VisualdevEntity getFormByTemplateId(String templateId) throws WorkFlowException {
        TemplateEntity template = this.getInfo(templateId);
        List<TemplateNodeEntity> nodeEntityList = templateNodeService.getList(template.getFlowId());

        TemplateNodeEntity nodeEntity = nodeEntityList.stream()
                .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.start.getType())).findFirst().orElse(null);
        if (null == nodeEntity) {
            throw new WorkFlowException(MsgCode.FA001.get());
        }
        return serviceUtil.getFormInfo(nodeEntity.getFormId());
    }

    @Override
    public FlowFormModel getFormIdAndFlowId(String templateId) throws WorkFlowException {
        List<String> userId = ImmutableList.of(UserProvider.getLoginUserId());
        FlowFormModel model = getFormIdAndFlowId(userId, templateId);
        if (model.getUserId().isEmpty()) {
            throw new WorkFlowException(MsgCode.WF029.get());
        }
        return model;
    }

    @Override
    public FlowFormModel getFormIdAndFlowId(List<String> userIdAll, String templateId) throws WorkFlowException {
        List<String> userList = new ArrayList<>();
        TemplateEntity template = this.getInfo(templateId);
        List<TemplateNodeEntity> nodeEntityList = templateNodeService.getList(template.getFlowId());
        // 判断权限
        for (String userId : userIdAll) {
            userList.add(userId);
            if (ObjectUtil.equals(template.getVisibleType(), 2)) {
                boolean commonUser = serviceUtil.isCommonUser(userId);
                if (commonUser) {
                    List<String> flowIds = serviceUtil.getLaunchPermission(userId);
                    if (!flowIds.contains(template.getId())) {
                        userList.remove(userId);
                    }
                }
            }
        }
        TemplateNodeEntity nodeEntity = nodeEntityList.stream()
                .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.start.getType())).findFirst().orElse(null);
        if (null == nodeEntity) {
            throw new WorkFlowException(MsgCode.FA001.get());
        }
        FlowFormModel model = new FlowFormModel();
        model.setFormId(nodeEntity.getFormId());
        model.setFlowId(template.getFlowId());
        model.setUserId(userList);
        return model;
    }

    @Override
    public List<String> getFormList() {
        List<String> resList = new ArrayList<>();
        List<TemplateJsonEntity> list = templateJsonService.getListOfEnable();
        if (CollectionUtil.isNotEmpty(list)) {
            List<String> flowIds = list.stream().map(TemplateJsonEntity::getId).distinct().collect(Collectors.toList());
            List<TemplateNodeEntity> startNodeList = templateNodeService.getList(flowIds, NodeEnum.start.getType());
            resList = startNodeList.stream().map(TemplateNodeEntity::getFormId).distinct().collect(Collectors.toList());
        }
        return resList;
    }

    @Override
    public Map<String, String> getFlowFormMap() {
        Map<String, String> map = new HashMap<>();
        List<TemplateNodeEntity> listStart = templateNodeService.getListStart();
        List<String> collect = listStart.stream().map(TemplateNodeEntity::getFlowId).collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(collect)) {
            QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().select(TemplateEntity::getId, TemplateEntity::getFlowId);
            queryWrapper.lambda().in(TemplateEntity::getFlowId, collect);
            Map<String, String> flowTempMap = this.list(queryWrapper).stream().collect(Collectors.toMap(TemplateEntity::getFlowId, TemplateEntity::getId));
            for (TemplateNodeEntity templateNodeEntity : listStart) {
                if (ObjectUtil.isNotEmpty(flowTempMap.get(templateNodeEntity.getFlowId()))) {
                    map.put(flowTempMap.get(templateNodeEntity.getFlowId()), templateNodeEntity.getFormId());
                }
            }
        }
        return map;
    }
}

