using System.Net;
using System.Text.Json;
using Microsoft.Extensions.Logging;

namespace LittleShop.Client.Http;

public class ErrorHandlingMiddleware : DelegatingHandler
{
    private readonly ILogger<ErrorHandlingMiddleware> _logger;
    
    public ErrorHandlingMiddleware(ILogger<ErrorHandlingMiddleware> logger)
    {
        _logger = logger;
    }
    
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        try
        {
            var response = await base.SendAsync(request, cancellationToken);
            
            // Log errors but don't throw - let the service layer handle the response
            if (!response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync(cancellationToken);
                _logger.LogWarning(
                    "HTTP {StatusCode} for {Method} {Uri}: {Content}",
                    (int)response.StatusCode,
                    request.Method,
                    request.RequestUri,
                    content);
                    
                // Try to parse error response
                if (!string.IsNullOrEmpty(content))
                {
                    try
                    {
                        var errorResponse = JsonSerializer.Deserialize<ErrorResponse>(content,
                            new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
                            
                        if (errorResponse != null && !string.IsNullOrEmpty(errorResponse.Message))
                        {
                            // Replace content with structured error message
                            response.Content = new StringContent(errorResponse.Message);
                        }
                    }
                    catch
                    {
                        // If we can't parse the error, leave original content
                    }
                }
            }
            
            return response;
        }
        catch (TaskCanceledException ex)
        {
            _logger.LogError(ex, "Request timeout for {Method} {Uri}", 
                request.Method, request.RequestUri);
            
            return new HttpResponseMessage(HttpStatusCode.RequestTimeout)
            {
                Content = new StringContent("Request timed out"),
                RequestMessage = request
            };
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "Network error for {Method} {Uri}", 
                request.Method, request.RequestUri);
            
            return new HttpResponseMessage(HttpStatusCode.ServiceUnavailable)
            {
                Content = new StringContent($"Network error: {ex.Message}"),
                RequestMessage = request
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unexpected error for {Method} {Uri}", 
                request.Method, request.RequestUri);
            
            return new HttpResponseMessage(HttpStatusCode.InternalServerError)
            {
                Content = new StringContent($"Unexpected error: {ex.Message}"),
                RequestMessage = request
            };
        }
    }
    
    private class ErrorResponse
    {
        public string? Message { get; set; }
        public string? Error { get; set; }
        public Dictionary<string, string[]>? Errors { get; set; }
    }
}