package cn.axzo.workflow.core.service.impl;

import cn.axzo.workflow.common.model.request.form.instance.FormContentUpdateDTO;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.service.FormInstanceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.TaskService;
import org.flowable.form.api.FormInfo;
import org.flowable.form.api.FormRepositoryService;
import org.flowable.form.api.FormService;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS;


/**
 * 表单实例 Service 实现
 *
 * @author wangli
 * @since 2023/7/21 15:27
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FormInstanceServiceImpl implements FormInstanceService {

    @Resource
    private FormRepositoryService formRepositoryService;
    @Resource
    private FormService formService;
    @Resource
    private TaskService taskService;

    @Override
    public void updateFormContent(FormContentUpdateDTO dto) {
        TaskQuery query = taskService.createTaskQuery().taskId(dto.getTaskId());
        if (Objects.nonNull(dto.getTenantId())) {
            query.taskTenantId(dto.getTenantId());
        }
        Task task = query.singleResult();
        if (Objects.isNull(task)) {
            throw new WorkflowEngineException(TASK_COMPLETE_FAIL_NOT_EXISTS);
        }
        if (!Objects.equals(dto.getUserId(), task.getAssignee())) {
            throw new WorkflowEngineException(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
        }

        FormInfo formInfo = formRepositoryService.getFormModelById(dto.getFormDefinitionId());
        if (Objects.nonNull(task.getProcessInstanceId())) {
            formService.saveFormInstanceByFormDefinitionId(dto.getFormVariables(), dto.getFormDefinitionId(),
                    dto.getTaskId(),
                    task.getProcessInstanceId(),
                    task.getProcessDefinitionId(), task.getTenantId(), null);
        } else {
            formService.saveFormInstanceWithScopeId(dto.getFormVariables(), dto.getFormDefinitionId(), dto.getTaskId(),
                    task.getScopeId(), task.getScopeType(), task.getScopeDefinitionId(), task.getTenantId(), null);
        }
    }
}
