package cn.axzo.workflow.core.common.utils;

import cn.axzo.workflow.common.model.request.form.FormPermissionMetaInfo;
import cn.axzo.workflow.common.util.ExpressionUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.ListUtils;
import org.flowable.form.api.FormModel;
import org.flowable.form.model.FormField;
import org.flowable.form.model.SimpleFormModel;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.axzo.workflow.common.constant.FormConstants.FIELD_PROPERTY_DEFAULT_VALUE;
import static cn.axzo.workflow.common.constant.FormConstants.FIELD_PROPERTY_EDITABLE;
import static cn.axzo.workflow.common.constant.FormConstants.FIELD_PROPERTY_HIDDEN;
import static cn.axzo.workflow.common.constant.FormConstants.FIELD_PROPERTY_READONLY;
import static cn.axzo.workflow.common.constant.FormConstants.FIELD_PROPERTY_REQUIRED;

/**
 * 表单处理帮助类
 *
 * @author wangli
 * @since 2024-11-29 15:57
 */
public class FormHelper {
    private FormHelper() {
    }

    /**
     * 填充表单模型数据
     *
     * @param formModel
     * @param fieldPermission
     * @param variables
     * @param showOriginDefaultValue
     * @return
     */
    public static FormModel populateFormModel(SimpleFormModel formModel,
                                              List<FormPermissionMetaInfo> fieldPermission,
                                              Map<String, Object> variables,
                                              boolean showOriginDefaultValue) {
        if (Objects.isNull(formModel)) {
            return null;
        }
        Map<String, FormPermissionMetaInfo> fieldMap = ListUtils.emptyIfNull(fieldPermission).stream()
                .collect(Collectors.toMap(FormPermissionMetaInfo::getFieldId, Function.identity(), (s, t) -> s));

        formModel.allFieldsAsMap().forEach((fieldId, formField) -> {
            Map<String, Object> oldParams = CollectionUtils.isEmpty(formField.getParams()) ? new HashMap<>() : formField.getParams();
            FormPermissionMetaInfo defaultPermission = fieldMap.getOrDefault(fieldId, new FormPermissionMetaInfo());
            oldParams.put(FIELD_PROPERTY_REQUIRED, defaultPermission.getRequired());
            oldParams.put(FIELD_PROPERTY_EDITABLE, defaultPermission.getEditable());
            oldParams.put(FIELD_PROPERTY_READONLY, defaultPermission.getReadonly());
            oldParams.put(FIELD_PROPERTY_HIDDEN, defaultPermission.getHidden());
            if (oldParams.containsKey(FIELD_PROPERTY_DEFAULT_VALUE)) {
                String defaultValue = oldParams.getOrDefault(FIELD_PROPERTY_DEFAULT_VALUE, "").toString();
                if (!showOriginDefaultValue) {
                    defaultValue = ExpressionUtil.parseString(String.valueOf(oldParams.get(FIELD_PROPERTY_DEFAULT_VALUE)),
                            CollectionUtils.isEmpty(variables) ? new HashMap<>() : variables);
                }
                oldParams.put(FIELD_PROPERTY_DEFAULT_VALUE, defaultValue);
                if (injectDefaultValue(formField) && StringUtils.hasText(defaultValue)) {
                    formField.setValue(defaultValue);
                }
            }
            formField.setParams(oldParams);
        });
        return formModel;
    }

    private static boolean injectDefaultValue(FormField field) {
        if (Objects.isNull(field.getValue())) {
            return true;
        }

        if (field.getValue() instanceof String && Objects.equals("", field.getValue())) {
            return false;
        }

        return !(field.getValue() instanceof Collection) || CollectionUtils.isEmpty((Collection<?>) field.getValue());
    }
}
