package tech.easyflow.publicapi.dto;

import com.easyagents.flow.core.chain.ChainStatus;
import com.easyagents.flow.core.chain.NodeStatus;
import com.fasterxml.jackson.annotation.JsonValue;

/**
 * 工作流 Public API 的可读执行状态。
 */
public enum PublicWorkflowExecutionStatus {

    /** 尚未开始。 */
    READY("ready", false),
    /** 正在执行。 */
    RUNNING("running", false),
    /** 等待外部参数恢复。 */
    SUSPENDED("suspended", false),
    /** 执行发生暂态错误，运行时仍可能继续处理。 */
    ERROR("error", false),
    /** 已成功完成。 */
    DONE("done", true),
    /** 已失败结束。 */
    FAILED("failed", true),
    /** 已取消。 */
    CANCELLED("cancelled", true),
    /** 无法识别的状态。 */
    UNKNOWN("unknown", false);

    /** 对外字符串值。 */
    private final String value;
    /** 是否为终态。 */
    private final boolean terminal;

    /**
     * 创建公开执行状态。
     *
     * @param value 对外字符串值
     * @param terminal 是否为终态
     */
    PublicWorkflowExecutionStatus(
            String value,
            boolean terminal) {
        this.value = value;
        this.terminal = terminal;
    }

    /**
     * 获取 JSON 响应中的状态值。
     *
     * @return 小写状态值
     */
    @JsonValue
    public String getValue() {
        return value;
    }

    /**
     * 判断是否为终态。
     *
     * @return 已结束时返回 {@code true}
     */
    public boolean isTerminal() {
        return terminal;
    }

    /**
     * 将内部工作流状态转换为公开枚举。
     *
     * @param status 内部数值状态
     * @return 公开状态枚举
     */
    public static PublicWorkflowExecutionStatus fromChainStatus(
            Integer status) {
        if (status == null) {
            return UNKNOWN;
        }
        ChainStatus chainStatus = ChainStatus.fromValue(status);
        if (chainStatus == null) {
            return UNKNOWN;
        }
        return switch (chainStatus) {
            case READY -> READY;
            case RUNNING -> RUNNING;
            case SUSPEND -> SUSPENDED;
            case ERROR -> ERROR;
            case SUCCEEDED -> DONE;
            case FAILED -> FAILED;
            case CANCELLED -> CANCELLED;
        };
    }

    /**
     * 将内部节点状态转换为公开枚举。
     *
     * @param status 内部数值状态
     * @return 公开状态枚举
     */
    public static PublicWorkflowExecutionStatus fromNodeStatus(
            Integer status) {
        if (status == null) {
            return UNKNOWN;
        }
        NodeStatus nodeStatus = NodeStatus.fromValue(status);
        if (nodeStatus == null) {
            return UNKNOWN;
        }
        return switch (nodeStatus) {
            case READY -> READY;
            case RUNNING -> RUNNING;
            case SUSPEND -> SUSPENDED;
            case ERROR -> ERROR;
            case SUCCEEDED -> DONE;
            case FAILED -> FAILED;
        };
    }
}
