package tech.easyflow.ai.service.discovery;

import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.stereotype.Service;
import tech.easyflow.ai.entity.Model;
import tech.easyflow.ai.entity.ModelProvider;
import tech.easyflow.ai.mapper.ModelMapper;
import tech.easyflow.ai.service.ModelProviderService;
import tech.easyflow.common.web.exceptions.BusinessException;

import java.math.BigInteger;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 远端模型发现应用服务。
 */
@Service
public class RemoteModelDiscoveryService {

    /** 单次发现最多返回的可用模型数量。 */
    private static final int MAX_MODEL_COUNT = 1000;

    /** 服务商服务。 */
    private final ModelProviderService modelProviderService;
    /** 本地模型映射器。 */
    private final ModelMapper modelMapper;
    /** 静态适配表。 */
    private final RemoteModelProviderAdapterRegistry adapterRegistry;
    /** 受控 HTTP 客户端。 */
    private final RemoteModelHttpClient httpClient;
    /** 模型元数据解析器。 */
    private final RemoteModelMetadataResolver metadataResolver;

    /**
     * 创建远端模型发现服务。
     *
     * @param modelProviderService 服务商服务
     * @param modelMapper 本地模型映射器
     * @param adapterRegistry 静态适配表
     * @param httpClient 受控 HTTP 客户端
     * @param metadataResolver 模型元数据解析器
     */
    public RemoteModelDiscoveryService(ModelProviderService modelProviderService,
                                       ModelMapper modelMapper,
                                       RemoteModelProviderAdapterRegistry adapterRegistry,
                                       RemoteModelHttpClient httpClient,
                                       RemoteModelMetadataResolver metadataResolver) {
        this.modelProviderService = modelProviderService;
        this.modelMapper = modelMapper;
        this.adapterRegistry = adapterRegistry;
        this.httpClient = httpClient;
        this.metadataResolver = metadataResolver;
    }

    /**
     * 主动获取指定服务商的远端模型列表。
     *
     * @param providerId 服务商 ID
     * @return 已补全能力和本地添加状态的模型列表
     * @throws BusinessException 服务商不存在或远端发现失败时抛出
     */
    public RemoteModelListResult discover(BigInteger providerId) {
        if (providerId == null) {
            throw new BusinessException(400, 40031, "服务商 ID 不能为空");
        }
        ModelProvider provider = modelProviderService.getById(providerId);
        if (provider == null) {
            throw new BusinessException(404, 40431, "模型服务商不存在");
        }

        RemoteModelProviderAdapter adapter = adapterRegistry.get(provider.getProviderType());
        List<String> fetchedIds = adapter.fetchModelIds(provider, httpClient);
        LinkedHashSet<String> uniqueIds = normalizeModelIds(fetchedIds);
        Set<String> addedModelIds = loadAddedModelIds(providerId);

        List<String> supportedIds = uniqueIds.stream()
                .filter(modelId -> !metadataResolver.isUnsupportedGenerationModel(
                        provider.getProviderType(), modelId))
                .collect(Collectors.toList());
        boolean truncated = supportedIds.size() > MAX_MODEL_COUNT;
        List<RemoteModelDescriptor> descriptors = supportedIds.stream()
                .limit(MAX_MODEL_COUNT)
                .map(modelId -> metadataResolver.describe(
                        provider.getProviderType(), modelId, addedModelIds.contains(modelId)))
                .sorted(Comparator.comparing(RemoteModelDescriptor::getFamily,
                                String.CASE_INSENSITIVE_ORDER)
                        .thenComparing(RemoteModelDescriptor::getDisplayName,
                                String.CASE_INSENSITIVE_ORDER)
                        .thenComparing(RemoteModelDescriptor::getModelId))
                .collect(Collectors.toList());
        return new RemoteModelListResult(providerId, descriptors, truncated);
    }

    /**
     * 规范化、去重并过滤非法远端模型 ID。
     *
     * @param fetchedIds 适配器返回的原始列表
     * @return 保持远端顺序的唯一模型 ID
     */
    private LinkedHashSet<String> normalizeModelIds(List<String> fetchedIds) {
        LinkedHashSet<String> uniqueIds = new LinkedHashSet<>();
        if (fetchedIds == null) {
            return uniqueIds;
        }
        for (String modelId : fetchedIds) {
            if (modelId == null) {
                continue;
            }
            String normalized = modelId.trim();
            if (!normalized.isEmpty() && normalized.chars().noneMatch(Character::isISOControl)) {
                uniqueIds.add(normalized);
            }
        }
        return uniqueIds;
    }

    /**
     * 加载当前租户在指定服务商下已添加的原始模型 ID。
     *
     * @param providerId 服务商 ID
     * @return 已添加模型 ID 集合
     */
    private Set<String> loadAddedModelIds(BigInteger providerId) {
        QueryWrapper query = QueryWrapper.create().eq(Model::getProviderId, providerId);
        List<Model> models = modelMapper.selectListByQuery(query);
        return models.stream()
                .map(Model::getModelName)
                .filter(value -> value != null && !value.isBlank())
                .collect(Collectors.toSet());
    }
}
