package com.infoepoch.pms.agent.observability.ai;

import org.springframework.ai.chat.model.ChatModel;
import org.springframework.util.StringUtils;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 统一模型调用入口。
 */
public class AiModelInvoker {

    private final AiObservationLogger logger;
    private final AiObservationSupport support;

    public AiModelInvoker(AiObservationLogger logger, AiObservationSupport support) {
        this.logger = logger;
        this.support = support;
    }

    public String call(AiObservationContext context, String prompt, ChatModel chatModel) {
        String requestStage = AiReadableLogSupport.stageWithScene(context, "模型请求");
        logger.info(
                AiModelInvoker.class,
                AiReadableLogSupport.formatModelPrompt(context, requestStage, prompt),
                context,
                buildRequestFields(prompt, context)
        );
        try {
            String response = support.withObservationContext(context, () -> chatModel.call(prompt));
            String responseStage = AiReadableLogSupport.stageWithScene(context, "模型完整返回");
            logger.info(
                    AiModelInvoker.class,
                    AiReadableLogSupport.formatModelResponse(context, responseStage, response),
                    context,
                    buildResponseFields(response)
            );
            return response;
        } catch (RuntimeException exception) {
            String errorStage = AiReadableLogSupport.stageWithScene(context, "模型异常");
            logger.error(
                    AiModelInvoker.class,
                    AiReadableLogSupport.format(
                            context,
                            errorStage,
                            "模型调用失败，异常=%s".formatted(resolveErrorMessage(exception))
                    ),
                    context,
                    Map.of(
                            "status", "failed",
                            "error.type", exception.getClass().getName(),
                            "error.message", resolveErrorMessage(exception)
                    ),
                    exception
            );
            throw exception;
        }
    }

    private Map<String, Object> buildRequestFields(String prompt, AiObservationContext context) {
        Map<String, Object> fields = new LinkedHashMap<>();
        fields.put("status", "started");
        fields.put("ai.input.preview", support.renderPayload(prompt));
        fields.put("ai.input.length", prompt == null ? 0 : prompt.length());
        if (StringUtils.hasText(context.modelProvider())) {
            fields.put("ai.model.provider", context.modelProvider());
        }
        if (StringUtils.hasText(context.modelName())) {
            fields.put("ai.model.name", context.modelName());
        }
        return fields;
    }

    private Map<String, Object> buildResponseFields(String response) {
        return Map.of(
                "status", "finished",
                "ai.output.preview", support.renderPayload(response),
                "ai.output.length", response == null ? 0 : response.length()
        );
    }

    private String resolveErrorMessage(Throwable error) {
        return error == null || !StringUtils.hasText(error.getMessage()) ? "unknown" : error.getMessage();
    }
}
