package com.fjhx.service.process.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.constants.FlowExplainConstant;
import com.fjhx.entity.process.ProcessNode;
import com.fjhx.entity.process.ProcessTenant;
import com.fjhx.enums.ProcessNodeHandleObjectTypeEnum;
import com.fjhx.mapper.process.ProcessNodeMapper;
import com.fjhx.params.ProcessNodeVo;
import com.fjhx.service.process.ProcessNodeService;
import com.fjhx.service.process.ProcessTenantService;
import com.fjhx.utils.Assert;
import com.fjhx.utils.FileClientUtil;
import org.springblade.core.secure.utils.AuthUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2022-08-12
 */
@Service
public class ProcessNodeServiceImpl extends ServiceImpl<ProcessNodeMapper, ProcessNode> implements ProcessNodeService {


    @Autowired
    private ProcessTenantService processTenantService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(ProcessNodeVo processNodeVo) {
        verificationField(processNodeVo);
        save(processNodeVo);
        FileClientUtil.bindingFile(processNodeVo.getId(), processNodeVo.getFileInfo());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(ProcessNodeVo processNodeVo) {
        verificationField(processNodeVo);
        updateById(processNodeVo);
        FileClientUtil.againBindingFile(processNodeVo.getId(), processNodeVo.getFileInfo());
    }

    @Override
    public Map<String, Object> getDetails(HashMap<String, String> condition) {
        Map<String, Object> result = new HashMap<>();
        Long id = Convert.toLong(condition.get("id"));

        ProcessTenant processTenant;

        if (ObjectUtil.isNotEmpty(id)) {
            processTenant = processTenantService.getById(id);
        } else {
            String code = condition.get("code");
            String tenantId = AuthUtil.getTenantId();
            processTenant = processTenantService.getProcessTenant(code, tenantId);

            Assert.notEmpty(processTenant, "无法通过流程编码找到流程");
            id = processTenant.getId();
        }
        
        List<ProcessNode> list = list(ProcessNode::getProcessTenantId, id);

        result.put("list", list);
        result.put("nodeObject", processTenant.getNodeObject());
        result.put("lineObject", processTenant.getLineObject());

        return result;
    }

    /**
     * 验证字段
     */
    private void verificationField(ProcessNodeVo processNodeVo) {

        // 所属租户流程
        Long processTenantId = processNodeVo.getProcessTenantId();
        Assert.notEmpty(processTenantId, FlowExplainConstant.PROCESS_TENANT_ID_EMPTY);

        // 节点类型
        Integer type = processNodeVo.getType();
        Assert.notEmpty(type, FlowExplainConstant.NODE_TYPE);

        // 父节点id
        Long parentId = processNodeVo.getParentId();
        Assert.notEmpty(parentId, FlowExplainConstant.NODE_PARENT_ID);

        // 节点名称
        String name = processNodeVo.getName();
        Assert.notEmpty(name, FlowExplainConstant.NODE_NAME);

        // 发起 / 处理对象类型
        Integer handleObjectType = processNodeVo.getHandleObjectType();
        Assert.notEmpty(handleObjectType, FlowExplainConstant.HANDLE_OBJECT_TYPE);

        // 处理对象id集合
        if (ObjectUtil.notEqual(handleObjectType, ProcessNodeHandleObjectTypeEnum.ALL.getType())) {
            List<String> handleObjectIdList = processNodeVo.getHandleObjectIdList();
            Assert.notEmpty(handleObjectIdList, FlowExplainConstant.HANDLE_OBJECT_ID_LIST);
        }

    }

}
