# from: https://stackoverflow.com/a/52700398
import logging
from rest_framework import response, status

logger = logging.getLogger(__name__)


def _unwrap_historical_instance(instance):
    """Resolve a HistoricalXxx record to the original LexModel instance.

    Historical models generated by django-simple-history / StandardHistory do
    not inherit from LexModel, so they lack permission_delete / can_delete.
    This helper mirrors the unwrap logic in LexSerializer._unwrap_instance().

    Returns (target_instance, original_instance) where original_instance is
    the pre-unwrap historical record (or None if no unwrapping was needed).
    """
    if hasattr(instance, 'permission_delete') or hasattr(instance, 'can_delete'):
        return instance, None  # Already a LexModel — no unwrap needed

    original = instance
    target = instance

    # Unwrap Meta wrapper (Level 2 → Level 1)
    if hasattr(target, 'history_object') and target.history_object:
        target = target.history_object

    # Unwrap History wrapper (Level 1 → Main) via FK
    unwrapped = False
    try:
        possible = getattr(target, 'instance', None)
        if possible:
            target = possible
            unwrapped = True
    except Exception:
        pass

    # Fallback: reconstruct from instance_type
    if not unwrapped and hasattr(target, 'instance_type'):
        try:
            ModelClass = target.instance_type
            init_kwargs = {}
            for field in ModelClass._meta.fields:
                if hasattr(target, field.attname):
                    init_kwargs[field.attname] = getattr(target, field.attname)
            target = ModelClass(**init_kwargs)
        except Exception:
            pass

    if target is original:
        return instance, None  # Unwrap failed — return as-is
    return target, original


class DestroyOneWithPayloadMixin:
    """
    The default destroy methods of Django do not return anything.
    However, we want to send the deleted instance with the response.
    """

    def destroy(self, *args, **kwargs):
        from rest_framework import response, status
        
        instance = self.get_object()
        request = self.request
        
        # Unwrap historical instances so we can check permission_delete
        # on the real LexModel even when deleting a HistoricalXxx record.
        target, original_instance = _unwrap_historical_instance(instance)

        # Check delete permission using new system
        can_delete = False
        try:
            if hasattr(target, 'permission_delete'):
                from lex.core.models.LexModel import UserContext
                user_context = UserContext.from_request(
                    request, target,
                )
                # If the instance was unwrapped from a historical record,
                # also try scopes registered under the historical resource
                # name so keycloak permissions resolve correctly.
                if original_instance is not None:
                    extra_scopes = UserContext._resolve_keycloak_scopes(
                        user_context.user_permissions,
                        target,
                        original_instance=original_instance,
                    )
                    if extra_scopes - user_context.keycloak_scopes:
                        merged = set(user_context.keycloak_scopes) | extra_scopes
                        user_context = UserContext(
                            user=user_context.user,
                            email=user_context.email,
                            is_authenticated=user_context.is_authenticated,
                            is_superuser=user_context.is_superuser,
                            groups=user_context.groups,
                            keycloak_scopes=merged,
                            user_permissions=user_context.user_permissions,
                            client_roles=user_context.client_roles,
                        )
                can_delete = target.permission_delete(user_context)
            elif hasattr(target, 'can_delete'):
                can_delete = target.can_delete(request)
            else:
                # No permission method found even after unwrapping — deny
                can_delete = False
        except Exception as exc:
            logger.error(
                "Permission check failed during delete of %s (pk=%s): %s",
                instance.__class__.__name__,
                getattr(instance, 'pk', '?'),
                exc,
            )
            # Deny by default on permission check error (principle of least privilege)
            can_delete = False
            
        if not can_delete:
            return response.Response({
                "message": f"You are not authorized to delete this record in {instance.__class__.__name__}"
            }, status=status.HTTP_400_BAD_REQUEST)
            
        serializer = self.get_serializer(instance)
        super().destroy(*args, **kwargs)
        return response.Response(serializer.data, status=status.HTTP_200_OK)