using OnlyOneAccessTemplate.Models;
using OnlyOneAccessTemplate.Services.OnlyOneAccessTemplate.Services;
using Polly;
using Polly.Extensions.Http;
using System.Text;
using System.Text.Json;

namespace OnlyOneAccessTemplate.Services
{
    public interface ITextConversionApiService
    {
        Task<string> ConvertToSentenceCaseAsync(string text);
        Task<string> ConvertToUpperCaseAsync(string text);
        Task<string> ConvertToLowerCaseAsync(string text);
        Task<bool> IsHealthyAsync();
    }

    public class TextConversionApiService : ITextConversionApiService
    {
        private readonly HttpClient _httpClient;
        private readonly ILogger<TextConversionApiService> _logger;
        private readonly IAsyncPolicy<HttpResponseMessage> _retryPolicy;
        private readonly string _baseUrl;

        public TextConversionApiService(
            HttpClient httpClient, 
            ILogger<TextConversionApiService> logger,
            IConfiguration configuration)
        {
            _httpClient = httpClient;
            _logger = logger;
            _baseUrl = configuration.GetValue<string>("TextConversionApi:BaseUrl") ?? "https://localhost:7071";

            // Configurar política de retry com Polly para HttpClient
            _retryPolicy = HttpPolicyExtensions
                .HandleTransientHttpError()
                .OrResult(msg => !msg.IsSuccessStatusCode)
                .WaitAndRetryAsync(
                    retryCount: 3,
                    sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                    onRetry: (outcome, timespan, retryCount, context) =>
                    {
                        _logger.LogWarning("Tentativa {RetryCount} de chamada à API após {Delay}ms. Status: {StatusCode}",
                            retryCount, timespan.TotalMilliseconds, outcome.Result?.StatusCode);
                    });

            // Configurar timeout
            _httpClient.Timeout = TimeSpan.FromSeconds(30);
        }

        public async Task<string> ConvertToSentenceCaseAsync(string text)
        {
            try
            {
                var request = new { Text = text };
                var response = await CallApiAsync("/api/text-conversion/sentence-case", request);
                return response.ConvertedText;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Erro ao converter texto para sentence case via API");
                throw;
            }
        }

        public async Task<string> ConvertToUpperCaseAsync(string text)
        {
            try
            {
                var request = new { Text = text };
                var response = await CallApiAsync("/api/text-conversion/upper-case", request);
                return response.ConvertedText;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Erro ao converter texto para maiúsculas via API");
                throw;
            }
        }

        public async Task<string> ConvertToLowerCaseAsync(string text)
        {
            try
            {
                var request = new { Text = text };
                var response = await CallApiAsync("/api/text-conversion/lower-case", request);
                return response.ConvertedText;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Erro ao converter texto para minúsculas via API");
                throw;
            }
        }

        public async Task<bool> IsHealthyAsync()
        {
            try
            {
                var response = await _retryPolicy.ExecuteAsync(async () =>
                {
                    return await _httpClient.GetAsync($"{_baseUrl}/api/text-conversion/health");
                });

                return response.IsSuccessStatusCode;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Erro ao verificar saúde da API de conversão de texto");
                return false;
            }
        }

        private async Task<TextConversionApiResponse> CallApiAsync(string endpoint, object request)
        {
            var json = JsonSerializer.Serialize(request);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            var response = await _retryPolicy.ExecuteAsync(async () =>
            {
                return await _httpClient.PostAsync($"{_baseUrl}{endpoint}", content);
            });

            if (!response.IsSuccessStatusCode)
            {
                var errorContent = await response.Content.ReadAsStringAsync();
                throw new HttpRequestException($"API call failed with status {response.StatusCode}: {errorContent}");
            }

            var responseContent = await response.Content.ReadAsStringAsync();
            var result = JsonSerializer.Deserialize<TextConversionApiResponse>(responseContent, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            });

            if (result == null || !result.Success)
            {
                throw new InvalidOperationException($"API returned unsuccessful response: {result?.ErrorMessage}");
            }

            return result;
        }
    }

    public class TextConversionApiResponse
    {
        public bool Success { get; set; }
        public string OriginalText { get; set; } = string.Empty;
        public string ConvertedText { get; set; } = string.Empty;
        public DateTime ProcessedAt { get; set; }
        public string? ErrorMessage { get; set; }
        public Dictionary<string, object>? Metadata { get; set; }
    }

    // Novo serviço que substitui o UpperLowerConversorService usando a API
    public class ApiBasedSentenceConverterService : BaseConverterService
    {
        private readonly ITextConversionApiService _apiService;

        public override string ConverterType => "text-case-sentence";
        public override string ConverterName => "Maiúsculas para minúsculas";

        public ApiBasedSentenceConverterService(
            ILogger<ApiBasedSentenceConverterService> logger, 
            IConfiguration configuration,
            ITextConversionApiService apiService)
            : base(logger, configuration) 
        {
            _apiService = apiService;
        }

        public override async Task<ConversionResult> ConvertAsync(ConversionRequest request)
        {
            try
            {
                var resultado = await _apiService.ConvertToSentenceCaseAsync(request.TextInput);
                return new ConversionResult(true, OutputText: resultado);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Erro na conversão via API");
                return new ConversionResult(false, ErrorMessage: "Erro ao processar via API");
            }
        }

        public override ConverterConfiguration GetConfiguration(string language)
        {
            var texts = GetLocalizedTexts(language);

            texts["ConverterTitle"] = language switch
            {
                "en" => "Sentence Case Convert",
                "es" => "Convertir a Mayúscula Inicial",
                _ => "Converter para primeira maiúscula"
            };

            return new ConverterConfiguration
            {
                ConverterType = "text",
                OutputType = "text",
                HasAdvancedOptions = false,
                AllowShare = true,
                LocalizedTexts = texts
            };
        }
    }
}