// PRE-GENERATED (design session). Local Ollama provider via /api/chat (format:json). Untested.
// For best reliability with small models, dev session can add a GBNF grammar constraint.
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 OllamaProvider : IAiEqProvider
{
    private const string Endpoint = "http://localhost:11434/api/chat";
    private readonly HttpClient _http = new() { Timeout = TimeSpan.FromMinutes(5) };
    private readonly string _model;

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

    public OllamaProvider(string model)
        => _model = string.IsNullOrWhiteSpace(model) ? "phi3.5" : model;

    public async Task<EqDelta> RequestEqAsync(string headphoneName, string type, string currentEqText,
                                              string userRequest, CancellationToken ct = default)
    {
        var body = new JsonObject
        {
            ["model"] = _model,
            ["stream"] = false,
            ["format"] = "json",
            ["messages"] = new JsonArray(
                new JsonObject { ["role"] = "system", ["content"] = EqPromptBuilder.SystemPrompt + JsonShape },
                new JsonObject { ["role"] = "user", ["content"] = EqPromptBuilder.BuildUserContext(headphoneName, type, currentEqText, userRequest) })
        };

        using var req = new HttpRequestMessage(HttpMethod.Post, Endpoint)
        { 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($"Ollama 요청 실패 ({(int)resp.StatusCode}): {json}");

        using var doc = JsonDocument.Parse(json);
        var content = doc.RootElement.GetProperty("message").GetProperty("content").GetString() ?? "{}";
        return EqDeltaParser.FromJsonText(content);
    }
}
