package cn.stylefeng.workflow.instance.modular.manage.factory;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.stylefeng.team.form.api.FormItemFormatApi;
import cn.stylefeng.team.form.api.entity.FormItem;
import cn.stylefeng.team.view.api.ViewApi;
import cn.stylefeng.workflow.api.entity.design.Definition;
import cn.stylefeng.workflow.api.enums.SummarySourceEnum;
import cn.stylefeng.workflow.api.pojo.InstanceVariable;
import cn.stylefeng.workflow.api.pojo.config.SixGraphDesign;
import cn.stylefeng.workflow.api.pojo.config.model.FlowGlobalConfig;
import cn.stylefeng.workflow.api.pojo.config.model.ModelSummaryField;
import cn.stylefeng.workflow.api.pojo.instance.SummaryFieldValue;
import cn.stylefeng.workflow.instance.core.util.FormItemUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TaskSummaryFieldFactory {

    public static List<SummaryFieldValue> createTaskSummaryField(Long instanceId, Definition definition, InstanceVariable instanceVariable) {

        if (ObjectUtil.isEmpty(instanceId) || ObjectUtil.isEmpty(definition) || ObjectUtil.isEmpty(instanceVariable)) {
            return null;
        }

        SixGraphDesign xSixGraphJson = definition.getXSixGraphJson();
        if (ObjectUtil.isEmpty(xSixGraphJson)) {
            return null;
        }
        FlowGlobalConfig flowGlobalConfig = xSixGraphJson.getFlowGlobalConfig();
        if (ObjectUtil.isEmpty(flowGlobalConfig)) {
            return null;
        }
        List<ModelSummaryField> modelSummaryFieldList = flowGlobalConfig.getModelSummaryFieldList();
        if (ObjectUtil.isEmpty(modelSummaryFieldList)) {
            return null;
        }

        Map<Long, List<FormItem>> flowDefinitionFormItemList = FormItemUtil.getFlowDefinitionFormItemList(flowGlobalConfig);

        ViewApi viewApi = SpringUtil.getBean(ViewApi.class);

        List<SummaryFieldValue> summaryFieldValues = new ArrayList<>();

        Map<String, Map<String, Object>> formData = instanceVariable.getFormData();

        Map<String, Object> customVueFormData = instanceVariable.getCustomVueFormData();

        for (ModelSummaryField modelSummaryField : modelSummaryFieldList) {

            SummaryFieldValue summaryFieldValue = new SummaryFieldValue();

            Integer summarySource = modelSummaryField.getSummarySource();

            if (SummarySourceEnum.FORM_VARIABLE.getCode().equals(summarySource)) {

                summaryFieldValue.setSummaryFieldName(modelSummaryField.getSumFormVariableName());

                Long sumFieldFormDefinitionId = modelSummaryField.getSumFieldFormDefinitionId();
                if (ObjectUtil.isEmpty(sumFieldFormDefinitionId)) {
                    continue;
                }

                Map<String, Object> defFormData = formData.get(String.valueOf(sumFieldFormDefinitionId));
                if (ObjectUtil.isEmpty(defFormData)) {
                    continue;
                }

                Object originValue = defFormData.get(modelSummaryField.getSumFormVariableCode());
                formatFormDataOriginValue(modelSummaryField, originValue, summaryFieldValue, summaryFieldValues, flowDefinitionFormItemList);
            }

            else if (SummarySourceEnum.CUSTOM_VUE_VARIABLE.getCode().equals(summarySource)) {

                if (ObjectUtil.isEmpty(customVueFormData)) {
                    continue;
                }

                summaryFieldValue.setSummaryFieldName(modelSummaryField.getSumModelVariableName());

                Object originValue = customVueFormData.get(modelSummaryField.getSumModelVariableCode());
                formatCustomVueDataOriginValue(modelSummaryField, originValue, viewApi, summaryFieldValue, summaryFieldValues);
            }
        }

        return summaryFieldValues;
    }

    private static void formatCustomVueDataOriginValue(ModelSummaryField modelSummaryField, Object originValue, ViewApi viewApi, SummaryFieldValue summaryFieldValue,
                                                       List<SummaryFieldValue> summaryFieldValues) {
        if (ObjectUtil.isEmpty(originValue)) {
            return;
        }

        String parserName = modelSummaryField.getParserName();
        if (ObjectUtil.isNotEmpty(parserName)) {
            Object formattedValue = viewApi.getFormattedValue(parserName, originValue);
            summaryFieldValue.setSummaryFieldValue(String.valueOf(formattedValue));
        } else {
            summaryFieldValue.setSummaryFieldValue(String.valueOf(originValue));
        }

        summaryFieldValues.add(summaryFieldValue);
    }

    private static void formatFormDataOriginValue(ModelSummaryField modelSummaryField,
                                                  Object originValue,
                                                  SummaryFieldValue summaryFieldValue,
                                                  List<SummaryFieldValue> summaryFieldValues,
                                                  Map<Long, List<FormItem>> flowDefinitionFormItemList) {
        if (ObjectUtil.isEmpty(originValue)) {
            return;
        }

        FormItem formItemByFieldCode = FormItemUtil.getFormItemByFieldCode(
                flowDefinitionFormItemList, modelSummaryField.getSumFieldFormDefinitionId(), modelSummaryField.getSumFormVariableCode());

        if (formItemByFieldCode == null) {
            return;
        }

        FormItemFormatApi formItemFormatApi = SpringUtil.getBean(FormItemFormatApi.class);
        Object format = formItemFormatApi.format(formItemByFieldCode.getComponentCode(), formItemByFieldCode, originValue);
        summaryFieldValue.setSummaryFieldValue(String.valueOf(format));

        summaryFieldValues.add(summaryFieldValue);
    }

}