package tech.easyflow.ai.service.discovery;

import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.stereotype.Component;
import tech.easyflow.ai.entity.ModelProvider;
import tech.easyflow.common.web.exceptions.BusinessException;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * OpenAI-compatible {@code data[].id} 模型目录适配器。
 */
@Component
public class OpenAiCompatibleRemoteModelAdapter implements RemoteModelProviderAdapter {

    /**
     * 获取 OpenAI-compatible 模型 ID。
     *
     * @param provider 已保存的服务商配置
     * @param httpClient 受控 HTTP 客户端
     * @return 原始模型 ID 列表
     * @throws BusinessException 对话路径或响应结构不兼容时抛出
     */
    @Override
    public List<String> fetchModelIds(ModelProvider provider, RemoteModelHttpClient httpClient) {
        String modelsPath = deriveModelsPath(provider.getChatPath());
        Map<String, String> query = "siliconflow".equals(normalize(provider.getProviderType()))
                ? Map.of("type", "text") : Map.of();
        JsonNode root = httpClient.getJson(provider, modelsPath, query);
        JsonNode data = root.get("data");
        if (data == null || !data.isArray()) {
            throw new BusinessException(502, 50231, "模型列表响应格式不兼容");
        }
        List<String> modelIds = new ArrayList<>();
        data.forEach(item -> addText(modelIds, item.get("id")));
        return modelIds;
    }

    /**
     * 从对话路径推导同版本的 models 路径。
     *
     * @param chatPath 已保存的对话路径
     * @return models 路径
     * @throws BusinessException 路径不符合兼容协议时抛出
     */
    public String deriveModelsPath(String chatPath) {
        if (chatPath == null || chatPath.isBlank()) {
            return "/v1/models";
        }
        String normalized = chatPath.trim();
        String suffix = "/chat/completions";
        if (!normalized.toLowerCase(Locale.ROOT).endsWith(suffix)) {
            throw new BusinessException(422, 42231, "当前服务暂不支持获取模型列表");
        }
        String prefix = normalized.substring(0, normalized.length() - suffix.length());
        return (prefix.isBlank() ? "" : prefix) + "/models";
    }

    /**
     * 添加非空文本模型 ID。
     *
     * @param target 结果列表
     * @param value JSON 文本节点
     */
    private void addText(List<String> target, JsonNode value) {
        if (value != null && value.isTextual() && !value.asText().isBlank()) {
            target.add(value.asText());
        }
    }

    /**
     * 规范化供应商类型。
     *
     * @param value 原始供应商类型
     * @return 小写供应商类型
     */
    private String normalize(String value) {
        return value == null ? "" : value.trim().toLowerCase(Locale.ROOT);
    }
}
