using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Text.Json;

namespace API_Access_Control.Middlewares;

public class LoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<LoggingMiddleware> _logger;

    public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var request = context.Request;
        var log = new
        {
            Timestamp = DateTime.UtcNow,
            Request = new
            {
                Method = request.Method,
                Path = request.Path,
                QueryString = request.QueryString.ToString(),
                Headers = request.Headers.ToDictionary(x => x.Key, x => x.Value.ToString())
            }
        };

        _logger.LogInformation(JsonSerializer.Serialize(log));

        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            var errorLog = new
            {
                Error = ex.Message,
                StackTrace = ex.StackTrace,
                Timestamp = DateTime.UtcNow
            };

            _logger.LogError(JsonSerializer.Serialize(errorLog));
        }
        finally
        {
            var response = context.Response;
            var responseLog = new
            {
                Timestamp = DateTime.UtcNow,
                Response = new
                {
                    StatusCode = response.StatusCode,
                    ContentType = response.ContentType,
                    Headers = response.Headers.ToDictionary(x => x.Key, x => x.Value.ToString())
                }
            };

            _logger.LogInformation(JsonSerializer.Serialize(responseLog));
        }
    }
}