using System.Text;
using System.Text.Json;
using KiMailOrderAgent.Models;
using KiMailOrderAgent.Settings;
using Microsoft.Extensions.Options;

namespace KiMailOrderAgent.Agents;

public class CorrectionAgent
{
    private readonly HttpClient _httpClient;
    private readonly AgentSettings _settings;

    public CorrectionAgent(HttpClient httpClient, IOptions<AgentSettings> options)
    {
        _httpClient = httpClient;
        _settings = options.Value;
    }

    public async Task<ExtractedOrder?> ApplyCorrectionAsync(
        ExtractedOrder currentOrder,
        string correctionText,
        CancellationToken cancellationToken)
    {
        var currentOrderJson = JsonSerializer.Serialize(currentOrder, new JsonSerializerOptions
        {
            WriteIndented = true
        });

        var prompt = $$"""
Du bist ein System zur Korrektur von Bestellungen.

Aktuelle Bestellung:
{{currentOrderJson}}

Korrektur vom Benutzer:
{{correctionText}}

Ändere die Bestellung entsprechend der Korrektur.
Gib NUR gültiges JSON im gleichen Format der Bestellung zurück.
Keine Markdown-Codeblöcke. Keine Erklärung.
""";

        var url =
            $"https://generativelanguage.googleapis.com/v1beta/models/{_settings.Model}:generateContent";

        using var request = new HttpRequestMessage(HttpMethod.Post, url);
        request.Headers.Add("x-goog-api-key", _settings.ApiKey);

        var body = new
        {
            contents = new[]
            {
                new
                {
                    parts = new[]
                    {
                        new { text = prompt }
                    }
                }
            }
        };

        request.Content = new StringContent(
            JsonSerializer.Serialize(body),
            Encoding.UTF8,
            "application/json");

        using var response = await _httpClient.SendAsync(request, cancellationToken);
        var responseText = await response.Content.ReadAsStringAsync(cancellationToken);

        if (!response.IsSuccessStatusCode)
            throw new Exception($"Gemini Fehler: {response.StatusCode} - {responseText}");

        var geminiText = ExtractTextFromGeminiResponse(responseText);

        if (string.IsNullOrWhiteSpace(geminiText))
            return null;

        geminiText = CleanJson(geminiText);

        return JsonSerializer.Deserialize<ExtractedOrder>(geminiText, new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        });
    }

    private static string? ExtractTextFromGeminiResponse(string responseText)
    {
        using var doc = JsonDocument.Parse(responseText);

        return doc.RootElement
            .GetProperty("candidates")[0]
            .GetProperty("content")
            .GetProperty("parts")[0]
            .GetProperty("text")
            .GetString();
    }

    private static string CleanJson(string text)
    {
        return text
            .Replace("```json", "")
            .Replace("```", "")
            .Trim();
    }
}