package com.jeeplus.modules.flowable.service.converter.json;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.jeeplus.common.utils.SpringContextHolder;
import com.jeeplus.modules.extension.entity.FlowButton;
import com.jeeplus.modules.extension.entity.FormSetting;
import com.jeeplus.modules.extension.entity.TaskDefExtension;
import com.jeeplus.modules.extension.service.FormSettingService;
import com.jeeplus.modules.extension.service.TaskDefExtensionService;
import org.flowable.bpmn.model.*;
import org.flowable.editor.constants.StencilConstants;
import org.flowable.editor.language.json.converter.ActivityProcessor;
import org.flowable.editor.language.json.converter.BaseBpmnJsonConverter;
import org.flowable.editor.language.json.converter.UserTaskJsonConverter;

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

public class FlowUserTaskJsonConverter extends UserTaskJsonConverter {


    public static void fillTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,
                                 Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        fillJsonTypes(convertersToBpmnMap);
        fillBpmnTypes(convertersToJsonMap);
    }

    public static void setCustomTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,
                                      Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        removeTypes(convertersToBpmnMap, convertersToJsonMap);
        fillTypes(convertersToBpmnMap, convertersToJsonMap);
    }

    public static void removeTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,
                                   Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        convertersToJsonMap.remove(UserTask.class);
        convertersToBpmnMap.remove(StencilConstants.STENCIL_TASK_USER);
    }

    public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {
        convertersToBpmnMap.put(STENCIL_TASK_USER, FlowUserTaskJsonConverter.class);
    }

    public static void fillBpmnTypes(
            Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        convertersToJsonMap.put(UserTask.class, FlowUserTaskJsonConverter.class);
    }

    @Override
    public void convertToJson(BaseElement baseElement, ActivityProcessor processor, BpmnModel model, FlowElementsContainer container, ArrayNode shapesArrayNode, double subProcessX, double subProcessY) {
        super.convertToJson(baseElement, processor, model, container, shapesArrayNode, subProcessX, subProcessY);
    }

    @Override
    protected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode,
                                               Map<String, JsonNode> shapeMap) {
        String procDefId = getProperty("process_id", modelNode).asText();
        String taskDefId = getProperty("overrideid", elementNode).asText();
        UserTask flowElement = (UserTask) super.convertJsonToElement(elementNode, modelNode, shapeMap);


        TaskDefExtension taskDefExtension = new TaskDefExtension();
        taskDefExtension.setTaskDefId(taskDefId);
        taskDefExtension.setProcessDefId(procDefId);
        List<TaskDefExtension> list = SpringContextHolder.getBean(TaskDefExtensionService.class).findList(taskDefExtension);
        if (list.size() > 0) {
            taskDefExtension = list.get(0);
            List<FlowButton> list1 =  SpringContextHolder.getBean(TaskDefExtensionService.class).get(taskDefExtension.getId()).getFlowButtonList();
            if (list1.size() > 0) {

//                ExtensionElement buttons = new ExtensionElement();
//                buttons.setId("flowable:buttons");
//                buttons.setName("flowable:buttons");


                for (FlowButton flowButton : list1) {
                    ExtensionElement button = new ExtensionElement();
                    button.setName("flowable:Button");

                    ExtensionAttribute id = new ExtensionAttribute();
                    id.setName("id");
                    id.setValue(flowButton.getId());
                    ExtensionAttribute code = new ExtensionAttribute();
                    code.setName("code");
                    code.setValue(flowButton.getCode());
                    ExtensionAttribute name = new ExtensionAttribute();
                    name.setName("name");
                    name.setValue(flowButton.getName());
                    ExtensionAttribute next = new ExtensionAttribute();
                    next.setName("next");
                    next.setValue(flowButton.getNext());

                    ExtensionAttribute isHide = new ExtensionAttribute();
                    isHide.setName("isHide");
                    isHide.setValue(flowButton.getIsHide());
                    ExtensionAttribute sort = new ExtensionAttribute();
                    sort.setName("sort");
                    sort.setValue(String.valueOf(flowButton.getSort()));

                    button.addAttribute(id);
                    button.addAttribute(code);
                    button.addAttribute(name);
                    button.addAttribute(next);
                    button.addAttribute(isHide);
                    button.addAttribute(sort);

                    flowElement.addExtensionElement(button);

                }
//                flowElement.addExtensionElement(buttons);
            }


        }

        FormSetting formSetting = SpringContextHolder.getBean(FormSettingService.class).queryByDefIdAndTaskId(procDefId, taskDefId);

        if(formSetting != null){
           String readOnly = formSetting.getFormReadOnly();
           ExtensionAttribute attribute = new ExtensionAttribute();
           attribute.setName("flowable:formReadOnly");
           attribute.setValue(readOnly);
           flowElement.addAttribute(attribute);


           String formType = formSetting.getFormType() ==null? "":formSetting.getFormType();
           ExtensionAttribute attribute2 = new ExtensionAttribute();
           attribute2.setName("flowable:formType");
           attribute2.setValue(formType);
           flowElement.addAttribute(attribute2);
       }

        return flowElement;
    }

    /**
     * 创建自定义属性
     *
     * @param propertyName  属性名称
     * @param propertyValue 属性值
     */
    private CustomProperty createProperty(String propertyName, String propertyValue) {
        CustomProperty customProperty = new CustomProperty();
        customProperty.setId(propertyName);
        customProperty.setName(propertyName);
        customProperty.setSimpleValue(propertyValue);
        return customProperty;
    }

}
