package net.northking.cctp.flowable.dto.ip;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import net.northking.cctp.common.exception.PlatformRuntimeException;
import net.northking.cctp.flowable.common.exception.FlowAppError;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * 实施流程
 */
public class IpProcessState {

    @ApiModelProperty(value = "主键id", required = true)
    private String id;

    @ApiModelProperty(value = "流程名字", required = true)
    private String name;

    @ApiModelProperty(value = "备注信息", required = false)
    private String memo;

    @ApiModelProperty(value = "可否修改的", required = false)
    private Boolean canModify = false;

    @ApiModelProperty(value = "是否默认流程", required = false)
    private Boolean defaulted = false;

    @ApiModelProperty(value = "是否启用流程", required = true)
    private Boolean enabled;

    @ApiModelProperty(value = "节点信息", required = true)
    private List<Event> events;

    @ApiModelProperty(value = "连线", required = true)
    private List<State> states;

    private String createdBy;

    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date createdTime;

    private String updatedBy;

    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date updatedTime;

    private Boolean deleted = false;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    public Boolean getCanModify() {
        return canModify;
    }

    public void setCanModify(Boolean canModify) {
        this.canModify = canModify;
    }

    public Boolean getDefaulted() {
        return defaulted;
    }

    public void setDefaulted(Boolean defaulted) {
        this.defaulted = defaulted;
    }

    public Boolean getEnabled() {
        return enabled;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public List<Event> getEvents() {
        if (this.events == null) {
            return new ArrayList<>();
        }
        return events;
    }

    public void setEvents(List<Event> events) {
        this.events = events;
        for (Event event : events) {
            event.setIpId(this.getId());
        }
    }

    public List<State> getStates() {
        if (this.states == null) {
            return new ArrayList<>();
        }
        return states;
    }

    public void setStates(List<State> states) {
        this.states = states;
        for (State state : states) {
            state.setIpId(this.getId());
        }
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public Date getCreatedTime() {
        return createdTime;
    }

    public void setCreatedTime(Date createdTime) {
        this.createdTime = createdTime;
    }

    public String getUpdatedBy() {
        return updatedBy;
    }

    public void setUpdatedBy(String updatedBy) {
        this.updatedBy = updatedBy;
    }

    public Date getUpdatedTime() {
        return updatedTime;
    }

    public void setUpdatedTime(Date updatedTime) {
        this.updatedTime = updatedTime;
    }

    public Boolean getDeleted() {
        return deleted;
    }

    public void setDeleted(Boolean deleted) {
        this.deleted = deleted;
    }

    public void flowCheck() {
        // 节点重复校验
        duplicateStateCheck();
        // 不能没有节点
        if (states == null || states.size() == 0) {
            throw new PlatformRuntimeException(FlowAppError.STATE_NODE_IS_EMPTY);
        }
        // 如果只有一个节点啊
        if (states.size() == 1) {
            return;
        }

        Map<String, Integer> sourceMap = new HashMap<>(); // 出
        Map<String, Integer> targetMap = new HashMap<>(); // 进
        for (Event event : events) {    // 处理每条线出现次数
            String source = event.getSource();
            if (!sourceMap.containsKey(source)) {
                sourceMap.put(source, 1);
            } else {
                sourceMap.put(source, sourceMap.get(source) + 1);
            }
            String target = event.getTarget();
            if (!targetMap.containsKey(target)) {
                targetMap.put(target, 1);
            } else {
                targetMap.put(target, targetMap.get(target) + 1);
            }
        }
        // 正常节点
        for (State state : getStates()) {
            Integer sourceCount = sourceMap.get(state.getId());
            Integer targetCount = targetMap.get(state.getId());
            if ((sourceCount == null && targetCount == null ) || ((sourceCount != null && sourceCount == 0) && (targetCount != null && targetCount == 0)) ) {
                throw new PlatformRuntimeException(FlowAppError.NODE_LINE_IS_NECESSARY, state.getLabelText());
            }
        }
    }
    /**
     * 状态点重复检查
     *
     */
    public void duplicateStateCheck() {
        List<String> list = new ArrayList<>();
        for (State state : states) {
            if (StringUtils.isEmpty(state.getLabel())) {
                throw new PlatformRuntimeException(FlowAppError.NODE_NAME_IS_EMPTY);
            }
            if (!list.contains(state.getLabel())) { // 如果没有添加到集合
                list.add(state.getLabel());
            } else {
                throw new PlatformRuntimeException(FlowAppError.DUPLICATED_NODE, state.getLabelText());
            }
        }
    }
}
