using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Options;

namespace MealPlan.Api.Services.AI;

public class OpenAiChatService : IOpenAiChatService
{
    private readonly HttpClient _http;
    private readonly OpenAiOptions _options;
    private readonly ILogger<OpenAiChatService> _logger;

    public OpenAiChatService(HttpClient http, IOptions<OpenAiOptions> options, ILogger<OpenAiChatService> logger)
    {
        _http = http;
        _options = options.Value;
        _logger = logger;
    }

    public bool IsConfigured => _options.IsConfigured;

    public async Task<string> CompleteJsonAsync(
        string systemPrompt,
        string userPrompt,
        OpenAiUseCase useCase = OpenAiUseCase.Default,
        CancellationToken ct = default)
    {
        if (!IsConfigured)
        {
            throw new InvalidOperationException(
                "OpenAI is not configured. Set OpenAI__ApiKey in appsettings.Local.json.");
        }

        var model = _options.ResolveModel(useCase);
        var payload = new
        {
            model,
            max_tokens = _options.MaxTokens,
            response_format = new { type = "json_object" },
            messages = new[]
            {
                new { role = "system", content = systemPrompt },
                new { role = "user", content = userPrompt },
            },
        };

        using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.openai.com/v1/chat/completions");
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _options.ApiKey);
        request.Content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");

        using var response = await _http.SendAsync(request, ct);
        var body = await response.Content.ReadAsStringAsync(ct);
        if (!response.IsSuccessStatusCode)
        {
            _logger.LogWarning("OpenAI API error {Status}: {Body}", response.StatusCode, body);
            throw new InvalidOperationException("OpenAI request failed. Check API key and quota.");
        }

        using var doc = JsonDocument.Parse(body);
        var content = doc.RootElement
            .GetProperty("choices")[0]
            .GetProperty("message")
            .GetProperty("content")
            .GetString() ?? "{}";

        return StripMarkdownFence(content);
    }

    private static string StripMarkdownFence(string content)
    {
        var trimmed = content.Trim();
        if (!trimmed.StartsWith("```", StringComparison.Ordinal)) return trimmed;
        var firstNewline = trimmed.IndexOf('\n');
        if (firstNewline < 0) return trimmed;
        var endFence = trimmed.LastIndexOf("```", StringComparison.Ordinal);
        if (endFence <= firstNewline) return trimmed;
        return trimmed[(firstNewline + 1)..endFence].Trim();
    }
}
