"""
Audit Log Mixins — Mixin برای ViewSet ها جهت ثبت خودکار تغییرات.
"""
from .models import AuditAction
from .services import AuditLogService


class AuditMixin:
    """
    Mixin برای DRF ViewSets.
    
    به طور خودکار عملیات create, update, destroy را در audit log ثبت می‌کند.
    
    Usage:
        class MyViewSet(AuditMixin, ModelViewSet):
            audit_module = 'hrm'
    """

    audit_module = ''

    def perform_create(self, serializer):
        instance = serializer.save()
        AuditLogService.log_model_change(
            instance=instance,
            action=AuditAction.CREATE,
            changes=serializer.validated_data,
            user=self.request.user if self.request.user.is_authenticated else None,
            module=self.audit_module,
            request=self.request,
        )

    def perform_update(self, serializer):
        # Capture old data before update
        instance = self.get_object()
        old_data = {}
        for field in serializer.validated_data.keys():
            old_data[field] = getattr(instance, field, None)

        instance = serializer.save()
        
        changes = AuditLogService.compute_changes(
            old_data={k: AuditLogService._serialize_value(v) for k, v in old_data.items()},
            new_data={k: AuditLogService._serialize_value(v) for k, v in serializer.validated_data.items()},
        )

        if changes:
            AuditLogService.log_model_change(
                instance=instance,
                action=AuditAction.UPDATE,
                changes=changes,
                user=self.request.user if self.request.user.is_authenticated else None,
                module=self.audit_module,
                request=self.request,
            )

    def perform_destroy(self, instance):
        AuditLogService.log_model_change(
            instance=instance,
            action=AuditAction.DELETE,
            user=self.request.user if self.request.user.is_authenticated else None,
            module=self.audit_module,
            request=self.request,
        )
        instance.delete()
