"""
Django Admin configuration for entity models with Unfold theme.
"""
from django.contrib import admin
from django.contrib.gis import admin as gis_admin
from django.db.models import Count, Q
from django.utils.html import format_html
from django.urls import reverse
from django.conf import settings
from unfold.admin import ModelAdmin, TabularInline
from unfold.contrib.filters.admin import RangeDateFilter, RangeNumericFilter, RelatedDropdownFilter, ChoicesDropdownFilter
from unfold.contrib.import_export.forms import ImportForm, ExportForm
from import_export.admin import ImportExportModelAdmin
from import_export import resources, fields
from import_export.widgets import ForeignKeyWidget
from .models import Company, RideModel, Park, Ride
from apps.media.admin import PhotoInline


# ============================================================================
# IMPORT/EXPORT RESOURCES
# ============================================================================

class CompanyResource(resources.ModelResource):
    """Import/Export resource for Company model."""
    
    class Meta:
        model = Company
        fields = (
            'id', 'name', 'slug', 'description', 'location',
            'company_types', 'founded_date', 'founded_date_precision',
            'closed_date', 'closed_date_precision', 'website',
            'logo_image_url', 'created', 'modified'
        )
        export_order = fields


class RideModelResource(resources.ModelResource):
    """Import/Export resource for RideModel model."""
    
    manufacturer = fields.Field(
        column_name='manufacturer',
        attribute='manufacturer',
        widget=ForeignKeyWidget(Company, 'name')
    )
    
    class Meta:
        model = RideModel
        fields = (
            'id', 'name', 'slug', 'description', 'manufacturer',
            'model_type', 'typical_height', 'typical_speed',
            'typical_capacity', 'image_url', 'created', 'modified'
        )
        export_order = fields


class ParkResource(resources.ModelResource):
    """Import/Export resource for Park model."""
    
    operator = fields.Field(
        column_name='operator',
        attribute='operator',
        widget=ForeignKeyWidget(Company, 'name')
    )
    
    class Meta:
        model = Park
        fields = (
            'id', 'name', 'slug', 'description', 'park_type', 'status',
            'latitude', 'longitude', 'operator', 'opening_date',
            'opening_date_precision', 'closing_date', 'closing_date_precision',
            'website', 'banner_image_url', 'logo_image_url',
            'created', 'modified'
        )
        export_order = fields


class RideResource(resources.ModelResource):
    """Import/Export resource for Ride model."""
    
    park = fields.Field(
        column_name='park',
        attribute='park',
        widget=ForeignKeyWidget(Park, 'name')
    )
    manufacturer = fields.Field(
        column_name='manufacturer',
        attribute='manufacturer',
        widget=ForeignKeyWidget(Company, 'name')
    )
    model = fields.Field(
        column_name='model',
        attribute='model',
        widget=ForeignKeyWidget(RideModel, 'name')
    )
    
    class Meta:
        model = Ride
        fields = (
            'id', 'name', 'slug', 'description', 'park', 'ride_category',
            'ride_type', 'status', 'manufacturer', 'model', 'height',
            'speed', 'length', 'duration', 'inversions', 'capacity',
            'opening_date', 'opening_date_precision', 'closing_date',
            'closing_date_precision', 'image_url', 'created', 'modified'
        )
        export_order = fields


# ============================================================================
# INLINE ADMIN CLASSES
# ============================================================================

class RideInline(TabularInline):
    """Inline for Rides within a Park."""
    
    model = Ride
    extra = 0
    fields = ['name', 'ride_category', 'status', 'manufacturer', 'opening_date']
    readonly_fields = ['name']
    show_change_link = True
    classes = ['collapse']
    
    def has_add_permission(self, request, obj=None):
        return False


class CompanyParksInline(TabularInline):
    """Inline for Parks operated by a Company."""
    
    model = Park
    fk_name = 'operator'
    extra = 0
    fields = ['name', 'park_type', 'status', 'ride_count', 'opening_date']
    readonly_fields = ['name', 'ride_count']
    show_change_link = True
    classes = ['collapse']
    
    def has_add_permission(self, request, obj=None):
        return False


class RideModelInstallationsInline(TabularInline):
    """Inline for Ride installations of a RideModel."""
    
    model = Ride
    fk_name = 'model'
    extra = 0
    fields = ['name', 'park', 'status', 'opening_date']
    readonly_fields = ['name', 'park']
    show_change_link = True
    classes = ['collapse']
    
    def has_add_permission(self, request, obj=None):
        return False


# ============================================================================
# MAIN ADMIN CLASSES
# ============================================================================

@admin.register(Company)
class CompanyAdmin(ModelAdmin, ImportExportModelAdmin):
    """Enhanced admin interface for Company model."""
    
    resource_class = CompanyResource
    import_form_class = ImportForm
    export_form_class = ExportForm
    
    list_display = [
        'name_with_icon',
        'location',
        'company_types_display',
        'park_count',
        'ride_count',
        'founded_date',
        'status_indicator',
        'created'
    ]
    list_filter = [
        ('company_types', ChoicesDropdownFilter),
        ('founded_date', RangeDateFilter),
        ('closed_date', RangeDateFilter),
    ]
    search_fields = ['name', 'slug', 'description', 'location']
    readonly_fields = ['id', 'created', 'modified', 'park_count', 'ride_count', 'slug']
    prepopulated_fields = {}  # Slug is auto-generated via lifecycle hook
    autocomplete_fields = []
    inlines = [CompanyParksInline, PhotoInline]
    
    list_per_page = 50
    list_max_show_all = 200
    
    fieldsets = (
        ('Basic Information', {
            'fields': ('name', 'slug', 'description', 'company_types')
        }),
        ('Location & Contact', {
            'fields': ('location', 'website')
        }),
        ('History', {
            'fields': (
                'founded_date', 'founded_date_precision',
                'closed_date', 'closed_date_precision'
            )
        }),
        ('Media', {
            'fields': ('logo_image_id', 'logo_image_url'),
            'classes': ['collapse']
        }),
        ('Statistics', {
            'fields': ('park_count', 'ride_count'),
            'classes': ['collapse']
        }),
        ('System Information', {
            'fields': ('id', 'created', 'modified'),
            'classes': ['collapse']
        }),
    )
    
    def name_with_icon(self, obj):
        """Display name with company type icon."""
        icons = {
            'manufacturer': '🏭',
            'operator': '🎡',
            'designer': '✏️',
        }
        icon = '🏢'  # Default company icon
        if obj.company_types:
            for ctype in obj.company_types:
                if ctype in icons:
                    icon = icons[ctype]
                    break
        return format_html('{} {}', icon, obj.name)
    name_with_icon.short_description = 'Company'
    name_with_icon.admin_order_field = 'name'
    
    def company_types_display(self, obj):
        """Display company types as badges."""
        if not obj.company_types:
            return '-'
        badges = []
        for ctype in obj.company_types:
            color = {
                'manufacturer': 'blue',
                'operator': 'green',
                'designer': 'purple',
            }.get(ctype, 'gray')
            badges.append(
                f'<span style="background-color: {color}; color: white; '
                f'padding: 2px 8px; border-radius: 4px; font-size: 11px; '
                f'margin-right: 4px;">{ctype.upper()}</span>'
            )
        return format_html(' '.join(badges))
    company_types_display.short_description = 'Types'
    
    def status_indicator(self, obj):
        """Visual status indicator."""
        if obj.closed_date:
            return format_html(
                '<span style="color: red;">●</span> Closed'
            )
        return format_html(
            '<span style="color: green;">●</span> Active'
        )
    status_indicator.short_description = 'Status'
    
    actions = ['export_admin_action']


@admin.register(RideModel)
class RideModelAdmin(ModelAdmin, ImportExportModelAdmin):
    """Enhanced admin interface for RideModel model."""
    
    resource_class = RideModelResource
    import_form_class = ImportForm
    export_form_class = ExportForm
    
    list_display = [
        'name_with_type',
        'manufacturer',
        'model_type',
        'typical_specs',
        'installation_count',
        'created'
    ]
    list_filter = [
        ('model_type', ChoicesDropdownFilter),
        ('manufacturer', RelatedDropdownFilter),
        ('typical_height', RangeNumericFilter),
        ('typical_speed', RangeNumericFilter),
    ]
    search_fields = ['name', 'slug', 'description', 'manufacturer__name']
    readonly_fields = ['id', 'created', 'modified', 'installation_count', 'slug']
    prepopulated_fields = {}
    autocomplete_fields = ['manufacturer']
    inlines = [RideModelInstallationsInline, PhotoInline]
    
    list_per_page = 50
    
    fieldsets = (
        ('Basic Information', {
            'fields': ('name', 'slug', 'description', 'manufacturer', 'model_type')
        }),
        ('Typical Specifications', {
            'fields': (
                'typical_height', 'typical_speed', 'typical_capacity'
            ),
            'description': 'Standard specifications for this ride model'
        }),
        ('Media', {
            'fields': ('image_id', 'image_url'),
            'classes': ['collapse']
        }),
        ('Statistics', {
            'fields': ('installation_count',),
            'classes': ['collapse']
        }),
        ('System Information', {
            'fields': ('id', 'created', 'modified'),
            'classes': ['collapse']
        }),
    )
    
    def name_with_type(self, obj):
        """Display name with model type icon."""
        icons = {
            'roller_coaster': '🎢',
            'water_ride': '🌊',
            'flat_ride': '🎡',
            'dark_ride': '🎭',
            'transport': '🚂',
        }
        icon = icons.get(obj.model_type, '🎪')
        return format_html('{} {}', icon, obj.name)
    name_with_type.short_description = 'Model Name'
    name_with_type.admin_order_field = 'name'
    
    def typical_specs(self, obj):
        """Display typical specifications."""
        specs = []
        if obj.typical_height:
            specs.append(f'H: {obj.typical_height}m')
        if obj.typical_speed:
            specs.append(f'S: {obj.typical_speed}km/h')
        if obj.typical_capacity:
            specs.append(f'C: {obj.typical_capacity}')
        return ' | '.join(specs) if specs else '-'
    typical_specs.short_description = 'Typical Specs'
    
    actions = ['export_admin_action']


@admin.register(Park)
class ParkAdmin(ModelAdmin, ImportExportModelAdmin):
    """Enhanced admin interface for Park model with geographic features."""
    
    resource_class = ParkResource
    import_form_class = ImportForm
    export_form_class = ExportForm
    
    list_display = [
        'name_with_icon',
        'location_display',
        'park_type',
        'status_badge',
        'ride_count',
        'coaster_count',
        'opening_date',
        'operator'
    ]
    list_filter = [
        ('park_type', ChoicesDropdownFilter),
        ('status', ChoicesDropdownFilter),
        ('operator', RelatedDropdownFilter),
        ('opening_date', RangeDateFilter),
        ('closing_date', RangeDateFilter),
    ]
    search_fields = ['name', 'slug', 'description', 'location']
    readonly_fields = [
        'id', 'created', 'modified', 'ride_count', 'coaster_count',
        'slug', 'coordinates_display'
    ]
    prepopulated_fields = {}
    autocomplete_fields = ['operator']
    inlines = [RideInline, PhotoInline]
    
    list_per_page = 50
    
    # Use GeoDjango admin for PostGIS mode
    if hasattr(settings, 'DATABASES') and 'postgis' in settings.DATABASES['default'].get('ENGINE', ''):
        change_form_template = 'gis/admin/change_form.html'
    
    fieldsets = (
        ('Basic Information', {
            'fields': ('name', 'slug', 'description', 'park_type', 'status')
        }),
        ('Geographic Location', {
            'fields': ('location', 'latitude', 'longitude', 'coordinates_display'),
            'description': 'Enter latitude and longitude for the park location'
        }),
        ('Dates', {
            'fields': (
                'opening_date', 'opening_date_precision',
                'closing_date', 'closing_date_precision'
            )
        }),
        ('Operator', {
            'fields': ('operator',)
        }),
        ('Media & Web', {
            'fields': (
                'banner_image_id', 'banner_image_url',
                'logo_image_id', 'logo_image_url',
                'website'
            ),
            'classes': ['collapse']
        }),
        ('Statistics', {
            'fields': ('ride_count', 'coaster_count'),
            'classes': ['collapse']
        }),
        ('Custom Data', {
            'fields': ('custom_fields',),
            'classes': ['collapse'],
            'description': 'Additional custom data in JSON format'
        }),
        ('System Information', {
            'fields': ('id', 'created', 'modified'),
            'classes': ['collapse']
        }),
    )
    
    def name_with_icon(self, obj):
        """Display name with park type icon."""
        icons = {
            'theme_park': '🎡',
            'amusement_park': '🎢',
            'water_park': '🌊',
            'indoor_park': '🏢',
            'fairground': '🎪',
        }
        icon = icons.get(obj.park_type, '🎠')
        return format_html('{} {}', icon, obj.name)
    name_with_icon.short_description = 'Park Name'
    name_with_icon.admin_order_field = 'name'
    
    def location_display(self, obj):
        """Display location with coordinates."""
        if obj.location:
            coords = obj.coordinates
            if coords:
                return format_html(
                    '{}<br><small style="color: gray;">({:.4f}, {:.4f})</small>',
                    obj.location, coords[0], coords[1]
                )
            return obj.location
        return '-'
    location_display.short_description = 'Location'
    
    def coordinates_display(self, obj):
        """Read-only display of coordinates."""
        coords = obj.coordinates
        if coords:
            return f"Longitude: {coords[0]:.6f}, Latitude: {coords[1]:.6f}"
        return "No coordinates set"
    coordinates_display.short_description = 'Current Coordinates'
    
    def status_badge(self, obj):
        """Display status as colored badge."""
        colors = {
            'operating': 'green',
            'closed_temporarily': 'orange',
            'closed_permanently': 'red',
            'under_construction': 'blue',
            'planned': 'purple',
        }
        color = colors.get(obj.status, 'gray')
        return format_html(
            '<span style="background-color: {}; color: white; '
            'padding: 3px 10px; border-radius: 12px; font-size: 11px;">'
            '{}</span>',
            color, obj.get_status_display()
        )
    status_badge.short_description = 'Status'
    status_badge.admin_order_field = 'status'
    
    actions = ['export_admin_action', 'activate_parks', 'close_parks']
    
    def activate_parks(self, request, queryset):
        """Bulk action to activate parks."""
        updated = queryset.update(status='operating')
        self.message_user(request, f'{updated} park(s) marked as operating.')
    activate_parks.short_description = 'Mark selected parks as operating'
    
    def close_parks(self, request, queryset):
        """Bulk action to close parks temporarily."""
        updated = queryset.update(status='closed_temporarily')
        self.message_user(request, f'{updated} park(s) marked as temporarily closed.')
    close_parks.short_description = 'Mark selected parks as temporarily closed'


@admin.register(Ride)
class RideAdmin(ModelAdmin, ImportExportModelAdmin):
    """Enhanced admin interface for Ride model."""
    
    resource_class = RideResource
    import_form_class = ImportForm
    export_form_class = ExportForm
    
    list_display = [
        'name_with_icon',
        'park',
        'ride_category',
        'status_badge',
        'manufacturer',
        'stats_display',
        'opening_date',
        'coaster_badge'
    ]
    list_filter = [
        ('ride_category', ChoicesDropdownFilter),
        ('status', ChoicesDropdownFilter),
        ('is_coaster', admin.BooleanFieldListFilter),
        ('park', RelatedDropdownFilter),
        ('manufacturer', RelatedDropdownFilter),
        ('opening_date', RangeDateFilter),
        ('height', RangeNumericFilter),
        ('speed', RangeNumericFilter),
    ]
    search_fields = [
        'name', 'slug', 'description',
        'park__name', 'manufacturer__name'
    ]
    readonly_fields = ['id', 'created', 'modified', 'is_coaster', 'slug']
    prepopulated_fields = {}
    autocomplete_fields = ['park', 'manufacturer', 'model']
    inlines = [PhotoInline]
    
    list_per_page = 50
    
    fieldsets = (
        ('Basic Information', {
            'fields': ('name', 'slug', 'description', 'park')
        }),
        ('Classification', {
            'fields': ('ride_category', 'ride_type', 'is_coaster', 'status')
        }),
        ('Dates', {
            'fields': (
                'opening_date', 'opening_date_precision',
                'closing_date', 'closing_date_precision'
            )
        }),
        ('Manufacturer & Model', {
            'fields': ('manufacturer', 'model')
        }),
        ('Ride Statistics', {
            'fields': (
                'height', 'speed', 'length',
                'duration', 'inversions', 'capacity'
            ),
            'description': 'Technical specifications and statistics'
        }),
        ('Media', {
            'fields': ('image_id', 'image_url'),
            'classes': ['collapse']
        }),
        ('Custom Data', {
            'fields': ('custom_fields',),
            'classes': ['collapse']
        }),
        ('System Information', {
            'fields': ('id', 'created', 'modified'),
            'classes': ['collapse']
        }),
    )
    
    def name_with_icon(self, obj):
        """Display name with category icon."""
        icons = {
            'roller_coaster': '🎢',
            'water_ride': '🌊',
            'dark_ride': '🎭',
            'flat_ride': '🎡',
            'transport': '🚂',
            'show': '🎪',
        }
        icon = icons.get(obj.ride_category, '🎠')
        return format_html('{} {}', icon, obj.name)
    name_with_icon.short_description = 'Ride Name'
    name_with_icon.admin_order_field = 'name'
    
    def stats_display(self, obj):
        """Display key statistics."""
        stats = []
        if obj.height:
            stats.append(f'H: {obj.height}m')
        if obj.speed:
            stats.append(f'S: {obj.speed}km/h')
        if obj.inversions:
            stats.append(f'🔄 {obj.inversions}')
        return ' | '.join(stats) if stats else '-'
    stats_display.short_description = 'Key Stats'
    
    def coaster_badge(self, obj):
        """Display coaster indicator."""
        if obj.is_coaster:
            return format_html(
                '<span style="background-color: #ff6b6b; color: white; '
                'padding: 2px 8px; border-radius: 10px; font-size: 10px;">'
                '🎢 COASTER</span>'
            )
        return ''
    coaster_badge.short_description = 'Type'
    
    def status_badge(self, obj):
        """Display status as colored badge."""
        colors = {
            'operating': 'green',
            'closed_temporarily': 'orange',
            'closed_permanently': 'red',
            'under_construction': 'blue',
            'sbno': 'gray',
        }
        color = colors.get(obj.status, 'gray')
        return format_html(
            '<span style="background-color: {}; color: white; '
            'padding: 3px 10px; border-radius: 12px; font-size: 11px;">'
            '{}</span>',
            color, obj.get_status_display()
        )
    status_badge.short_description = 'Status'
    status_badge.admin_order_field = 'status'
    
    actions = ['export_admin_action', 'activate_rides', 'close_rides']
    
    def activate_rides(self, request, queryset):
        """Bulk action to activate rides."""
        updated = queryset.update(status='operating')
        self.message_user(request, f'{updated} ride(s) marked as operating.')
    activate_rides.short_description = 'Mark selected rides as operating'
    
    def close_rides(self, request, queryset):
        """Bulk action to close rides temporarily."""
        updated = queryset.update(status='closed_temporarily')
        self.message_user(request, f'{updated} ride(s) marked as temporarily closed.')
    close_rides.short_description = 'Mark selected rides as temporarily closed'


# ============================================================================
# DASHBOARD CALLBACK
# ============================================================================

def dashboard_callback(request, context):
    """
    Callback function for Unfold dashboard.
    Provides statistics and overview data.
    """
    # Entity counts
    total_parks = Park.objects.count()
    total_rides = Ride.objects.count()
    total_companies = Company.objects.count()
    total_models = RideModel.objects.count()
    
    # Operating counts
    operating_parks = Park.objects.filter(status='operating').count()
    operating_rides = Ride.objects.filter(status='operating').count()
    
    # Coaster count
    total_coasters = Ride.objects.filter(is_coaster=True).count()
    
    # Recent additions (last 30 days)
    from django.utils import timezone
    from datetime import timedelta
    thirty_days_ago = timezone.now() - timedelta(days=30)
    
    recent_parks = Park.objects.filter(created__gte=thirty_days_ago).count()
    recent_rides = Ride.objects.filter(created__gte=thirty_days_ago).count()
    
    # Top manufacturers by ride count
    top_manufacturers = Company.objects.filter(
        company_types__contains=['manufacturer']
    ).annotate(
        ride_count_actual=Count('manufactured_rides')
    ).order_by('-ride_count_actual')[:5]
    
    # Parks by type
    parks_by_type = Park.objects.values('park_type').annotate(
        count=Count('id')
    ).order_by('-count')
    
    context.update({
        'total_parks': total_parks,
        'total_rides': total_rides,
        'total_companies': total_companies,
        'total_models': total_models,
        'operating_parks': operating_parks,
        'operating_rides': operating_rides,
        'total_coasters': total_coasters,
        'recent_parks': recent_parks,
        'recent_rides': recent_rides,
        'top_manufacturers': top_manufacturers,
        'parks_by_type': parks_by_type,
    })
    
    return context
