using System.Text.Json;

namespace WorkClub.Api.Middleware;

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

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

    public async Task InvokeAsync(HttpContext context)
    {
        _logger.LogInformation("TenantValidationMiddleware: Processing request for {Path}", context.Request.Path);
        if (!context.User.Identity?.IsAuthenticated ?? true)
        {
            await _next(context);
            return;
        }

    // Exempt bootstrap, admin, and debug endpoints from tenant validation
    if (context.Request.Path.StartsWithSegments("/api/clubs/me") ||
        context.Request.Path.StartsWithSegments("/api/admin") ||
        context.Request.Path.StartsWithSegments("/api/debug"))
    {
      _logger.LogInformation("TenantValidationMiddleware: Exempting {Path} from tenant validation", context.Request.Path);
      await _next(context);
      return;
    }

        if (!context.Request.Headers.TryGetValue("X-Tenant-Id", out var tenantIdHeader) ||
            string.IsNullOrWhiteSpace(tenantIdHeader))
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
            await context.Response.WriteAsJsonAsync(new { error = "X-Tenant-Id header is required" });
            return;
        }

        var requestedTenantId = tenantIdHeader.ToString();
        var clubsClaim = context.User.FindFirst("clubs")?.Value;

        if (string.IsNullOrEmpty(clubsClaim))
        {
        // NEW: Skip check if user is a global admin
        var realmAccess = context.User.FindFirst("realm_access")?.Value;
        if (!string.IsNullOrEmpty(realmAccess) && IsAdminUser(realmAccess))
        {
          await _next(context);
          return;
        }

    static bool IsAdminUser(string realmAccess)
    {
      try
      {
        using var doc = System.Text.Json.JsonDocument.Parse(realmAccess);
        if (doc.RootElement.TryGetProperty("roles", out var rolesElement) &&
            rolesElement.ValueKind == System.Text.Json.JsonValueKind.Array)
        {
          foreach (var role in rolesElement.EnumerateArray())
          {
            if (role.GetString()?.Equals("admin", StringComparison.OrdinalIgnoreCase) == true)
              return true;
          }
        }
      }
      catch
      {
        // If JSON parsing fails, fallback to string contains check
        return realmAccess.Contains("admin", StringComparison.OrdinalIgnoreCase);
      }
      return false;
    }

            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            await context.Response.WriteAsJsonAsync(new { error = "User does not have clubs claim" });
            return;
        }

        // Parse comma-separated club UUIDs
        var clubIds = clubsClaim.Split(',', StringSplitOptions.RemoveEmptyEntries)
            .Select(id => id.Trim())
            .ToArray();

        if (clubIds.Length == 0 || !clubIds.Contains(requestedTenantId))
        {
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            await context.Response.WriteAsJsonAsync(new { error = $"User is not a member of tenant {requestedTenantId}" });
            return;
        }

        // Store validated tenant ID in HttpContext.Items for downstream middleware/services
        context.Items["TenantId"] = requestedTenantId;
        _logger.LogInformation("TenantValidationMiddleware: Set TenantId={TenantId} in HttpContext.Items", requestedTenantId);

        await _next(context);
    }
}
