/*
 * Copyright (c) 2023 codvision.com All Rights Reserved.
 */

package com.codvision.workflow.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codvision.auth.entity.SysMenu;
import com.codvision.auth.mapper.SysMenuMapper;
import com.codvision.commoncore.utils.Preconditions;
import com.codvision.workflow.entity.QuestionnaireModule;
import com.codvision.workflow.entity.WorkFlowFormLink;
import com.codvision.workflow.entity.dto.WorkFlowFormLinkDTO;
import com.codvision.workflow.entity.vo.WorkFlowFormLinkVO;
import com.codvision.workflow.mapper.QuestionnaireModuleMapper;
import com.codvision.workflow.mapper.WorkFlowFormLinkMapper;
import com.codvision.workflow.service.WorkFlowFormLinkService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author hxl
 */
@Service
@RequiredArgsConstructor
public class WorkFlowFormLinkServiceImpl extends ServiceImpl<WorkFlowFormLinkMapper, WorkFlowFormLink> implements WorkFlowFormLinkService {

    private final SysMenuMapper sysMenuMapper;
    private final QuestionnaireModuleMapper questionnaireModuleMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addFormLink(WorkFlowFormLinkDTO workFlowFormLinkDTO) {
        List<WorkFlowFormLink> workFlowFormLinks = new ArrayList<>();
        for (Integer menuId : workFlowFormLinkDTO.getMenuIds()) {
            SysMenu sysMenu = sysMenuMapper.selectById(menuId);
            if (sysMenu == null) {
                continue;
            }

            WorkFlowFormLink link = this.getOne(Wrappers.<WorkFlowFormLink>lambdaQuery().eq(WorkFlowFormLink::getMenuId, menuId));
            Preconditions.checkArgument(link == null, "业务模块【" + sysMenu.getName() + "】" + "已配置流程");

            WorkFlowFormLink workFlowFormLink = WorkFlowFormLink.builder()
                    .definitionId(workFlowFormLinkDTO.getDefinitionId()).definitionKey(workFlowFormLinkDTO.getDefinitionKey()).formId(workFlowFormLinkDTO.getFormId()).menuId(menuId).build();
            workFlowFormLinks.add(workFlowFormLink);
        }

        this.saveBatch(workFlowFormLinks);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFormLink(WorkFlowFormLinkDTO workFlowFormLinkDTO) {
        delAllByDefinitionKey(workFlowFormLinkDTO.getDefinitionKey());
        if (CollectionUtils.isNotEmpty(workFlowFormLinkDTO.getMenuIds())) {
            addFormLink(workFlowFormLinkDTO);
        }
    }

    @Override
    public WorkFlowFormLinkVO getFormInfoByMenuId(Integer menuId) {
        WorkFlowFormLink link = this.getOne(Wrappers.<WorkFlowFormLink>lambdaQuery().eq(WorkFlowFormLink::getMenuId, menuId));
        Preconditions.checkArgument(link != null, "当前模块尚未配置流程");

        List<QuestionnaireModule> modules = questionnaireModuleMapper.selectList(Wrappers.<QuestionnaireModule>lambdaQuery()
                .eq(QuestionnaireModule::getQuestionnaireId, link.getFormId()).orderByAsc(QuestionnaireModule::getSort));
        Preconditions.checkArgument(CollectionUtils.isNotEmpty(modules), "获取表单信息失败");
        return WorkFlowFormLinkVO.builder()
                .definitionId(link.getDefinitionId()).definitionKey(link.getDefinitionKey()).formId(link.getFormId()).formJson(modules).build();
    }

    @Override
    public List<WorkFlowFormLink> getByDefinitionId(String definitionId) {
        return this.list(Wrappers.<WorkFlowFormLink>lambdaQuery().eq(WorkFlowFormLink::getDefinitionId, definitionId));
    }

    @Override
    public List<WorkFlowFormLink> getByDefinitionKey(String definitionKey) {
        return this.list(Wrappers.<WorkFlowFormLink>lambdaQuery().eq(WorkFlowFormLink::getDefinitionKey, definitionKey));
    }

    @Override
    public void delAllByDefinitionKey(String definitionKey) {
        this.remove(Wrappers.<WorkFlowFormLink>lambdaQuery().eq(WorkFlowFormLink::getDefinitionKey, definitionKey));
    }

    @Override
    public void delAllByDefinitionId(String definitionId) {
        this.remove(Wrappers.<WorkFlowFormLink>lambdaQuery().eq(WorkFlowFormLink::getDefinitionId, definitionId));
    }
}
