package tech.easyflow.agent.runtime;

import com.easyagents.agent.runtime.model.AgentHttpVersionPolicy;
import com.easyagents.agent.runtime.model.AgentModelProviderType;
import com.easyagents.agent.runtime.model.AgentModelSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tech.easyflow.ai.entity.Model;

import java.util.Locale;
import java.util.Map;

/**
 * 将 EasyFlow 模型配置映射为智能体运行时模型声明。
 */
public final class AgentModelSpecMapper {

    private static final Logger LOG = LoggerFactory.getLogger(AgentModelSpecMapper.class);

    /**
     * 禁止实例化工具类。
     */
    private AgentModelSpecMapper() {
    }

    /**
     * 按模型持久化配置创建运行时模型声明。
     *
     * @param model 已补齐供应商默认配置的模型
     * @return 运行时模型声明
     * @throws IllegalArgumentException 模型为空时抛出
     */
    public static AgentModelSpec fromModel(Model model) {
        return fromModel(model, Map.of());
    }

    /**
     * 按模型配置和 Agent 快照覆盖项创建运行时模型声明。
     *
     * @param model 已补齐供应商默认配置的模型
     * @param overrides Agent 发布快照中的模型覆盖项
     * @return 运行时模型声明
     * @throws IllegalArgumentException 模型为空时抛出
     */
    public static AgentModelSpec fromModel(Model model, Map<String, Object> overrides) {
        if (model == null) {
            throw new IllegalArgumentException("模型配置不能为空");
        }
        Map<String, Object> safeOverrides = overrides == null ? Map.of() : overrides;
        AgentModelSpec spec = new AgentModelSpec();
        String providerType = stringValue(
                safeOverrides,
                "providerType",
                model.getModelProvider() == null ? null : model.getModelProvider().getProviderType());
        spec.setProviderType(parseProviderType(providerType));
        spec.setModelName(stringValue(safeOverrides, "modelName", model.getModelName()));
        spec.setBaseUrl(stringValue(safeOverrides, "baseUrl", model.getEndpoint()));
        spec.setEndpointPath(stringValue(safeOverrides, "endpointPath", model.getRequestPath()));
        spec.setApiKey(stringValue(safeOverrides, "apiKey", model.getApiKey()));
        spec.setSupportImage(Boolean.TRUE.equals(model.getSupportImage()));
        spec.setSupportImageBase64Only(Boolean.TRUE.equals(model.getSupportImageB64Only()));
        spec.setHttpVersionPolicy(parseHttpVersionPolicy(model));
        spec.getMetadata().put("modelId", model.getId());
        if (providerType != null && !providerType.isBlank()) {
            spec.getMetadata().put("sourceProviderType", providerType);
        }
        return spec;
    }

    /**
     * 解析模型配置中的 Agent HTTP 版本策略。
     *
     * @param model 模型配置
     * @return HTTP 版本策略，缺失或非法时返回 AUTO
     */
    private static AgentHttpVersionPolicy parseHttpVersionPolicy(Model model) {
        Object rawPolicy = model.getOptions() == null
                ? null
                : model.getOptions().get("agentHttpVersionPolicy");
        if (rawPolicy == null || String.valueOf(rawPolicy).isBlank()) {
            return AgentHttpVersionPolicy.AUTO;
        }
        String normalizedPolicy = String.valueOf(rawPolicy).trim().toUpperCase(Locale.ROOT);
        try {
            return AgentHttpVersionPolicy.valueOf(normalizedPolicy);
        } catch (IllegalArgumentException exception) {
            LOG.warn("Invalid Agent HTTP version policy '{}' for model {}, fallback to AUTO",
                    rawPolicy, model.getId());
            return AgentHttpVersionPolicy.AUTO;
        }
    }

    /**
     * 解析 AgentScope 支持的模型供应商类型。
     *
     * @param providerType 供应商类型
     * @return 运行时供应商类型，未知值按 OpenAI-compatible 处理
     */
    private static AgentModelProviderType parseProviderType(String providerType) {
        if (providerType == null || providerType.isBlank()) {
            return AgentModelProviderType.OPENAI_COMPATIBLE;
        }
        try {
            return AgentModelProviderType.valueOf(providerType.trim().toUpperCase(Locale.ROOT));
        } catch (IllegalArgumentException ignored) {
            return AgentModelProviderType.OPENAI_COMPATIBLE;
        }
    }

    /**
     * 读取字符串覆盖项。
     *
     * @param values 配置映射
     * @param key 字段名
     * @param defaultValue 默认值
     * @return 覆盖值或默认值
     */
    private static String stringValue(Map<String, Object> values, String key, String defaultValue) {
        Object value = values.get(key);
        return value == null ? defaultValue : String.valueOf(value);
    }
}
