using System.Diagnostics;

namespace KArtSell.Host.Infrastructure;

/// <summary>
/// Establishes one correlation identifier at the HTTP boundary.
/// Endpoint code may use TraceIdentifier or Items[CorrelationId], but both resolve
/// to the same value and the response exposes it for support/replay tracing.
/// </summary>
public sealed class CorrelationIdMiddleware(RequestDelegate next, ILogger<CorrelationIdMiddleware> logger)
{
    public async Task InvokeAsync(HttpContext context)
    {
        var correlationId = ReadCorrelationId(context.Request.Headers["X-Correlation-Id"]);

        context.TraceIdentifier = correlationId.ToString("D");
        context.Items["CorrelationId"] = correlationId;
        context.Response.Headers["X-Correlation-Id"] = correlationId.ToString("D");
        Activity.Current?.SetTag("kartsell.correlation_id", correlationId.ToString("D"));

        using (logger.BeginScope(new Dictionary<string, object?>
        {
            ["CorrelationId"] = correlationId,
        }))
        {
            await next(context);
        }
    }

    private static Guid ReadCorrelationId(string? headerValue) =>
        Guid.TryParse(headerValue, out var correlationId) && correlationId != Guid.Empty
            ? correlationId
            : Guid.NewGuid();
}
