namespace ROLAC.API.Entities.Logging;

/// <summary>
/// An append-only audit row recording a meaningful action: a data change (Create/Update/
/// Delete with before→after values), a security event (login, role/permission change), or a
/// key business action (check issued, expense approved, ...). Does NOT inherit AuditableEntity.
/// </summary>
public class AuditLog
{
    public long           Id            { get; set; }
    public DateTimeOffset Timestamp     { get; set; }
    public LogLevelEnum   Level         { get; set; } = LogLevelEnum.Information;

    /// <summary>One of <see cref="AuditActions"/>.</summary>
    public string         Action        { get; set; } = null!;

    /// <summary>One of <see cref="AuditCategories"/> — drives the UI grouping.</summary>
    public string         Category      { get; set; } = null!;

    public string?        EntityName    { get; set; }

    /// <summary>String to cover int, Guid and string primary keys uniformly.</summary>
    public string?        EntityId      { get; set; }

    /// <summary>JSON <c>{ "before": {...}, "after": {...} }</c> (jsonb column); sensitive fields masked.</summary>
    public string?        Changes       { get; set; }

    /// <summary>Human-readable one-liner, e.g. "Check #1042 issued to Acme — $1,200.00".</summary>
    public string?        Summary       { get; set; }

    public string?        UserId        { get; set; }
    /// <summary>Denormalized actor email — survives user deletion and avoids a join in the grid.</summary>
    public string?        UserEmail     { get; set; }
    public string?        IpAddress     { get; set; }
    public string?        CorrelationId { get; set; }
}

/// <summary>Canonical audit action names (stored verbatim in <see cref="AuditLog.Action"/>).</summary>
public static class AuditActions
{
    public const string Create             = "Create";
    public const string Update             = "Update";
    public const string Delete             = "Delete";
    public const string Login              = "Login";
    public const string Logout             = "Logout";
    public const string LoginFailed        = "LoginFailed";
    public const string RoleChanged        = "RoleChanged";
    public const string PasswordChanged    = "PasswordChanged";
    public const string UserDeactivated    = "UserDeactivated";
    public const string PermissionChanged  = "PermissionChanged";
    public const string InvitationCreated  = "InvitationCreated";
    public const string InvitationAccepted = "InvitationAccepted";
    public const string CheckIssued        = "CheckIssued";
    public const string CheckVoided        = "CheckVoided";
    public const string ExpenseApproved    = "ExpenseApproved";
    public const string ExpenseRejected    = "ExpenseRejected";
    public const string StatementFinalized = "StatementFinalized";

    public static readonly IReadOnlyList<string> All =
    [
        Create, Update, Delete, Login, Logout, LoginFailed, RoleChanged,
        PasswordChanged, UserDeactivated, PermissionChanged,
        InvitationCreated, InvitationAccepted, CheckIssued,
        CheckVoided, ExpenseApproved, ExpenseRejected, StatementFinalized,
    ];
}

/// <summary>Top-level audit grouping (stored verbatim in <see cref="AuditLog.Category"/>).</summary>
public static class AuditCategories
{
    public const string DataChange = "DataChange";
    public const string Security   = "Security";
    public const string Business   = "Business";

    public static readonly IReadOnlyList<string> All = [DataChange, Security, Business];
}
