"""Single audit-log entry helper for SME-Hub services.

All SP1–SP5 service modules call ``record_audit`` (re-exported as ``_audit``)
to write a row to ``apps.core.audit.models.AuditLog``. Centralising the helper
here ensures every state transition is captured with the same shape:
actor, action code, target app/model/pk/repr, and a JSON ``changes`` blob.

Importing the helper from a single module makes it trivial to extend later —
e.g. attaching the request IP or user-agent — without auditing every services.py.
"""
from __future__ import annotations

from apps.core.audit.models import AuditLog

# Re-exported so service modules need only one shared import.
__all__ = ["AuditLog", "record_audit", "_audit"]


def record_audit(
    actor,
    action: str,
    target,
    *,
    metadata: dict | None = None,
) -> AuditLog | None:
    """Write an AuditLog row for a state-changing action.

    Returns the created row (handy for tests) or ``None`` when no target was
    supplied — callers commonly pass ``None`` when an action does not yet have
    a persistent target (e.g. registration before the user row exists).
    """
    if target is None:
        return None
    return AuditLog.objects.create(
        actor=actor if (actor is not None and getattr(actor, "is_authenticated", False)) else None,
        action=action,
        target_app=target._meta.app_label,
        target_model=target._meta.model_name,
        object_id=str(target.pk),
        object_repr=str(target)[:200],
        changes=metadata or {},
    )


# Backwards-compatible alias for service modules that still import ``_audit``.
_audit = record_audit
