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

import cn.axzo.workflow.common.model.request.form.definition.FormFieldDTO;
import cn.axzo.workflow.common.model.response.form.instance.FormInstanceVO;
import cn.axzo.workflow.common.model.response.form.model.FormModelVO;
import org.flowable.form.api.FormInstanceInfo;
import org.flowable.form.api.FormModel;
import org.flowable.form.model.FormContainer;
import org.flowable.form.model.FormField;
import org.flowable.form.model.SimpleFormModel;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static org.mapstruct.NullValueCheckStrategy.ALWAYS;

/**
 * 表单实例模型的 MapStruts 转换器
 *
 * @author wangli
 * @since 2024-11-14 10:31
 */
@Mapper(
        componentModel = "spring",
        nullValueCheckStrategy = ALWAYS,
        imports = Arrays.class
)
public interface FormInstanceConverter extends EntityConverter<FormInstanceVO, FormInstanceInfo> {

    @Mapping(target = "id", source = "entity.id")
    @Mapping(target = "name", source = "entity.name")
    @Mapping(target = "key", source = "entity.key")
    @Mapping(target = "version", source = "entity.version")
    @Mapping(target = "formModel", expression = "java(formModelConverter(entity.getFormModel()))")
    @Mapping(target = "formInstanceId", source = "entity.formInstanceId")
    @Mapping(target = "submittedBy", source = "entity.submittedBy")
    @Mapping(target = "submittedDate", source = "entity.submittedDate")
    @Mapping(target = "taskId", source = "entity.taskId")
    @Mapping(target = "processInstanceId", source = "entity.processInstanceId")
    @Mapping(target = "processDefinitionId", source = "entity.processDefinitionId")
    @Mapping(target = "tenantId", source = "entity.tenantId")
    FormInstanceVO toVo(FormInstanceInfo entity);

    default FormModelVO formModelConverter(FormModel formModel) {
        FormModelVO formModelVO = new FormModelVO();
        if (formModel instanceof SimpleFormModel) {
            SimpleFormModel simpleFormModel = (SimpleFormModel) formModel;
            formModelVO.setName(simpleFormModel.getName());
            formModelVO.setKey(simpleFormModel.getKey());
            formModelVO.setVersion(simpleFormModel.getVersion());
            formModelVO.setFields(formContainersToFormFieldDTOs(simpleFormModel.getFields()));
        }
        return formModelVO;
    }

    default FormFieldDTO formFieldConverter(FormField formField) {
        FormFieldDTO formFieldDTO = new FormFieldDTO();
        formFieldDTO.setType(formField.getType());
        formFieldDTO.setId(formField.getId());
        formFieldDTO.setName(formField.getName());
        formFieldDTO.setValue(ConversionUtils.convertObject(formField.getValue()));
        formFieldDTO.setPlaceholder(formField.getPlaceholder());
        formFieldDTO.setParams(formField.getParams());
        if (formField instanceof FormContainer) {
            FormContainer formContainer = (FormContainer) formField;
            formFieldDTO.setFieldType(formContainer.getClass().getSimpleName());
            formFieldDTO.setFields(formContainerListsToFormFieldDTOLists(formContainer.getFields()));
        }
        return formFieldDTO;
    }


    // 辅助方法，用于处理List<FormContainer>到List<FormFieldDTO>的转换，调用上面自定义的转换方法
    default List<FormFieldDTO> formContainersToFormFieldDTOs(List<FormField> formContainers) {
        if (formContainers == null) {
            return null;
        }
        return formContainers.stream()
                .map(this::formFieldConverter)
                .collect(Collectors.toList());
    }

    // 辅助方法，用于处理List<List<FormContainer>>到List<List<FormFieldDTO>>的转换，调用上面的辅助方法
    default List<List<FormFieldDTO>> formContainerListsToFormFieldDTOLists(List<List<FormField>> formContainerLists) {
        if (formContainerLists == null) {
            return null;
        }
        return formContainerLists.stream()
                .map(this::formContainersToFormFieldDTOs)
                .collect(Collectors.toList());
    }
}
