from rest_framework.permissions import BasePermission
from rest_framework.exceptions import PermissionDenied

class UserPermissionCheck(BasePermission):
    def has_permission(self, request, view):
        user = request.user
        if not user.is_authenticated:
            return False

        if user.is_superuser or user.is_staff:
            return True

        user_perms = getattr(user, "permissions", {})

        
        app_name = self.get_app_name(view)
        model_name = self.get_model_name(view)
        
        
        if app_name not in user_perms:
            raise PermissionDenied("You don't have permission to perform this action on this model.")
        
        if model_name not in user_perms[app_name]:
            raise PermissionDenied("You don't have permission to perform this action on this model.")
        
        allowed_actions = user_perms[app_name][model_name]

        action_mapping = {
            'list': 'list',
            'create': 'create',
            'update': 'update',
            'partial_update': 'partial_update',
            'retrieve': 'retrieve',
            'destroy': 'destroy',
            
            # Custom actions
            'toggle_status': 'toggle_status',
            'manage_permissions': 'manage_permissions',
            'change_role': 'change_role', 
            'status_change': 'status_change',
            'logout': 'logout',
            'claim_referral': 'claim_referral',
            'me': 'me',
            'subscribe': 'subscribe',
            'unsubscribe': 'unsubscribe',
            'user_packages': 'user_packages',
            'my_downline': 'my_downline',
            'level': 'level',
            'stats': 'stats',
            'earning_report': 'earning_report',
            'reset_password': 'reset_password',  
            'approve': 'approve',
            'reject': 'reject'
        }
        
        # Get current action from view
        current_action = view.action
        
        # If action is None, try to get it from the method name
        if current_action is None and hasattr(view, 'action_mapping'):
            current_action = view.action_mapping.get(request.method.lower())
        
        # Map the action if it exists in the mapping
        if current_action in action_mapping:
            current_action = action_mapping[current_action]
        
        # If current_action is still None, use the HTTP method
        if current_action is None:
            current_action = request.method.lower()
        
        if current_action not in allowed_actions:
            raise PermissionDenied(f"You do not have permission to perform '{view.action}' on {model_name}.")
        
        return True

    def has_object_permission(self, request, view, obj):
        user = request.user
        
        if user.is_superuser or user.is_staff:
            return True

        return self.has_permission(request, view)

    def get_app_name(self, view):
        try:
            if hasattr(view, 'permission_app_name'):
                return view.permission_app_name
            
            # Derive from module path
            module_parts = view.__module__.split(".")
            for part in module_parts:
                if part in ['apps', 'views', 'api', 'v1', 'v2']:
                    continue
                if part and part != '__init__':
                    return part
            return module_parts[-1] if module_parts else 'unknown'
        except:
            return 'unknown'

    def get_model_name(self, view):
        try:
            if hasattr(view, 'permission_model_name'):
                return view.permission_model_name
            
            view_name = view.__class__.__name__
            if 'ViewSet' in view_name:
                model_name = view_name.replace("ViewSet", "").lower()
            else:
                model_name = view_name.lower()
            
            return model_name
        except:
            return 'unknown'