package org.springblade.openapi.mk.pojo.enums;

import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 *  流程回调类型
 * @author bfhuange
 * @since 2024/11/23
 */
@AllArgsConstructor
@Getter
public enum ProcessCallbackType {
    /**
     *  提交
     */
    SUBMIT(ProcessOperationType.DRAFTER_SUBMIT),
    /**
     *  起草人撤回
     */
    RETRACT(ProcessOperationType.DRAFTER_RETRACT),
    /**
     *  审批通过
     */
    PASS(ProcessOperationType.HANDLER_PASS),
    /**
     *  审批驳回
     */
    REJECT(ProcessOperationType.HANDLER_REJECT),
    /**
     *  废弃（起草人废弃、审批人废弃、超管废弃）
     */
    ABANDON(ProcessOperationType.DRAFTER_ABANDON, ProcessOperationType.HANDLER_ABANDON, ProcessOperationType.ADMIN_ABANDON),
    /**
     *  修改当前处理人（超管修改当前处理人、审批人转办、审批人撤回、特权人前后跳转）
     */
    CHANGE_CUR_HANDLER(ProcessOperationType.ADMIN_CHANGE_CUR_HANDLER, ProcessOperationType.HANDLER_TRANSFER, ProcessOperationType.HISTORY_HANDLER_RETRACT, ProcessOperationType.ADMIN_JUMP),
    /**
     *  流程结束
     */
    FINISH(ProcessOperationType.PROCESS_FINISH),
    ;
    /**
     *  编码
     */
    private final List<String> operationTypes;

    ProcessCallbackType(ProcessOperationType... operationTypes) {
        if (operationTypes.length == 0) {
            throw new RuntimeException("流程操作类型不能为空");
        }
        this.operationTypes = Stream.of(operationTypes)
                .map(ProcessOperationType::getCode)
                .toList();
    }

    ProcessCallbackType(String... operationTypes) {
        if (operationTypes.length == 0) {
            throw new RuntimeException("流程操作类型不能为空");
        }
        this.operationTypes = Lists.newArrayList(operationTypes);
    }


    /**
     *  流程操作类型对应的事件
     */
    private static final Map<String, ProcessCallbackType> CALLBACK_MAP = initCallbackMap();

    /**
     *  初始化流程操作类型对应的事件
     * @return
     */
    private static Map<String, ProcessCallbackType> initCallbackMap() {
        return Stream.of(values())
                .flatMap(callbackType -> callbackType.getOperationTypes().stream()
                        .collect(Collectors.toMap(Function.identity(), type -> callbackType))
                        .entrySet()
                        .stream()
                )
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> {
                    throw new RuntimeException("流程操作类型不能重复");
                }));
    }

    /**
     *  根据流程操作类型，获取对应的回调
     * @param operationType
     * @return
     */
    public static ProcessCallbackType getCallbackType(String operationType) {
        return CALLBACK_MAP.get(operationType);
    }
}
