using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;

namespace Nalu.Web.Infrastructure;

public class OpenRouterClient
{
    private readonly HttpClient _http;
    private readonly IConfiguration _config;
    private readonly ILogger<OpenRouterClient> _logger;

    public OpenRouterClient(HttpClient http, IConfiguration config, ILogger<OpenRouterClient> logger)
    {
        _http = http;
        _config = config;
        _logger = logger;
    }

    public async Task<LlmCallResult> ChatAsync(
        string systemPrompt,
        string userMessage,
        CancellationToken ct = default)
    {
        var model = _config["OpenRouter:Model"] ?? "mistralai/mistral-7b-instruct";
        var maxTokens = _config.GetValue<int>("OpenRouter:MaxTokens", 500);
        var temperature = _config.GetValue<double>("OpenRouter:Temperature", 0.1);

        var body = GroqClient.BuildRequestBody(model, systemPrompt, userMessage, maxTokens, temperature);

        try
        {
            using var request = new HttpRequestMessage(HttpMethod.Post, "chat/completions")
            {
                Content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
            };

            var response = await _http.SendAsync(request, ct);

            if (!response.IsSuccessStatusCode)
            {
                var err = await response.Content.ReadAsStringAsync(ct);
                _logger.LogError("OpenRouter error {Status}: {Body}", response.StatusCode, err);
                return new LlmCallResult { Error = $"OpenRouter {response.StatusCode}: {err}" };
            }

            var json = await response.Content.ReadAsStringAsync(ct);
            var doc = JsonNode.Parse(json);
            var content = doc?["choices"]?[0]?["message"]?["content"]?.GetValue<string>();

            if (content is null)
                return new LlmCallResult { Error = "Empty content in OpenRouter response" };

            var obj = JsonNode.Parse(content) as JsonObject;
            return obj is not null
                ? new LlmCallResult { Content = obj }
                : new LlmCallResult { Error = "OpenRouter returned non-object JSON" };
        }
        catch (Exception ex) when (ex is not OperationCanceledException)
        {
            _logger.LogError(ex, "OpenRouter call failed unexpectedly");
            return new LlmCallResult { Error = ex.Message };
        }
    }
}
