// PRE-GENERATED (design session). Google Gemini provider via JSON response mode. Untested.
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;

namespace DansoriEQ.Core.Ai;

public sealed class GeminiProvider : IAiEqProvider
{
    private readonly HttpClient _http;
    private readonly string _key;
    private readonly string _model;

    private const string JsonShape =
        "\n\nReturn ONLY a JSON object: {\"preamp_db\":number,\"replace\":boolean," +
        "\"filters\":[{\"type\":\"PK|LSC|HSC\",\"fc\":number,\"gain\":number,\"q\":number,\"enabled\":boolean}]," +
        "\"explanation\":string}.";

    public GeminiProvider(string apiKey, string? model = null, HttpClient? http = null)
    {
        _key = apiKey;
        _model = string.IsNullOrWhiteSpace(model) ? "gemini-2.0-flash" : model!;
        _http = http ?? new HttpClient();
    }

    public async Task<EqDelta> RequestEqAsync(string headphoneName, string type, string currentEqText,
                                              string userRequest, CancellationToken ct = default)
    {
        var url = $"https://generativelanguage.googleapis.com/v1beta/models/{_model}:generateContent?key={Uri.EscapeDataString(_key)}";
        var body = new JsonObject
        {
            ["systemInstruction"] = new JsonObject
            {
                ["parts"] = new JsonArray(new JsonObject { ["text"] = EqPromptBuilder.SystemPrompt + JsonShape })
            },
            ["contents"] = new JsonArray(new JsonObject
            {
                ["role"] = "user",
                ["parts"] = new JsonArray(new JsonObject { ["text"] = EqPromptBuilder.BuildUserContext(headphoneName, type, currentEqText, userRequest) })
            }),
            ["generationConfig"] = new JsonObject { ["responseMimeType"] = "application/json" }
        };

        using var req = new HttpRequestMessage(HttpMethod.Post, url)
        { Content = new StringContent(body.ToJsonString(), Encoding.UTF8, "application/json") };
        using var resp = await _http.SendAsync(req, ct);
        var json = await resp.Content.ReadAsStringAsync(ct);
        if (!resp.IsSuccessStatusCode)
            throw new InvalidOperationException($"Gemini 요청 실패 ({(int)resp.StatusCode}): {json}");

        using var doc = JsonDocument.Parse(json);
        var text = doc.RootElement.GetProperty("candidates")[0].GetProperty("content")
                      .GetProperty("parts")[0].GetProperty("text").GetString() ?? "{}";
        return EqDeltaParser.FromJsonText(text);
    }
}
