"""
Base Admin Mixins for account and site/sector filtering
"""
from django.contrib import admin
from django.core.exceptions import PermissionDenied


class AccountAdminMixin:
    """Mixin for admin classes that need account filtering"""
    
    def get_queryset(self, request):
        """Filter queryset by account"""
        qs = super().get_queryset(request)
        # Check for account field
        has_account_field = hasattr(qs.model, 'account')
        if has_account_field:
            # Superuser and developers can see all
            if request.user.is_superuser or (hasattr(request.user, 'is_developer') and request.user.is_developer()):
                return qs
            # Filter by user's account
            user_account = getattr(request.user, 'account', None)
            if user_account:
                return qs.filter(account=user_account)
        return qs
    
    def has_view_permission(self, request, obj=None):
        """Check if user can view this object"""
        if obj:
            obj_account = getattr(obj, 'account', None)
            if obj_account:
                if request.user.is_superuser or (hasattr(request.user, 'is_developer') and request.user.is_developer()):
                    return True
                user_account = getattr(request.user, 'account', None)
                if user_account:
                    return obj_account == user_account
        return super().has_view_permission(request, obj)
    
    def has_change_permission(self, request, obj=None):
        """Check if user can change this object"""
        if obj:
            obj_account = getattr(obj, 'account', None)
            if obj_account:
                if request.user.is_superuser or (hasattr(request.user, 'is_developer') and request.user.is_developer()):
                    return True
                user_account = getattr(request.user, 'account', None)
                if user_account:
                    return obj_account == user_account
        return super().has_change_permission(request, obj)
    
    def has_delete_permission(self, request, obj=None):
        """Check if user can delete this object"""
        if obj:
            obj_account = getattr(obj, 'account', None)
            if obj_account:
                if request.user.is_superuser or (hasattr(request.user, 'is_developer') and request.user.is_developer()):
                    return True
                user_account = getattr(request.user, 'account', None)
                if user_account:
                    return obj_account == user_account
        return super().has_delete_permission(request, obj)



class SiteSectorAdminMixin:
    """Mixin for admin classes that need site/sector filtering"""
    
    def get_queryset(self, request):
        """Filter queryset by site/sector access"""
        qs = super().get_queryset(request)
        if hasattr(qs.model, 'site') and hasattr(qs.model, 'sector'):
            # Superuser and developers can see all
            if request.user.is_superuser or (hasattr(request.user, 'is_developer') and request.user.is_developer()):
                return qs
            # Filter by accessible sites
            if hasattr(request.user, 'get_accessible_sites'):
                accessible_sites = request.user.get_accessible_sites()
                return qs.filter(site__in=accessible_sites)
        return qs
    
    def has_view_permission(self, request, obj=None):
        """Check if user can view this object"""
        if obj and hasattr(obj, 'site'):
            if request.user.is_superuser or (hasattr(request.user, 'is_developer') and request.user.is_developer()):
                return True
            if hasattr(request.user, 'get_accessible_sites'):
                accessible_sites = request.user.get_accessible_sites()
                return obj.site in accessible_sites
        return super().has_view_permission(request, obj)
    
    def has_change_permission(self, request, obj=None):
        """Check if user can change this object"""
        if obj and hasattr(obj, 'site'):
            if request.user.is_superuser or (hasattr(request.user, 'is_developer') and request.user.is_developer()):
                return True
            if hasattr(request.user, 'get_accessible_sites'):
                accessible_sites = request.user.get_accessible_sites()
                return obj.site in accessible_sites
        return super().has_change_permission(request, obj)
    
    def has_delete_permission(self, request, obj=None):
        """Check if user can delete this object"""
        if obj and hasattr(obj, 'site'):
            if request.user.is_superuser or (hasattr(request.user, 'is_developer') and request.user.is_developer()):
                return True
            if hasattr(request.user, 'get_accessible_sites'):
                accessible_sites = request.user.get_accessible_sites()
                return obj.site in accessible_sites
        return super().has_delete_permission(request, obj)



# ============================================================================
# Custom ModelAdmin for Sidebar Fix
# ============================================================================

from unfold.admin import ModelAdmin as UnfoldModelAdmin


class Igny8ModelAdmin(UnfoldModelAdmin):
    """
    Custom ModelAdmin that ensures sidebar_navigation is set correctly on ALL pages
    
    Django's ModelAdmin views don't call AdminSite.each_context(), 
    so we override them to inject our custom sidebar.
    """
    
    def _inject_sidebar_context(self, request, extra_context=None):
        """Helper to inject custom sidebar into context"""
        if extra_context is None:
            extra_context = {}
        
        # Get our custom sidebar from the admin site
        from igny8_core.admin.site import admin_site
        
        # CRITICAL: Get the full Unfold context (includes all branding, form classes, etc.)
        # This is what makes the logo/title appear properly
        unfold_context = admin_site.each_context(request)
        
        # Get the current path to detect active group
        current_path = request.path
        
        sidebar_navigation = admin_site.get_sidebar_list(request)
        
        # Detect active group and expand it by setting collapsible=False
        for group in sidebar_navigation:
            group_is_active = False
            for item in group.get('items', []):
                item_link = item.get('link', '')
                # Check if current path matches this item's link
                if item_link and current_path.startswith(item_link):
                    item['active'] = True
                    group_is_active = True
            
            # If any item in this group is active, expand the group
            if group_is_active:
                group['collapsible'] = False  # Expanded state
            else:
                group['collapsible'] = True   # Collapsed state
        
        # Merge Unfold context with our custom sidebar
        unfold_context['sidebar_navigation'] = sidebar_navigation
        unfold_context['available_apps'] = admin_site.get_app_list(request, app_label=None)
        unfold_context['app_list'] = unfold_context['available_apps']
        
        # Merge with any existing extra_context
        unfold_context.update(extra_context)
        
        return unfold_context
    
    def changelist_view(self, request, extra_context=None):
        """Override to inject custom sidebar"""
        extra_context = self._inject_sidebar_context(request, extra_context)
        return super().changelist_view(request, extra_context)
    
    def change_view(self, request, object_id, form_url='', extra_context=None):
        """Override to inject custom sidebar"""
        extra_context = self._inject_sidebar_context(request, extra_context)
        return super().change_view(request, object_id, form_url, extra_context)
    
    def add_view(self, request, form_url='', extra_context=None):
        """Override to inject custom sidebar"""
        extra_context = self._inject_sidebar_context(request, extra_context)
        return super().add_view(request, form_url, extra_context)
