from django.contrib import admin
from django.urls import path
from django.utils.html import format_html

from .admin_forms import (
    ClaimAdminForm,
    CounterArgumentInlineForm,
    EvidenceFileInlineForm,
    SourceInlineForm,
)
from .admin_views import AssistantView, ReviewDraftView
from .models import Category, Claim, ClaimDraft, CounterArgument, EvidenceFile, Source, Tag


class FaktenAdminMixin:
    class Media:
        css = {'all': ['css/admin_custom.css']}
        js = ['js/admin_custom.js']


class EvidenceFileInline(FaktenAdminMixin, admin.StackedInline):
    model = EvidenceFile
    form = EvidenceFileInlineForm
    extra = 1
    fields = ('preview', 'file', 'title', 'caption', 'order')
    readonly_fields = ('preview',)
    classes = ('collapse-open',)
    verbose_name = 'Nachweis'
    verbose_name_plural = 'Nachweise (Grafiken / PDFs)'

    @admin.display(description='Vorschau')
    def preview(self, obj):
        if not obj or not obj.pk or not obj.file:
            return format_html('<span class="quiet">Nach dem Speichern sichtbar</span>')
        if obj.is_image:
            return format_html(
                '<div class="fk-evidence-preview"><a href="{}" target="_blank" rel="noopener">'
                '<img src="{}" alt="{}"></a></div>',
                obj.file.url,
                obj.file.url,
                obj.image_alt,
            )
        if obj.is_pdf:
            return format_html(
                '<div class="fk-evidence-preview"><a href="{}" target="_blank" rel="noopener">'
                '📄 PDF öffnen</a></div>',
                obj.file.url,
            )
        return '—'


class SourceInline(FaktenAdminMixin, admin.StackedInline):
    model = Source
    form = SourceInlineForm
    extra = 1
    fields = ('title', 'organization', 'url', 'description')
    classes = ('collapse-open',)
    verbose_name = 'Quelle'
    verbose_name_plural = 'Quellen'


class CounterArgumentInline(FaktenAdminMixin, admin.StackedInline):
    model = CounterArgument
    form = CounterArgumentInlineForm
    extra = 1
    fields = ('argument', 'response')
    classes = ('collapse-open',)
    verbose_name = 'Gegenargument'
    verbose_name_plural = 'Gegenargumente'


@admin.register(Tag)
class TagAdmin(FaktenAdminMixin, admin.ModelAdmin):
    list_display = ('name', 'slug')
    prepopulated_fields = {'slug': ('name',)}
    search_fields = ('name',)


@admin.register(Category)
class CategoryAdmin(FaktenAdminMixin, admin.ModelAdmin):
    list_display = ('name', 'slug', 'claim_count', 'created_at')
    prepopulated_fields = {'slug': ('name',)}
    search_fields = ('name', 'description')
    fieldsets = (
        (None, {
            'fields': ('name', 'slug', 'icon'),
        }),
        ('Beschreibung', {
            'fields': ('description',),
            'classes': ('wide',),
        }),
    )

    def formfield_for_dbfield(self, db_field, request, **kwargs):
        formfield = super().formfield_for_dbfield(db_field, request, **kwargs)
        if db_field.name == 'description':
            formfield.widget.attrs.update({'rows': 4, 'class': 'fk-admin-textarea'})
        return formfield

    @admin.display(description='Anzahl Behauptungen')
    def claim_count(self, obj):
        return obj.claims.count()


@admin.register(Claim)
class ClaimAdmin(FaktenAdminMixin, admin.ModelAdmin):
    form = ClaimAdminForm
    change_form_template = 'admin/claims/claim/change_form.html'
    list_display = ('title', 'category', 'status', 'evidence_level', 'updated_at')
    list_display_links = ('title',)
    list_filter = ('category', 'status', 'evidence_level', 'tags')
    search_fields = ('title', 'short_answer', 'detailed_explanation')
    prepopulated_fields = {'slug': ('title',)}
    filter_horizontal = ('tags',)
    autocomplete_fields = ('category',)
    save_on_top = True
    date_hierarchy = 'updated_at'
    inlines = [EvidenceFileInline, SourceInline, CounterArgumentInline]
    readonly_fields = ('public_link', 'created_at', 'updated_at')
    fieldsets = (
        ('Einordnung', {
            'fields': ('category', 'status', 'evidence_level', 'tags'),
        }),
        ('Behauptung', {
            'fields': ('title', 'slug', 'public_link'),
        }),
        ('Texte', {
            'fields': ('short_answer', 'detailed_explanation'),
            'classes': ('wide',),
            'description': 'Kurzantwort: in ~20 Sekunden lesbar. Ausführliche Erklärung optional.',
        }),
        ('Zeitstempel', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',),
        }),
    )

    @admin.display(description='Website')
    def public_link(self, obj):
        if not obj.pk:
            return '—'
        return format_html(
            '<a href="{}" target="_blank" rel="noopener">Behauptung auf der Website öffnen</a>',
            obj.get_absolute_url(),
        )


@admin.register(EvidenceFile)
class EvidenceFileAdmin(FaktenAdminMixin, admin.ModelAdmin):
    list_display = ('preview_thumb', 'display_title', 'claim', 'order', 'created_at')
    list_filter = ('claim__category',)
    search_fields = ('title', 'caption', 'claim__title')
    readonly_fields = ('preview',)
    fields = ('claim', 'preview', 'file', 'title', 'caption', 'order')

    @admin.display(description='')
    def preview_thumb(self, obj):
        if obj.is_image and obj.file:
            return format_html(
                '<img src="{}" style="max-width:48px;max-height:48px;object-fit:contain">',
                obj.file.url,
            )
        return obj.file_extension.upper()

    @admin.display(description='Vorschau')
    def preview(self, obj):
        return EvidenceFileInline.preview(self, obj)


@admin.register(Source)
class SourceAdmin(FaktenAdminMixin, admin.ModelAdmin):
    form = SourceInlineForm
    list_display = ('title', 'organization', 'claim')
    list_filter = ('claim__category',)
    search_fields = ('title', 'organization', 'description')


@admin.register(CounterArgument)
class CounterArgumentAdmin(FaktenAdminMixin, admin.ModelAdmin):
    form = CounterArgumentInlineForm
    list_display = ('argument_preview', 'claim')
    list_filter = ('claim__category',)
    search_fields = ('argument', 'response')

    @admin.display(description='Gegenargument')
    def argument_preview(self, obj):
        return obj.argument[:80]


@admin.register(ClaimDraft)
class ClaimDraftAdmin(FaktenAdminMixin, admin.ModelAdmin):
    change_list_template = 'admin/claims/claimdraft/change_list.html'
    list_display = ('title', 'status', 'created_by', 'created_at', 'published_claim')
    list_filter = ('status', 'created_at')
    search_fields = ('title', 'user_notes', 'article_url')
    readonly_fields = (
        'created_by', 'status', 'article_url', 'user_notes', 'uploaded_file',
        'article_text', 'conversation', 'ai_raw_response', 'error_message',
        'published_claim', 'created_at', 'updated_at',
    )

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(created_by=request.user)

    def has_change_permission(self, request, obj=None):
        if obj and not request.user.is_superuser and obj.created_by_id != request.user.id:
            return False
        return super().has_change_permission(request, obj)

    def has_delete_permission(self, request, obj=None):
        if obj and not request.user.is_superuser and obj.created_by_id != request.user.id:
            return False
        return super().has_delete_permission(request, obj)

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path(
                'assistant/',
                self.admin_site.admin_view(AssistantView.as_view()),
                name='claims_claimdraft_assistant',
            ),
            path(
                '<int:draft_id>/review/',
                self.admin_site.admin_view(ReviewDraftView.as_view()),
                name='claims_claimdraft_review',
            ),
        ]
        return custom_urls + urls
