package tech.easyflow.ai.invoke.service.impl;

import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Service;
import tech.easyflow.ai.entity.Model;
import tech.easyflow.ai.invoke.exception.ModelInvokeException;
import tech.easyflow.ai.invoke.model.UnifiedChatRequest;
import tech.easyflow.ai.invoke.model.UnifiedChatResponse;
import tech.easyflow.ai.invoke.model.UnifiedContentPart;
import tech.easyflow.ai.invoke.model.UnifiedMessage;
import tech.easyflow.ai.invoke.provider.ModelProviderGateway;
import tech.easyflow.ai.invoke.provider.ModelProviderGatewayRegistry;
import tech.easyflow.ai.invoke.provider.UnifiedChatChunkObserver;
import tech.easyflow.ai.invoke.service.UnifiedModelInvokeService;
import tech.easyflow.ai.service.ModelService;

import java.util.List;

@Service
public class UnifiedModelInvokeServiceImpl implements UnifiedModelInvokeService {

    private final ModelService modelService;
    private final ModelProviderGatewayRegistry gatewayRegistry;

    public UnifiedModelInvokeServiceImpl(ModelService modelService,
                                         ModelProviderGatewayRegistry gatewayRegistry) {
        this.modelService = modelService;
        this.gatewayRegistry = gatewayRegistry;
    }

    @Override
    public UnifiedChatResponse chat(UnifiedChatRequest request) {
        Model model = resolveModel(request);
        validateRequestAgainstModel(model, request);
        ModelProviderGateway gateway = gatewayRegistry.getGateway(model.getModelProvider().getProviderType());
        return gateway.chat(model, request);
    }

    @Override
    public void chatStream(UnifiedChatRequest request, UnifiedChatChunkObserver observer) {
        Model model = resolveModel(request);
        validateRequestAgainstModel(model, request);
        ModelProviderGateway gateway = gatewayRegistry.getGateway(model.getModelProvider().getProviderType());
        gateway.chatStream(model, request, observer);
    }

    private Model resolveModel(UnifiedChatRequest request) {
        if (request == null || StrUtil.isBlank(request.getModel())) {
            throw ModelInvokeException.badRequest("model 不能为空", "model", "model_required");
        }
        Model model = modelService.getModelInstanceByInvokeCode(request.getModel());
        if (model == null) {
            throw ModelInvokeException.notFound("未找到可调用模型: " + request.getModel());
        }
        if (!Boolean.TRUE.equals(model.getPublishEnabled())) {
            throw ModelInvokeException.badRequest("当前模型未开启 API 调用发布", "model", "model_not_published");
        }
        if (!Model.MODEL_TYPES[0].equals(model.getModelType())) {
            throw ModelInvokeException.badRequest("当前模型不是 chatModel，无法通过 chat/completions 调用", "model", "model_type_mismatch");
        }
        if (model.getModelProvider() == null || StrUtil.isBlank(model.getModelProvider().getProviderType())) {
            throw ModelInvokeException.badRequest("当前模型缺少 providerType 配置", "model", "provider_type_missing");
        }
        return model;
    }

    private void validateRequestAgainstModel(Model model, UnifiedChatRequest request) {
        List<UnifiedMessage> messages = request.getMessages();
        if (messages == null || messages.isEmpty()) {
            throw ModelInvokeException.badRequest("messages 不能为空", "messages", "messages_required");
        }
        if (hasImageInput(messages)) {
            if (!Boolean.TRUE.equals(model.getSupportImage())) {
                throw ModelInvokeException.badRequest("当前模型不支持图片输入", "messages", "image_not_supported");
            }
            if (Boolean.TRUE.equals(model.getSupportImageB64Only()) && hasNonBase64Image(messages)) {
                throw ModelInvokeException.badRequest("当前模型仅支持 base64 图片输入", "messages", "image_base64_only");
            }
        }
        if (request.getTools() != null && !request.getTools().isEmpty() && !Boolean.TRUE.equals(model.getSupportTool())) {
            throw ModelInvokeException.badRequest("当前模型不支持 tools 参数", "tools", "tool_not_supported");
        }
        if (hasToolMessage(messages) && !Boolean.TRUE.equals(model.getSupportToolMessage())) {
            throw ModelInvokeException.badRequest("当前模型不支持 tool 消息透传", "messages", "tool_message_not_supported");
        }
    }

    private boolean hasImageInput(List<UnifiedMessage> messages) {
        return messages.stream()
                .map(UnifiedMessage::getContentParts)
                .filter(parts -> parts != null && !parts.isEmpty())
                .flatMap(List::stream)
                .anyMatch(part -> "image_url".equals(part.getType()));
    }

    private boolean hasNonBase64Image(List<UnifiedMessage> messages) {
        return messages.stream()
                .map(UnifiedMessage::getContentParts)
                .filter(parts -> parts != null && !parts.isEmpty())
                .flatMap(List::stream)
                .filter(part -> "image_url".equals(part.getType()))
                .map(UnifiedContentPart::getImageUrl)
                .filter(imageUrl -> imageUrl != null && StrUtil.isNotBlank(imageUrl.getUrl()))
                .anyMatch(imageUrl -> !StrUtil.startWithIgnoreCase(imageUrl.getUrl(), "data:"));
    }

    private boolean hasToolMessage(List<UnifiedMessage> messages) {
        return messages.stream().anyMatch(message ->
                StrUtil.equals(message.getRole(), "tool")
                        || (message.getToolCalls() != null && !message.getToolCalls().isEmpty())
                        || StrUtil.isNotBlank(message.getToolCallId())
        );
    }
}
