from django.contrib import admin
from django.contrib import messages
from django.contrib.auth.models import User, Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
from .models import *
from django import forms
from unfold.admin import ModelAdmin, TabularInline
from unfold.sites import UnfoldAdminSite
from django.utils.html import format_html
from django.utils.text import Truncator
from django.urls import path
from django.http import JsonResponse
from django.template.response import TemplateResponse
from cms.geo.metrics import get_metrics
from cms.geo.errors import get_error_logger
from cms.visitor_services import BLOCKLIST
class UserProfileInline(TabularInline):
    model = UserProfile
    can_delete = False
    verbose_name_plural = 'Managed Region'

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "managed_region":
            if not request.user.is_superuser and hasattr(request.user, 'profile') and request.user.profile.managed_region:
                kwargs["queryset"] = Region.objects.filter(id=request.user.profile.managed_region.id)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

class CustomUserAdmin(BaseUserAdmin, ModelAdmin):
    inlines = (UserProfileInline, )
    
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        if hasattr(request.user, 'profile') and request.user.profile.managed_region:
            return qs.filter(profile__managed_region=request.user.profile.managed_region)
        return qs

class CustomGroupAdmin(BaseGroupAdmin, ModelAdmin):
    pass

class RegionRestrictedAdminMixin:
    """Mixin to restrict queryset and form choices based on user's managed_region."""
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        if hasattr(request.user, 'profile') and request.user.profile.managed_region:
            # Check if the model has a 'regions' ManyToMany field
            if hasattr(self.model, 'regions'):
                return qs.filter(regions=request.user.profile.managed_region)
        return qs

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "regions":
            if not request.user.is_superuser and hasattr(request.user, 'profile') and request.user.profile.managed_region:
                kwargs["queryset"] = Region.objects.filter(id=request.user.profile.managed_region.id)
        return super().formfield_for_manytomany(db_field, request, **kwargs)
    
    def save_model(self, request, obj, form, change):
        super().save_model(request, obj, form, change)
        # Ensure that non-superusers automatically have their managed region attached if applicable
        if not request.user.is_superuser and hasattr(request.user, 'profile') and request.user.profile.managed_region:
            if hasattr(obj, 'regions') and not obj.regions.exists():
                obj.regions.add(request.user.profile.managed_region)

class SeoModelAdminForm(forms.ModelForm):
    """Custom form to add help text for auto-generated SEO fields."""
    class Meta:
        model = None  # Will be set dynamically
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Add help text to indicate auto-generation
        for field in ['meta_title', 'meta_description', 'meta_keywords', 'meta_image', 'meta_canonical_url']:
            if field in self.fields:
                self.fields[field].help_text += " (Auto-generated if left blank)"


class SeoModelAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    form = SeoModelAdminForm
    
    # Define base fieldsets components for reusability
    BASE_FIELDS_CONFIG = ('title', 'slug', 'is_published', 'regions') # Added regions here
    CONTENT_FIELD_CONFIG = ('content',) # For models with a 'content' field
    DESCRIPTION_FIELD_CONFIG = ('description',) # For models with a 'description' field
    SEO_FIELDS_CONFIG = ('meta_title', 'meta_description', 'meta_keywords', 'meta_image', 'meta_canonical_url')
    TIMESTAMP_FIELDS_CONFIG = ('created_at', 'updated_at')

    # Default fieldsets - subclasses can override this entire structure or parts of it
    fieldsets = (
        (None, {'fields': BASE_FIELDS_CONFIG + CONTENT_FIELD_CONFIG}),
        ('Timestamps', {'fields': TIMESTAMP_FIELDS_CONFIG, 'classes': ('collapse',)}),
        ('SEO', {'classes': ('collapse',), 'fields': SEO_FIELDS_CONFIG}),
    )
    
    readonly_fields = TIMESTAMP_FIELDS_CONFIG
    list_display_base = ('title', 'slug') # Base for list_display
    list_display_timestamps = ('created_at', 'updated_at')
    list_display = list_display_base + ('is_published_badge',) + list_display_timestamps
    
    list_filter = ('is_published', 'regions') # Added regions filter
    search_fields = ('title', 'slug', 'meta_title', 'meta_description') # Common search fields
    prepopulated_fields = {'slug': ('title',)} # Auto-populate slug from title
    
    actions_list_display = ['is_published_badge'] # For Unfold theme

    @admin.display(description='Status', ordering='is_published')
    def is_published_badge(self, obj):
        if obj.is_published:
            return format_html('<span class="unfold-badge unfold-badge--success">{}</span>', 'Published')
        return format_html('<span class="unfold-badge unfold-badge--danger">{}</span>', 'Draft')


@admin.register(Region)
class RegionAdmin(ModelAdmin):
    list_display = ('name', 'code', 'is_active', 'is_default')
    list_filter = ('is_active',)
    search_fields = ('name', 'code')


SERVICE_TYPE_CHOICES = (
    ("security", "Security"),
    ("cleaning", "Cleaning"),
    ("staffing", "Staffing Solutions"),
    ("logistics", "Logistics"),
    ("risk-management", "Risk Management"),
    ("property", "Property & Facility"),
)


class ServiceAdminForm(SeoModelAdminForm):
    service_type = forms.ChoiceField(choices=SERVICE_TYPE_CHOICES)


@admin.register(Service)
class ServiceAdmin(SeoModelAdmin):
    form = ServiceAdminForm
    # Service model does not have created_at/updated_at timestamps in the model definition
    # Thus, we don't include Timestamps fieldset or readonly_fields for them here.
    fieldsets = (
        ('Basic Info', {'fields': ('title', 'slug', 'is_published', 'regions', 'service_type', 'order'), 'classes': ('tab',)}),
        ('Content', {'fields': ('description', 'image', 'icon', 'primary_cta_url'), 'classes': ('tab',)}),
        ('SEO', {'classes': ('collapse', 'tab'), 'fields': SeoModelAdmin.SEO_FIELDS_CONFIG}),
    )
    list_display = SeoModelAdmin.list_display_base + ('is_published_badge', 'service_type', 'order')
    list_filter = ('is_published', 'service_type', 'regions')
    search_fields = SeoModelAdmin.search_fields + ('description',)
    readonly_fields = () # Override SeoModelAdmin's readonly_fields as Service doesn't have timestamps
    
    # Unfold specific configurations
    ordering = ['order']


@admin.register(About)
class AboutAdmin(SeoModelAdmin):
    # About model DOES NOT have regions field
    fieldsets = (
        ('Content', {'fields': ('title', 'slug', 'is_published', 'content', 'image'), 'classes': ('tab',)}),
        ('SEO', {'classes': ('collapse', 'tab'), 'fields': SeoModelAdmin.SEO_FIELDS_CONFIG}),
        ('Timestamps', {'fields': SeoModelAdmin.TIMESTAMP_FIELDS_CONFIG, 'classes': ('collapse', 'tab')}),
    )
    # list_display and readonly_fields inherited from SeoModelAdmin
    search_fields = SeoModelAdmin.search_fields + ('content',)
    list_filter = ('is_published',) # Override to remove regions


class FooterLinkInline(TabularInline):
    model = FooterLink
    extra = 1
    fields = ('label', 'url_name', 'custom_url', 'open_in_new', 'order', 'is_active')


@admin.register(FooterLinkGroup)
class FooterLinkGroupAdmin(ModelAdmin):
    list_display = ('title', 'location', 'order', 'is_active')
    list_filter = ('location', 'is_active')
    ordering = ('location', 'order')
    inlines = [FooterLinkInline]


@admin.register(FooterSettings)
class FooterSettingsAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    fieldsets = (
        ('Footer Content', {'fields': ('contact_heading', 'office_label', 'description', 'regions')}),
        ('Badges', {'fields': ('badge_one_label', 'badge_one_icon', 'badge_two_label', 'badge_two_icon')}),
        ('Hours', {'fields': ('business_hours', 'emergency_hours')}),
    )


@admin.register(CompanySettings)
class CompanySettingsAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    fieldsets = (
        ('Company Info', {'fields': ('company_name', 'description', 'regions')}),
        ('Contact', {'fields': ('phone', 'emergency_phone', 'email')}),
        ('Address', {'fields': ('building_name', 'office_number', 'street_address', 'address_line_2', 'city', 'region', 'postal_code', 'country')}),
        ('Social', {'fields': ('facebook_url', 'linkedin_url', 'twitter_url', 'instagram_url')}),
    )
   

@admin.register(TeamMember)
class TeamMemberAdmin(RegionRestrictedAdminMixin, ModelAdmin): # TeamMember doesn't use SeoModelAdmin
    list_display = ('name', 'position', 'order', 'photo_preview', 'created_at', 'updated_at')
    readonly_fields = ('created_at', 'updated_at')
    ordering = ['order']
    list_filter = ('regions',) # Added regions filter
    # Add created_at, updated_at to fieldsets if you want them visible on the edit page
    fieldsets = (
        (None, {'fields': ('name', 'position', 'bio', 'photo', 'regions', 'order')}), # Added regions
        ('Timestamps', {'fields': ('created_at', 'updated_at'), 'classes': ('collapse',)}),
    )
    
    @admin.display(description='Photo')
    def photo_preview(self, obj):
        if obj.photo:
            return format_html('<img src="{}" style="max-height: 50px; max-width: 100px;" />', obj.photo.url)
        return ""


@admin.register(Testimonial)
class TestimonialAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    list_display = ('name', 'company', 'is_published_badge', 'photo_preview') # Using is_published_badge for consistency
    list_filter = ('is_published', 'regions') # Added regions
    
    # Helper method for is_published_badge if not inheriting from SeoModelAdmin
    # Or, create a common BaseModelAdmin with this badge if many non-SEO models need it.
    @admin.display(description='Status', ordering='is_published')
    def is_published_badge(self, obj):
        if obj.is_published:
            return format_html('<span class="unfold-badge unfold-badge--success">{}</span>', 'Published')
        return format_html('<span class="unfold-badge unfold-badge--danger">{}</span>', 'Draft')
    
    @admin.display(description='Photo')
    def photo_preview(self, obj):
        if obj.photo:
            return format_html('<img src="{}" style="max-height: 50px; max-width: 100px;" />', obj.photo.url)
        return ""


# Customize the admin site
admin.site.site_header = 'Xinfinity Admin'
admin.site.site_title = 'Xinfinity Admin Portal'
admin.site.index_title = 'Welcome to Xinfinity Admin Portal'


@admin.register(RedirectLog)
class RedirectLogAdmin(ModelAdmin):
    """Admin interface for RedirectLog model.
    
    Provides monitoring and analysis of geo-redirect events including:
    - Filtering by country and timestamp
    - Searching by IP address
    - Viewing redirect details (source IP, target URL, status code, user agent, referer)
    """
    list_display = ('source_ip', 'detected_country', 'status_code', 'timestamp', 'target_url_preview')
    list_filter = ('detected_country', 'status_code', 'timestamp')
    search_fields = ('source_ip', 'target_url', 'user_agent')
    readonly_fields = ('source_ip', 'detected_country', 'target_url', 'status_code', 'user_agent', 'referer', 'timestamp')
    
    fieldsets = (
        ('Redirect Information', {
            'fields': ('source_ip', 'detected_country', 'target_url', 'status_code', 'timestamp')
        }),
        ('Request Details', {
            'fields': ('user_agent', 'referer'),
            'classes': ('collapse',)
        }),
    )
    
    date_hierarchy = 'timestamp'
    ordering = ['-timestamp']
    
    @admin.display(description='Target URL', ordering='target_url')
    def target_url_preview(self, obj):
        """Display a truncated preview of the target URL."""
        max_length = 50
        if len(obj.target_url) > max_length:
            return format_html(
                '<span title="{}">{}</span>',
                obj.target_url,
                obj.target_url[:max_length] + '...'
            )
        return obj.target_url
    
    def has_add_permission(self, request):
        """Disable adding redirect logs manually - they're created automatically."""
        return False
    
    def has_delete_permission(self, request, obj=None):
        """Allow deletion of redirect logs for maintenance."""
        return True
    
    def has_change_permission(self, request, obj=None):
        """Disable editing redirect logs - they're immutable records."""
        return False


@admin.register(Contact)
class ContactAdmin(ModelAdmin):
    list_display = ('name', 'email', 'phone', 'message_preview', 'created_at', 'is_resolved', 'ip_address', 'country_code', 'is_spam')
    list_filter = ('is_resolved', 'is_spam', 'country_code', 'created_at')
    search_fields = ('name', 'email', 'subject', 'message', 'ip_address', 'city', 'spam_reason')
    readonly_fields = ('created_at', 'ip_address', 'country_code', 'country_name', 'city', 'user_agent', 'spam_reason')
    date_hierarchy = 'created_at'
    list_per_page = 50
    fieldsets = (
        ('Contact Information', {
            'fields': ('name', 'email', 'phone', 'subject'),
            'classes': ('tab',)
        }),
        ('Message', {
            'fields': ('message',),
            'classes': ('tab',)
        }),
        ('Status', {
            'fields': ('is_resolved', 'is_spam', 'spam_reason', 'created_at'),
            'classes': ('tab',)
        }),
        ('Visitor Intelligence', {
            'fields': ('ip_address', 'country_code', 'country_name', 'city', 'user_agent'),
            'classes': ('collapse', 'tab')
        }),
    )
    
    actions = ['mark_as_resolved', 'mark_as_unresolved', 'mark_as_spam', 'mark_as_legitimate', 'block_sender_ip', 'unblock_sender_ip']

    @admin.display(description='Message', ordering='message')
    def message_preview(self, obj):
        """One-glance message preview so you don't have to open every row."""
        snippet = Truncator(obj.message.strip()).chars(90, html=False)
        return format_html(
            '<div title="{}" style="white-space:normal;min-width:240px;max-width:420px;'
            'color:#334155;line-height:1.4;">{}</div>',
            Truncator(obj.message.strip()).chars(400, html=False),
            snippet,
        )

    @admin.display(description='Status', ordering='is_spam')
    def is_spam(self, obj):
        if obj.is_spam:
            return format_html('<span class="unfold-badge unfold-badge--danger">{}</span>', 'SPAM')
        return ''
    
    @admin.action(description="Mark selected contacts as resolved")
    def mark_as_resolved(self, request, queryset):
        queryset.update(is_resolved=True)
    
    @admin.action(description="Mark selected contacts as unresolved")
    def mark_as_unresolved(self, request, queryset):
        queryset.update(is_resolved=False)

    @admin.action(description="Mark selected contacts as spam")
    def mark_as_spam(self, request, queryset):
        queryset.update(is_spam=True, spam_reason='Marked as spam in admin')
        self.message_user(request, f'Marked {queryset.count()} submission(s) as spam.')

    @admin.action(description="Mark selected contacts as legitimate")
    def mark_as_legitimate(self, request, queryset):
        queryset.update(is_spam=False, spam_reason='')

    @admin.action(description="Block sender IPs (and delete submissions)")
    def block_sender_ip(self, request, queryset):
        """Block every distinct sender IP and delete the spam submissions."""
        blocked = []
        for obj in queryset:
            if obj.ip_address:
                BLOCKLIST.add_block(
                    obj.ip_address,
                    reason=f'Spam/fake contact from {obj.email}',
                    source='manual',
                    notes='Blocked from Contact Submissions admin',
                    created_by=request.user,
                )
                blocked.append(obj.ip_address)
        count = queryset.delete()[0]
        self.message_user(
            request,
            f'Blocked {len(set(blocked))} unique IP(s) and deleted {count} submission(s).',
        )

    @admin.action(description="Unblock sender IPs")
    def unblock_sender_ip(self, request, queryset):
        """Deactivate any active blocks matching the selected senders' IPs."""
        unblocked = set()
        for obj in queryset:
            if obj.ip_address:
                match = BLOCKLIST.is_blocked(obj.ip_address)
                if match:
                    BLOCKLIST.remove_block(obj.ip_address)
                    unblocked.add(obj.ip_address)
        if unblocked:
            self.message_user(request, f'Unblocked {len(unblocked)} IP address(es): {", ".join(sorted(unblocked))}.')
        else:
            self.message_user(request, 'None of the selected senders had an active block.', messages.WARNING)


# Google Business Profile Admin

class GBPPhotoInline(TabularInline):
    """Inline admin for GBP photos."""
    model = GBPPhoto
    extra = 1
    fields = ('title', 'photo_type', 'image', 'is_published', 'order')
    ordering = ['order']


class GBPPostInline(TabularInline):
    """Inline admin for GBP posts."""
    model = GBPPost
    extra = 1
    fields = ('title', 'post_type', 'is_published', 'published_at')
    readonly_fields = ('published_at',)


class GBPReviewInline(TabularInline):
    """Inline admin for GBP reviews."""
    model = GBPReview
    extra = 0
    fields = ('reviewer_name', 'rating', 'review_date', 'response_status')
    readonly_fields = ('reviewer_name', 'rating', 'review_date', 'response_status')
    can_delete = False


@admin.register(GoogleBusinessProfile)
class GoogleBusinessProfileAdmin(ModelAdmin):
    """Admin interface for Google Business Profile."""
    list_display = ('business_name', 'city', 'country', 'is_verified_badge', 'completeness_percentage', 'photo_count', 'review_count')
    list_filter = ('is_verified', 'country', 'business_type')
    search_fields = ('business_name', 'city', 'email', 'phone')
    readonly_fields = ('created_at', 'updated_at', 'last_synced', 'completeness_display')
    
    inlines = [GBPPhotoInline, GBPPostInline, GBPReviewInline]
    
    fieldsets = (
        ('Business Information', {
            'fields': ('business_name', 'business_type', 'description'),
            'classes': ('tab',)
        }),
        ('Contact Information', {
            'fields': ('phone', 'email', 'website'),
            'classes': ('tab',)
        }),
        ('Address', {
            'fields': ('street_address', 'city', 'state_province', 'postal_code', 'country'),
            'classes': ('tab',)
        }),
        ('Service Details', {
            'fields': ('service_categories', 'service_areas', 'business_hours', 'attributes'),
            'classes': ('tab',)
        }),
        ('Profile Status', {
            'fields': ('is_verified', 'verification_date', 'completeness_display'),
            'classes': ('tab',)
        }),
        ('Metadata', {
            'fields': ('created_at', 'updated_at', 'last_synced'),
            'classes': ('collapse', 'tab')
        }),
    )
    
    actions = ['mark_as_verified', 'mark_as_unverified']
    
    @admin.display(description='Verified', ordering='is_verified')
    def is_verified_badge(self, obj):
        if obj.is_verified:
            return format_html('<span class="unfold-badge unfold-badge--success">{}</span>', 'Verified')
        return format_html('<span class="unfold-badge unfold-badge--warning">{}</span>', 'Not Verified')
    
    @admin.display(description='Completeness')
    def completeness_percentage(self, obj):
        from cms.gbp_manager import GBPManager
        completeness = GBPManager.get_profile_completeness(obj.id)
        percentage = completeness['percentage']
        
        if percentage >= 80:
            color = 'green'
        elif percentage >= 50:
            color = 'orange'
        else:
            color = 'red'
        
        return format_html(
            '<span style="color: {}; font-weight: bold;">{:.0f}%</span>',
            color,
            percentage
        )
    
    @admin.display(description='Completeness Details')
    def completeness_display(self, obj):
        from cms.gbp_manager import GBPManager
        completeness = GBPManager.get_profile_completeness(obj.id)
        return f"{completeness['completed']} / {completeness['total']} fields completed ({completeness['percentage']:.0f}%)"
    
    @admin.display(description='Photos')
    def photo_count(self, obj):
        count = obj.photos.filter(is_published=True).count()
        return format_html(
            '<span style="background-color: #e3f2fd; padding: 3px 8px; border-radius: 3px;">{}</span>',
            count
        )
    
    @admin.display(description='Reviews')
    def review_count(self, obj):
        count = obj.reviews.count()
        return format_html(
            '<span style="background-color: #f3e5f5; padding: 3px 8px; border-radius: 3px;">{}</span>',
            count
        )
    
    @admin.action(description="Mark selected profiles as verified")
    def mark_as_verified(self, request, queryset):
        from django.utils import timezone
        queryset.update(is_verified=True, verification_date=timezone.now())
    
    @admin.action(description="Mark selected profiles as unverified")
    def mark_as_unverified(self, request, queryset):
        queryset.update(is_verified=False, verification_date=None)


@admin.register(GBPPhoto)
class GBPPhotoAdmin(ModelAdmin):
    """Admin interface for GBP photos."""
    list_display = ('title', 'profile', 'photo_type', 'is_published_badge', 'view_count', 'order', 'image_preview')
    list_filter = ('photo_type', 'is_published', 'profile')
    search_fields = ('title', 'description', 'profile__business_name')
    readonly_fields = ('view_count', 'uploaded_at', 'updated_at', 'image_preview_large')
    
    fieldsets = (
        ('Photo Information', {
            'fields': ('profile', 'title', 'description', 'photo_type', 'image'),
            'classes': ('tab',)
        }),
        ('Display', {
            'fields': ('is_published', 'order', 'image_preview_large'),
            'classes': ('tab',)
        }),
        ('Statistics', {
            'fields': ('view_count', 'uploaded_at', 'updated_at'),
            'classes': ('collapse', 'tab')
        }),
    )
    
    ordering = ['profile', 'order']
    
    @admin.display(description='Status', ordering='is_published')
    def is_published_badge(self, obj):
        if obj.is_published:
            return format_html('<span class="unfold-badge unfold-badge--success">{}</span>', 'Published')
        return format_html('<span class="unfold-badge unfold-badge--danger">{}</span>', 'Draft')
    
    @admin.display(description='Preview')
    def image_preview(self, obj):
        if obj.image:
            return format_html('<img src="{}" style="max-height: 50px; max-width: 100px;" />', obj.image.url)
        return ""
    
    @admin.display(description='Image Preview')
    def image_preview_large(self, obj):
        if obj.image:
            return format_html('<img src="{}" style="max-height: 300px; max-width: 400px;" />', obj.image.url)
        return "No image"


@admin.register(GBPPost)
class GBPPostAdmin(ModelAdmin):
    """Admin interface for GBP posts."""
    list_display = ('title', 'profile', 'post_type', 'is_published_badge', 'published_at', 'view_count', 'click_count')
    list_filter = ('post_type', 'is_published', 'profile', 'published_at')
    search_fields = ('title', 'content', 'profile__business_name')
    readonly_fields = ('view_count', 'click_count', 'phone_call_count', 'created_at', 'updated_at', 'published_at')
    
    fieldsets = (
        ('Post Information', {
            'fields': ('profile', 'title', 'content', 'post_type'),
            'classes': ('tab',)
        }),
        ('Call-to-Action', {
            'fields': ('call_to_action', 'cta_url'),
            'classes': ('tab',)
        }),
        ('Offer/Event Details', {
            'fields': ('offer_code', 'start_date', 'end_date'),
            'classes': ('tab',)
        }),
        ('Media', {
            'fields': ('image',),
            'classes': ('tab',)
        }),
        ('Publishing', {
            'fields': ('is_published', 'published_at'),
            'classes': ('tab',)
        }),
        ('Engagement', {
            'fields': ('view_count', 'click_count', 'phone_call_count'),
            'classes': ('collapse', 'tab')
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse', 'tab')
        }),
    )
    
    date_hierarchy = 'published_at'
    ordering = ['-published_at']
    
    @admin.display(description='Status', ordering='is_published')
    def is_published_badge(self, obj):
        if obj.is_published:
            return format_html('<span class="unfold-badge unfold-badge--success">{}</span>', 'Published')
        return format_html('<span class="unfold-badge unfold-badge--danger">{}</span>', 'Draft')


@admin.register(GBPReview)
class GBPReviewAdmin(ModelAdmin):
    """Admin interface for GBP reviews."""
    list_display = ('reviewer_name', 'profile', 'rating_stars', 'review_date', 'response_status_badge', 'helpful_count')
    list_filter = ('rating', 'response_status', 'profile', 'review_date')
    search_fields = ('reviewer_name', 'review_text', 'profile__business_name')
    readonly_fields = ('review_date', 'synced_at', 'updated_at', 'rating_stars')
    
    fieldsets = (
        ('Review Information', {
            'fields': ('profile', 'reviewer_name', 'rating', 'rating_stars', 'review_text', 'review_url'),
            'classes': ('tab',)
        }),
        ('Response', {
            'fields': ('response_status', 'response_text', 'response_date'),
            'classes': ('tab',)
        }),
        ('Engagement', {
            'fields': ('helpful_count',),
            'classes': ('collapse', 'tab')
        }),
        ('Timestamps', {
            'fields': ('review_date', 'synced_at', 'updated_at'),
            'classes': ('collapse', 'tab')
        }),
    )
    
    actions = ['mark_as_responded', 'mark_as_not_responded']
    date_hierarchy = 'review_date'
    ordering = ['-review_date']
    
    @admin.display(description='Rating')
    def rating_stars(self, obj):
        return obj.get_rating_display_stars()
    
    @admin.display(description='Response Status', ordering='response_status')
    def response_status_badge(self, obj):
        if obj.response_status == 'responded':
            return format_html('<span class="unfold-badge unfold-badge--success">{}</span>', 'Responded')
        elif obj.response_status == 'archived':
            return format_html('<span class="unfold-badge unfold-badge--secondary">{}</span>', 'Archived')
        else:
            return format_html('<span class="unfold-badge unfold-badge--warning">{}</span>', 'Not Responded')
    
    @admin.action(description="Mark selected reviews as responded")
    def mark_as_responded(self, request, queryset):
        from django.utils import timezone
        queryset.update(response_status='responded', response_date=timezone.now())
    
    @admin.action(description="Mark selected reviews as not responded")
    def mark_as_not_responded(self, request, queryset):
        queryset.update(response_status='not_responded', response_date=None)


# Performance Metrics Admin Views
class PerformanceMetricsAdminMixin:
    """Mixin to add performance metrics and error monitoring views to the admin site."""
    
    def get_urls(self):
        """Add custom URLs for performance metrics and error monitoring."""
        urls = super().get_urls()
        from cms.visitor_admin import security_dashboard_view, visitor_live_json_view
        custom_urls = [
            path('geo/metrics/summary/', self.admin_view(self.metrics_summary_view), name='geo_metrics_summary'),
            path('geo/metrics/geolocation/', self.admin_view(self.metrics_geolocation_view), name='geo_metrics_geolocation'),
            path('geo/metrics/cache/', self.admin_view(self.metrics_cache_view), name='geo_metrics_cache'),
            path('geo/metrics/redirect/', self.admin_view(self.metrics_redirect_view), name='geo_metrics_redirect'),
            path('geo/metrics/dashboard/', self.admin_view(self.metrics_dashboard_view), name='geo_metrics_dashboard'),
            path('geo/errors/summary/', self.admin_view(self.errors_summary_view), name='geo_errors_summary'),
            path('geo/errors/details/', self.admin_view(self.errors_details_view), name='geo_errors_details'),
            path('geo/errors/clear/', self.admin_view(self.errors_clear_view), name='geo_errors_clear'),
            path('geo/errors/dashboard/', self.admin_view(self.errors_dashboard_view), name='geo_errors_dashboard'),
            path('cache-management/', self.admin_view(self.cache_management_view), name='cache_management'),
            path('security/dashboard/', self.admin_view(security_dashboard_view), name='security_dashboard'),
            path('security/live/', self.admin_view(visitor_live_json_view), name='visitor_live'),
        ]
        return custom_urls + urls
    
    def cache_management_view(self, request):
        """Directly clears the cache and redirects back to the referring page."""
        from django.core.cache import cache
        from django.contrib import messages
        from django.http import HttpResponseRedirect
        
        # Clear the entire cache
        cache.clear()
        messages.success(request, 'Website cache cleared successfully! If changes are still not visible, re-run collectstatic on the server and hard refresh the browser.')
        
        # Redirect back to where the user came from, or admin index if no referrer
        referer = request.META.get('HTTP_REFERER', '/admin/')
        return HttpResponseRedirect(referer)
    
    @staticmethod
    def metrics_summary_view(request):
        """Get a summary of all performance metrics."""
        minutes = int(request.GET.get('minutes', 60))
        metrics = get_metrics()
        summary = metrics.get_all_metrics_summary(minutes=minutes)
        return JsonResponse(summary)
    
    @staticmethod
    def metrics_geolocation_view(request):
        """Get detailed geolocation lookup statistics."""
        minutes = int(request.GET.get('minutes', 60))
        metrics = get_metrics()
        stats = metrics.get_geolocation_stats(minutes=minutes)
        return JsonResponse(stats.to_dict())
    
    @staticmethod
    def metrics_cache_view(request):
        """Get cache hit rate statistics."""
        minutes = int(request.GET.get('minutes', 60))
        metrics = get_metrics()
        cache_hit_rate = metrics.get_cache_hit_rate(minutes=minutes)
        return JsonResponse({
            'cache_hit_rate': cache_hit_rate,
            'cache_miss_rate': 100 - cache_hit_rate,
            'minutes': minutes,
        })
    
    @staticmethod
    def metrics_redirect_view(request):
        """Get redirect decision statistics."""
        minutes = int(request.GET.get('minutes', 60))
        metrics = get_metrics()
        stats = metrics.get_redirect_decision_stats(minutes=minutes)
        return JsonResponse(stats.to_dict())
    
    @staticmethod
    def metrics_dashboard_view(request):
        """Render the performance metrics dashboard."""
        metrics = get_metrics()
        metrics_1h = metrics.get_all_metrics_summary(minutes=60)
        metrics_24h = metrics.get_all_metrics_summary(minutes=1440)
        
        context = {
            'title': 'Performance Metrics Dashboard',
            'metrics_1h': metrics_1h,
            'metrics_24h': metrics_24h,
        }
        
        return TemplateResponse(request, 'admin/geo_metrics_dashboard.html', context)
    
    @staticmethod
    def errors_summary_view(request):
        """Get a summary of recent errors."""
        error_logger = get_error_logger()
        summary = error_logger.get_error_summary()
        return JsonResponse(summary)
    
    @staticmethod
    def errors_details_view(request):
        """Get detailed error information."""
        error_logger = get_error_logger()
        summary = error_logger.get_error_summary()
        
        error_code = request.GET.get('error_code')
        
        if error_code:
            # Filter errors by code
            recent_errors = [
                e for e in summary.get('recent_errors', [])
                if e.get('error_code') == error_code
            ]
        else:
            recent_errors = summary.get('recent_errors', [])
        
        return JsonResponse({
            'error_code': error_code,
            'errors': recent_errors,
            'total_count': len(recent_errors),
        })
    
    @staticmethod
    def errors_clear_view(request):
        """Clear the error log."""
        if request.method != 'POST':
            return JsonResponse({'error': 'POST method required'}, status=400)
        
        error_logger = get_error_logger()
        error_logger.clear_error_log()
        
        return JsonResponse({'status': 'success', 'message': 'Error log cleared'})
    
    @staticmethod
    @staticmethod
    def errors_dashboard_view(request):
        """Render the error monitoring dashboard."""
        error_logger = get_error_logger()
        error_summary = error_logger.get_error_summary()
        
        context = {
            'title': 'Error Monitoring Dashboard',
            'error_summary': error_summary,
            'total_errors': error_summary.get('total_errors', 0),
            'errors_by_code': error_summary.get('errors_by_code', {}),
            'recent_errors': error_summary.get('recent_errors', []),
        }
        
        return TemplateResponse(request, 'admin/geo_error_dashboard.html', context)


# ============================================================================
# HOMEPAGE CONTENT ADMIN CLASSES
# ============================================================================

@admin.register(HeroSection)
class HeroSectionAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    fieldsets = (
        ('Main Content', {
            'fields': ('headline', 'subheading', 'description', 'badge_text', 'hero_image', 'hero_image_alt'),
            'classes': ('tab',)
        }),
        ('CTA Buttons', {
            'fields': ('cta_primary_text', 'cta_primary_url', 'cta_secondary_text', 'cta_secondary_url'),
            'classes': ('tab',)
        }),
        ('Trust Indicators', {
            'fields': (
                'trust_indicator_1_label', 'trust_indicator_1_value',
                'trust_indicator_2_label', 'trust_indicator_2_value',
                'trust_indicator_3_label', 'trust_indicator_3_value',
            ),
            'classes': ('tab',)
        }),
        ('Badges & Status', {
            'fields': ('uptime_percentage', 'licensed_badge_text', 'is_active', 'regions'),
            'classes': ('tab',)
        }),
    )
    list_display = ('headline', 'is_active', 'updated_at')
    list_filter = ('is_active', 'regions')
    readonly_fields = ('created_at', 'updated_at')


@admin.register(Certification)
class CertificationAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    list_display = ('title', 'description', 'order', 'is_published', 'image_preview')
    list_filter = ('is_published', 'order', 'regions')
    search_fields = ('title', 'description')
    ordering = ['order']
    
    fieldsets = (
        ('Certification Details', {
            'fields': ('title', 'description', 'image', 'image_alt', 'order', 'is_published', 'regions'),
            'classes': ('tab',)
        }),
    )
    
    @admin.display(description='Image')
    def image_preview(self, obj):
        if obj.image:
            return format_html('<img src="{}" style="max-height: 50px; max-width: 100px;" />', obj.image.url)
        return ""


@admin.register(CertificationSection)
class CertificationSectionAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    fieldsets = (
        ('Section Content', {
            'fields': ('badge_text', 'title', 'description'),
            'classes': ('tab',)
        }),
        ('Trust Indicators', {
            'fields': ('trust_indicator_1', 'trust_indicator_2', 'trust_indicator_3'),
            'classes': ('tab',)
        }),
        ('Status', {
            'fields': ('is_active', 'regions'),
            'classes': ('tab',)
        }),
    )
    list_display = ('title', 'is_active', 'updated_at')
    list_filter = ('is_active', 'regions')
    readonly_fields = ('created_at', 'updated_at')


@admin.register(WhyChooseSection)
class WhyChooseSectionAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    fieldsets = (
        ('Section Details', {
            'fields': ('title', 'description', 'is_active', 'regions'),
            'classes': ('tab',)
        }),
    )
    list_display = ('title', 'is_active', 'updated_at')
    list_filter = ('is_active', 'regions')
    readonly_fields = ('created_at', 'updated_at')


class FeatureCardInline(TabularInline):
    model = FeatureCard
    extra = 1
    fields = ('title', 'description', 'icon', 'order')
    ordering = ['order']


@admin.register(FeatureCard)
class FeatureCardAdmin(ModelAdmin):
    list_display = ('title', 'section', 'order', 'updated_at')
    list_filter = ('section', 'order')
    search_fields = ('title', 'description')
    ordering = ['section', 'order']
    
    fieldsets = (
        ('Feature Details', {
            'fields': ('section', 'title', 'description', 'icon', 'order'),
            'classes': ('tab',)
        }),
    )


@admin.register(KeyDifferentiator)
class KeyDifferentiatorAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    list_display = ('title', 'order', 'is_published', 'updated_at')
    list_filter = ('is_published', 'order', 'regions')
    search_fields = ('title', 'description')
    ordering = ['order']
    
    fieldsets = (
        ('Differentiator Details', {
            'fields': ('title', 'description', 'icon', 'order', 'is_published', 'regions'),
            'classes': ('tab',)
        }),
    )


@admin.register(TestimonialSection)
class TestimonialSectionAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    fieldsets = (
        ('Section Details', {
            'fields': ('title', 'description', 'is_active', 'regions'),
            'classes': ('tab',)
        }),
    )
    list_display = ('title', 'is_active', 'updated_at')
    list_filter = ('is_active', 'regions')
    readonly_fields = ('created_at', 'updated_at')


@admin.register(SeoAdvance)
class SeoAdvanceAdmin(RegionRestrictedAdminMixin, ModelAdmin):
    """Admin interface for SEO Advances with AI generation capability."""
    
    list_display = ('title', 'status_badge', 'priority_badge', 'target_ranking', 'current_ranking', 'due_date', 'updated_at')
    list_filter = ('status', 'priority', 'is_active', 'regions', 'created_at')
    search_fields = ('title', 'description', 'target_keywords', 'target_url')
    readonly_fields = ('created_at', 'updated_at', 'completed_date')
    date_hierarchy = 'created_at'
    
    fieldsets = (
        ('Basic Information', {
            'fields': ('title', 'description', 'status', 'priority', 'is_active'),
            'classes': ('tab',)
        }),
        ('Target Configuration', {
            'fields': ('target_url', 'canonical_url', 'target_keywords', 'regions'),
            'classes': ('tab',)
        }),
        ('Meta Tags & Schema', {
            'fields': ('custom_meta_tags', 'schema_markup', 'robots_meta', 'hreflang_tags'),
            'classes': ('tab',)
        }),
        ('Social Media', {
            'fields': ('og_title', 'og_description', 'og_image', 'twitter_card_type'),
            'classes': ('tab',)
        }),
        ('Analytics & Goals', {
            'fields': ('target_traffic', 'current_ranking', 'target_ranking'),
            'classes': ('tab',)
        }),
        ('Implementation', {
            'fields': ('implementation_notes', 'results_notes', 'due_date', 'completed_date'),
            'classes': ('tab',)
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse', 'tab')
        }),
    )
    
    actions = ['mark_as_completed', 'mark_as_in_progress', 'mark_as_pending', 'generate_seo_content']
    
    @admin.display(description='Status', ordering='status')
    def status_badge(self, obj):
        colors = {
            'pending': 'warning',
            'in_progress': 'info',
            'completed': 'success',
            'archived': 'secondary',
        }
        color = colors.get(obj.status, 'secondary')
        return format_html(
            '<span class="unfold-badge unfold-badge--{}">{}</span>',
            color,
            obj.get_status_display()
        )
    
    @admin.display(description='Priority', ordering='priority')
    def priority_badge(self, obj):
        colors = {
            'low': 'secondary',
            'medium': 'info',
            'high': 'warning',
            'critical': 'danger',
        }
        color = colors.get(obj.priority, 'secondary')
        return format_html(
            '<span class="unfold-badge unfold-badge--{}">{}</span>',
            color,
            obj.get_priority_display()
        )
    
    @admin.action(description="Mark selected as completed")
    def mark_as_completed(self, request, queryset):
        from django.utils import timezone
        queryset.update(status='completed', completed_date=timezone.now().date())
        self.message_user(request, f"{queryset.count()} SEO tasks marked as completed.")
    
    @admin.action(description="Mark selected as in progress")
    def mark_as_in_progress(self, request, queryset):
        queryset.update(status='in_progress')
        self.message_user(request, f"{queryset.count()} SEO tasks marked as in progress.")
    
    @admin.action(description="Mark selected as pending")
    def mark_as_pending(self, request, queryset):
        queryset.update(status='pending', completed_date=None)
        self.message_user(request, f"{queryset.count()} SEO tasks marked as pending.")
    
    @admin.action(description="Generate SEO content with AI")
    def generate_seo_content(self, request, queryset):
        """Generate SEO content for selected items using AI."""
        count = 0
        for obj in queryset:
            # Generate meta tags if missing
            if not obj.og_title and obj.title:
                obj.og_title = obj.title[:60]
            
            if not obj.og_description and obj.description:
                obj.og_description = obj.description[:200]
            
            # Generate basic schema markup if missing
            if not obj.schema_markup and obj.target_url:
                obj.schema_markup = f'''{{
  "@context": "https://schema.org",
  "@type": "WebPage",
  "name": "{obj.title}",
  "description": "{obj.description[:160] if obj.description else ''}",
  "url": "{obj.target_url}"
}}'''
            
            # Generate robots meta if missing
            if not obj.robots_meta:
                obj.robots_meta = "index, follow"
            
            obj.save()
            count += 1
        
        self.message_user(request, f"Generated SEO content for {count} items.")


# Extend the default admin site with metrics views
class GeoTargetingAdminSite(PerformanceMetricsAdminMixin, UnfoldAdminSite):
    """Custom admin site with geo-targeting metrics and unfold theme."""
    pass


# Create custom admin site instance
geo_admin_site = GeoTargetingAdminSite(name='geo_admin')

geo_admin_site.register(User, CustomUserAdmin)
geo_admin_site.register(Group, CustomGroupAdmin)

# Register models with the custom admin site
geo_admin_site.register(Region, RegionAdmin)
geo_admin_site.register(Service, ServiceAdmin)
geo_admin_site.register(About, AboutAdmin)
geo_admin_site.register(TeamMember, TeamMemberAdmin)
geo_admin_site.register(Testimonial, TestimonialAdmin)
geo_admin_site.register(RedirectLog, RedirectLogAdmin)
geo_admin_site.register(Contact, ContactAdmin)

# Register Homepage Content Models
geo_admin_site.register(HeroSection, HeroSectionAdmin)
geo_admin_site.register(Certification, CertificationAdmin)
geo_admin_site.register(CertificationSection, CertificationSectionAdmin)
geo_admin_site.register(WhyChooseSection, WhyChooseSectionAdmin)
geo_admin_site.register(FeatureCard, FeatureCardAdmin)
geo_admin_site.register(KeyDifferentiator, KeyDifferentiatorAdmin)
geo_admin_site.register(TestimonialSection, TestimonialSectionAdmin)
geo_admin_site.register(SeoAdvance, SeoAdvanceAdmin)
geo_admin_site.register(FooterLinkGroup, FooterLinkGroupAdmin)
geo_admin_site.register(FooterSettings, FooterSettingsAdmin)
geo_admin_site.register(CompanySettings, CompanySettingsAdmin)

# Import SEO Monitoring Admin
from .seo_monitoring_admin import (
    KeywordRankingAdmin,
    OrganicTrafficAdmin,
    ConversionMetricAdmin,
    CoreWebVitalAdmin,
    CrawlErrorAdmin,
    SEOAlertAdmin,
    SEODashboardMetricsAdmin,
)

# Import Thought Leadership Admin
from .thought_leadership_admin import (
    ResearchProjectAdmin,
    MediaOutreachAdmin,
    AuthorProfileAdmin,
)

# Import Visitor & IP-blocking Admin
from .visitor_admin import (
    VisitorSessionAdmin,
    VisitorPageViewAdmin,
    BlockedIPAdmin,
)

geo_admin_site.register(VisitorSession, VisitorSessionAdmin)
geo_admin_site.register(VisitorPageView, VisitorPageViewAdmin)
geo_admin_site.register(BlockedIP, BlockedIPAdmin)
