using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;

namespace Mindforge.API.Providers
{
    public class OpenAIApiProvider : ILlmApiProvider
    {
        private readonly HttpClient _httpClient;
        private readonly IConfiguration _configuration;
        private readonly ILogger<OpenAIApiProvider> _logger;

        public OpenAIApiProvider(HttpClient httpClient, IConfiguration configuration, ILogger<OpenAIApiProvider> logger)
        {
            _httpClient = httpClient;
            _httpClient.Timeout = TimeSpan.FromMinutes(5);
            _configuration = configuration;
            _logger = logger;
        }

        public async Task<string> SendRequestAsync(string systemPrompt, string userPrompt, string model)
        {
            var apiKey = _configuration["OPENAI_API_KEY"];
            if (string.IsNullOrEmpty(apiKey))
            {
                throw new Exception("OPENAI_API_KEY not found in configuration.");
            }

            var apiBase = "https://api.openai.com/v1";
            var url = $"{apiBase.TrimEnd('/')}/responses";

            var reqBody = new
            {
                model = model,
                input = new[]
                {
                    new { role = "developer", content = systemPrompt },
                    new { role = "user", content = userPrompt }
                },
                reasoning = new
                {
                    effort = "low"
                }
            };

            var jsonBody = JsonSerializer.Serialize(reqBody);

            Exception? lastErr = null;

            for (int i = 0; i < 5; i++)
            {
                using var request = new HttpRequestMessage(HttpMethod.Post, url);
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
                request.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");

                try
                {
                    var response = await _httpClient.SendAsync(request);
                    var responseBody = await response.Content.ReadAsStringAsync();

                    if (!response.IsSuccessStatusCode)
                    {
                        lastErr = new Exception($"OpenAI API error status {(int)response.StatusCode}: {responseBody}");
                        await Task.Delay(TimeSpan.FromSeconds(1 << i));
                        continue;
                    }

                    var result = JsonSerializer.Deserialize<JsonElement>(responseBody);
                    if (result.TryGetProperty("output", out var outputArray))
                    {
                        foreach (var outputItem in outputArray.EnumerateArray())
                        {
                            if (outputItem.TryGetProperty("content", out var contentArray))
                            {
                                foreach (var contentItem in contentArray.EnumerateArray())
                                {
                                    if (contentItem.TryGetProperty("text", out var textContent))
                                    {
                                        return textContent.GetString() ?? string.Empty;
                                    }
                                }
                            }
                        }
                    }

                    _logger.LogWarning("OpenAI API raw response: {responseBody}", responseBody);

                    throw new Exception("empty response from OpenAI API");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error in OpenAI API request");
                    lastErr = ex;
                    await Task.Delay(TimeSpan.FromSeconds(1 << i));
                }
            }

            throw new Exception($"failed to get OpenAI response after 5 attempts. Last error: {lastErr?.Message}", lastErr);
        }

        public async Task<string> SendRequestBatchAsync(string systemPrompt, string userPrompt, string model)
        {
            throw new NotImplementedException();
        }
    }
}
