using foodmarket.Domain.Organizations;
using foodmarket.Infrastructure.Persistence;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Security.Claims;

namespace foodmarket.Api.Infrastructure.Tenancy;

/// <summary>Phase 3 audit-trail: когда SuperAdmin в режиме «открыть как…» с
/// edit-mode (X-Org-Override + X-Org-Override-Reason ≥ 10 символов) делает
/// успешную мутацию — пишем запись в SuperAdminAuditLog с reason, путём,
/// methodом, status code'ом. Запускается ПОСЛЕ controller'а, только если
/// ответ 2xx (успех) — неудачные запросы не засоряют журнал.</summary>
public class SuperAdminEditAuditFilter : IAsyncActionFilter
{
    private readonly AppDbContext _db;
    public SuperAdminEditAuditFilter(AppDbContext db) => _db = db;

    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        var ctx = context.HttpContext;
        var method = ctx.Request.Method.ToUpperInvariant();
        var hasOverride = ctx.Request.Headers.ContainsKey(HttpContextTenantContext.OrgOverrideHeader);
        var hasReason = ctx.Request.Headers.TryGetValue(HttpContextTenantContext.EditReasonHeader, out var reasonHv)
                        && (reasonHv.ToString() ?? "").Trim().Length >= 10;
        var isMutation = method is "POST" or "PUT" or "PATCH" or "DELETE";
        var isSuper = ctx.User?.IsInRole(HttpContextTenantContext.SuperAdminRole) == true;

        var executed = await next();

        if (!hasOverride || !hasReason || !isMutation || !isSuper) return;
        if (executed.Exception is not null) return;
        var status = ctx.Response.StatusCode;
        if (status < 200 || status >= 300) return;

        var orgGuid = Guid.TryParse(ctx.Request.Headers[HttpContextTenantContext.OrgOverrideHeader].ToString(), out var g) ? g : (Guid?)null;
        var userIdRaw = ctx.User?.FindFirstValue(ClaimTypes.NameIdentifier) ?? ctx.User?.FindFirstValue("sub");
        Guid.TryParse(userIdRaw, out var uid);
        _db.SuperAdminAuditLogs.Add(new SuperAdminAuditLog
        {
            SuperAdminUserId = uid,
            ActionType = "EditEntity",
            OrganizationId = orgGuid,
            Description = $"{method} {ctx.Request.Path.Value} → {status}",
            Reason = reasonHv.ToString().Trim(),
            ChangesJson = "{}",
            IpAddress = ctx.Connection?.RemoteIpAddress?.ToString() ?? "",
        });
        await _db.SaveChangesAsync();
    }
}
