from django.apps import apps
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver
from django.forms.models import model_to_dict

from logmancer.conf import get_bool, should_exclude_model
from logmancer.utils import LogEvent


def connect_signals():
    if not get_bool("ENABLE_SIGNALS"):
        return

    def make_save_handler(model):
        @receiver(post_save, sender=model)
        def handler(sender, instance, created, **kwargs):
            if should_exclude_model(sender):
                return

            action = "created" if created else "updated"
            LogEvent.info(
                message=f"{sender.__name__} instance {action}: #{instance.pk}",
                meta={
                    "model": sender.__name__,
                    "action": action,
                    "data": model_to_dict(instance),
                },
                source="signal",
                actor_type="system",
            )

        return handler

    def make_delete_handler(model):
        @receiver(post_delete, sender=model)
        def handler(sender, instance, **kwargs):
            if should_exclude_model(sender):
                return

            LogEvent.warning(
                message=f"{sender.__name__} instance deleted: #{instance.pk}",
                meta={
                    "model": sender.__name__,
                    "action": "deleted",
                    "data": model_to_dict(instance),
                },
                source="signal",
                actor_type="system",
            )

        return handler

    for model in apps.get_models():
        if should_exclude_model(model):
            continue
        make_save_handler(model)
        make_delete_handler(model)
