package cn.axzo.workflow.core.engine.cmd;

import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
import cn.axzo.workflow.core.engine.job.AsyncActivitySetAssigneeJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.job.service.JobService;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;

import static cn.axzo.workflow.core.engine.cmd.CustomBizSpecifyAssigneeToTaskCmd.getOperateTask;
import static cn.axzo.workflow.core.engine.cmd.CustomBizSpecifyAssigneeToTaskCmd.validProcessInstance;
import static cn.axzo.workflow.core.engine.cmd.CustomBizSpecifyAssigneeToTaskCmd.validate;
import static cn.axzo.workflow.core.engine.cmd.CustomBizSpecifyAssigneeToTaskCmd.validateActivityConfig;

/**
 * 自定的业务指定审批人命令实现
 *
 * @author wangli
 * @since 2023/12/22 13:51
 */
public class CustomBizSpecifyAssigneeToTaskAsyncCmd extends AbstractCommand<String> implements Serializable {

    private static final Logger log = LoggerFactory.getLogger(CustomBizSpecifyAssigneeToTaskAsyncCmd.class);
    private final BpmnActivitySetAssigneeDTO dto;

    public CustomBizSpecifyAssigneeToTaskAsyncCmd(BpmnActivitySetAssigneeDTO dto) {
        this.dto = dto;
    }

    @Override
    public String paramToJsonString() {
        return JSON.toJSONString(dto);
    }

    @Override
    public String execute(CommandContext commandContext) {
        ProcessEngineConfigurationImpl processEngineConfiguration =
                CommandContextUtil.getProcessEngineConfiguration(commandContext);
        TaskService taskService = processEngineConfiguration.getTaskService();
        TaskEntity task = (TaskEntity) getOperateTask(taskService, dto.getTriggerId());
        //校验
        validate(processEngineConfiguration.getRuntimeService(), dto.getTriggerId(), task, dto.getAssigners());

        // 校验节点真实的节点配置，还是否是指定人？
        if (!validateActivityConfig(task)) {
            log.info("业务节点设置审批人时，发现节点已经修改配置，无法继续设置审批人，processInstanceId:{}, taskDefinitionKey={}", task.getProcessInstanceId(), task.getTaskDefinitionKey());
            return "";
        }

        validProcessInstance(commandContext, task, dto.getAssigners());

        return startAsync(processEngineConfiguration, task);
    }

    private String startAsync(ProcessEngineConfigurationImpl processEngineConfiguration, TaskEntity task) {
        JobService jobService = processEngineConfiguration.getJobServiceConfiguration().getJobService();

        JobEntity job = jobService.createJob();
        // 这里的 executionId 可为 null
        job.setExecutionId(task.getExecutionId());
        job.setProcessInstanceId(task.getProcessInstanceId());
        job.setProcessDefinitionId(task.getProcessDefinitionId());
        job.setElementId(task.getTaskDefinitionKey());
        job.setElementName(task.getName());
        job.setJobHandlerType(AsyncActivitySetAssigneeJobHandler.TYPE);
        job.setTenantId(task.getTenantId());

        // 携带自定义的数据
        job.setCustomValues(JSONUtil.toJsonStr(dto));

        // 创建异步任务并调度
        jobService.createAsyncJob(job, false);
        jobService.scheduleAsyncJob(job);
        return job.getId();
    }


}
