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

import cn.axzo.workflow.common.model.request.form.definition.FormContentSearchDTO;
import cn.axzo.workflow.common.model.request.form.definition.FormDefinitionSearchDTO;
import cn.axzo.workflow.common.model.response.form.definition.FormDefinitionVO;
import cn.axzo.workflow.form.service.FormDefinitionService;
import cn.axzo.workflow.form.service.converter.FormFieldConverter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.form.api.FormInfo;
import org.flowable.form.api.FormRepositoryService;
import org.flowable.form.api.FormService;
import org.flowable.form.model.FormField;
import org.flowable.form.model.SimpleFormModel;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

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


/**
 * 表单定义 Service 实现
 *
 * @author wangli
 * @since 2023/7/19 16:47
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FormDefinitionServiceImpl implements FormDefinitionService {
    @Resource
    private FormRepositoryService formRepositoryService;
    @Resource
    private FormFieldConverter formFieldConverter;
    @Resource
    private HistoryService historyService;
    @Resource
    private FormService formService;

    @Override
    public FormDefinitionVO get(FormDefinitionSearchDTO dto) {
        FormInfo formModel;
        try {
            formModel = formRepositoryService.getFormModelByKeyAndParentDeploymentId(dto.getKey(),dto.getParentDeploymentId(), dto.getTenantId(),false );
        }catch (FlowableObjectNotFoundException e){
           return null;
        }

        FormDefinitionVO formDefinitionVO = new FormDefinitionVO();
        formDefinitionVO.setFormDefinitionId(formModel.getId());
        formDefinitionVO.setName(formModel.getName());
        formDefinitionVO.setKey(formModel.getKey());
        formDefinitionVO.setVersion(formModel.getVersion());
        formDefinitionVO.setTenantId(dto.getTenantId());
        List<FormField> fields = ((SimpleFormModel) formModel.getFormModel()).getFields();
        formDefinitionVO.setFields(formFieldConverter.toVos(fields));
        return formDefinitionVO;
    }

    @Override
    public FormInfo getFormInfo(FormContentSearchDTO dto) {
        if (StringUtils.hasText(dto.getProcessInstanceId()) && !StringUtils.hasText(dto.getKey())) {
            HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
                    .includeProcessVariables()
                    .processInstanceId(dto.getProcessInstanceId())
                    .processInstanceTenantId(dto.getTenantId())
                    .singleResult();
            if (Objects.nonNull(instance)) {
                dto.setKey(instance.getProcessDefinitionKey());
                dto.setVariables(instance.getProcessVariables());
            } else {
                return null;
            }
        }
        return formService.getFormModelWithVariablesByKey(dto.getKey(), dto.getTaskId(), dto.getVariables(), dto.getTenantId(), true);
    }
}
