using System.Net;
using System.Text.Json;
using Serilog;

namespace SecureSharing.Infrastructure.Middleware;

public sealed class ExceptionHandlingMiddleware
{
    private readonly RequestDelegate nextRequestDelegate;
    private IWebHostEnvironment environment;

    public ExceptionHandlingMiddleware(
        RequestDelegate nextRequestDelegate,
        IWebHostEnvironment environment
    )
    {
        this.nextRequestDelegate = nextRequestDelegate ?? throw new ArgumentNullException(nameof(nextRequestDelegate));
        this.environment = environment ?? throw new ArgumentNullException(nameof(environment));
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            context.TraceIdentifier = Guid.NewGuid().ToString();
            await nextRequestDelegate(context);
        }
        catch (Exception ex)
        {
            await HandleGlobalExceptionAsync(context, ex);
        }
    }

    private async Task HandleGlobalExceptionAsync(HttpContext context, Exception ex)
    {
        try
        {
            await WriteResponseAsync(context, HttpStatusCode.InternalServerError,
                JsonSerializer.Serialize(ex.Message));
        }
        catch (Exception e)
        {
            await WriteResponseAsync(context, HttpStatusCode.InternalServerError,
                JsonSerializer.Serialize(e.Message));
        }

        var logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.File(@"AppData\Errors\log-.log", rollingInterval: RollingInterval.Day)
            .CreateLogger();
        logger.Error(ex, "Unhandled Exception" /* - Detected UserId: {UserId}" /*, context.User.GetUserId()*/);
    }

    private async Task WriteResponseAsync(HttpContext context, HttpStatusCode code, string jsonResponse)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)code;
        await context.Response.WriteAsync(jsonResponse);
    }
}