"""
Admin interface for versioning models.

Provides Django admin interface for viewing version history,
comparing versions, and managing version records.
"""

from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from unfold.admin import ModelAdmin

from apps.versioning.models import EntityVersion


@admin.register(EntityVersion)
class EntityVersionAdmin(ModelAdmin):
    """
    Admin interface for EntityVersion model.
    
    Provides read-only view of version history with search and filtering.
    """
    
    # Display settings
    list_display = [
        'version_number',
        'entity_link',
        'change_type',
        'changed_by_link',
        'submission_link',
        'changed_field_count',
        'created',
    ]
    
    list_filter = [
        'change_type',
        'entity_type',
        'created',
    ]
    
    search_fields = [
        'entity_id',
        'comment',
        'changed_by__email',
        'changed_by__username',
    ]
    
    ordering = ['-created']
    
    date_hierarchy = 'created'
    
    # Read-only admin (versions should not be modified)
    readonly_fields = [
        'id',
        'entity_type',
        'entity_id',
        'entity_link',
        'version_number',
        'change_type',
        'snapshot_display',
        'changed_fields_display',
        'changed_by',
        'submission',
        'comment',
        'ip_address',
        'user_agent',
        'created',
        'modified',
    ]
    
    fieldsets = (
        ('Version Information', {
            'fields': (
                'id',
                'version_number',
                'change_type',
                'created',
                'modified',
            )
        }),
        ('Entity', {
            'fields': (
                'entity_type',
                'entity_id',
                'entity_link',
            )
        }),
        ('Changes', {
            'fields': (
                'changed_fields_display',
                'snapshot_display',
            )
        }),
        ('Metadata', {
            'fields': (
                'changed_by',
                'submission',
                'comment',
                'ip_address',
                'user_agent',
            )
        }),
    )
    
    def has_add_permission(self, request):
        """Disable adding versions manually."""
        return False
    
    def has_delete_permission(self, request, obj=None):
        """Disable deleting versions."""
        return False
    
    def has_change_permission(self, request, obj=None):
        """Only allow viewing versions, not editing."""
        return False
    
    def entity_link(self, obj):
        """Display link to the entity."""
        try:
            entity = obj.entity
            if entity:
                # Try to get admin URL for entity
                admin_url = reverse(
                    f'admin:{obj.entity_type.app_label}_{obj.entity_type.model}_change',
                    args=[entity.pk]
                )
                return format_html(
                    '<a href="{}">{}</a>',
                    admin_url,
                    str(entity)
                )
        except:
            pass
        return f"{obj.entity_type.model}:{obj.entity_id}"
    entity_link.short_description = 'Entity'
    
    def changed_by_link(self, obj):
        """Display link to user who made the change."""
        if obj.changed_by:
            try:
                admin_url = reverse(
                    'admin:users_user_change',
                    args=[obj.changed_by.pk]
                )
                return format_html(
                    '<a href="{}">{}</a>',
                    admin_url,
                    obj.changed_by.email
                )
            except:
                return obj.changed_by.email
        return '-'
    changed_by_link.short_description = 'Changed By'
    
    def submission_link(self, obj):
        """Display link to content submission if applicable."""
        if obj.submission:
            try:
                admin_url = reverse(
                    'admin:moderation_contentsubmission_change',
                    args=[obj.submission.pk]
                )
                return format_html(
                    '<a href="{}">#{}</a>',
                    admin_url,
                    obj.submission.pk
                )
            except:
                return str(obj.submission.pk)
        return '-'
    submission_link.short_description = 'Submission'
    
    def changed_field_count(self, obj):
        """Display count of changed fields."""
        count = len(obj.changed_fields)
        if count == 0:
            return '-'
        return f"{count} field{'s' if count != 1 else ''}"
    changed_field_count.short_description = 'Changed Fields'
    
    def snapshot_display(self, obj):
        """Display snapshot in a formatted way."""
        import json
        snapshot = obj.get_snapshot_dict()
        
        # Format as pretty JSON
        formatted = json.dumps(snapshot, indent=2, sort_keys=True)
        
        return format_html(
            '<pre style="background: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto;">{}</pre>',
            formatted
        )
    snapshot_display.short_description = 'Snapshot'
    
    def changed_fields_display(self, obj):
        """Display changed fields in a formatted way."""
        if not obj.changed_fields:
            return format_html('<em>No fields changed</em>')
        
        html_parts = ['<table style="width: 100%; border-collapse: collapse;">']
        html_parts.append('<thead><tr style="background: #f5f5f5;">')
        html_parts.append('<th style="padding: 8px; text-align: left; border: 1px solid #ddd;">Field</th>')
        html_parts.append('<th style="padding: 8px; text-align: left; border: 1px solid #ddd;">Old Value</th>')
        html_parts.append('<th style="padding: 8px; text-align: left; border: 1px solid #ddd;">New Value</th>')
        html_parts.append('</tr></thead><tbody>')
        
        for field_name, change in obj.changed_fields.items():
            old_val = change.get('old', '-')
            new_val = change.get('new', '-')
            
            # Truncate long values
            if isinstance(old_val, str) and len(old_val) > 100:
                old_val = old_val[:97] + '...'
            if isinstance(new_val, str) and len(new_val) > 100:
                new_val = new_val[:97] + '...'
            
            html_parts.append('<tr>')
            html_parts.append(f'<td style="padding: 8px; border: 1px solid #ddd;"><strong>{field_name}</strong></td>')
            html_parts.append(f'<td style="padding: 8px; border: 1px solid #ddd; color: #d32f2f;">{old_val}</td>')
            html_parts.append(f'<td style="padding: 8px; border: 1px solid #ddd; color: #388e3c;">{new_val}</td>')
            html_parts.append('</tr>')
        
        html_parts.append('</tbody></table>')
        
        return format_html(''.join(html_parts))
    changed_fields_display.short_description = 'Changed Fields'
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        qs = super().get_queryset(request)
        return qs.select_related(
            'entity_type',
            'changed_by',
            'submission',
            'submission__user'
        )
