from django.contrib import admin
from django.http import FileResponse, Http404, HttpResponseRedirect
from django.urls import path, reverse
from django.utils.html import format_html

from apps.core.admin_video import video_admin_preview
from apps.core.video import VIDEO_ADMIN_FIELDSET

from .models import (
    AboutSection,
    AboutSectionItem,
    ContactSubmission,
    ContactSubmissionAttachment,
    CustomPage,
    CustomPageSection,
    CustomPageSectionItem,
    DownloadItem,
    FAQEntry,
    HeroSection,
    HomepageSection,
    HomepageSectionItem,
    PageVideo,
)


@admin.register(HeroSection)
class HeroSectionAdmin(admin.ModelAdmin):
    fieldsets = (
        ("Badge", {"fields": ("badge",)}),
        ("Title", {"fields": ("title", "title_highlight")}),
        ("Text", {"fields": ("subtitle", "description")}),
        ("Primary Button", {"fields": ("primary_cta_text", "primary_cta_url")}),
        ("Secondary Button", {"fields": ("secondary_cta_text", "secondary_cta_url")}),
        ("Image", {"fields": ("image", "image_alt")}),
    )

    def has_add_permission(self, request):
        return not HeroSection.objects.exists()

    def has_delete_permission(self, request, obj=None):
        return False

    def changelist_view(self, request, extra_context=None):
        hero = HeroSection.objects.first()
        if hero:
            return HttpResponseRedirect(
                reverse("admin:pages_herosection_change", args=[hero.pk])
            )
        return super().changelist_view(request, extra_context)


class HomepageSectionItemInline(admin.TabularInline):
    model = HomepageSectionItem
    extra = 1
    fields = (
        "icon",
        "title",
        "content",
        "url",
        "image",
        "image_alt",
        "tags",
        "project_status",
        "order",
    )
    ordering = ("order",)


@admin.register(HomepageSection)
class HomepageSectionAdmin(admin.ModelAdmin):
    list_display = ("section_type", "title", "badge", "order", "is_active")
    list_filter = ("section_type", "is_active")
    list_editable = ("order", "is_active")
    inlines = [HomepageSectionItemInline]
    readonly_fields = ("video_preview",)
    fieldsets = (
        (None, {"fields": ("section_type", "badge", "title", "title_highlight", "description_format", "description")}),
        ("CTA Link (About Strip)", {"fields": ("link_text", "link_url"), "classes": ("collapse",)}),
        VIDEO_ADMIN_FIELDSET,
        ("Settings", {"fields": ("order", "is_active")}),
    )

    @admin.display(description="Preview")
    def video_preview(self, obj):
        return video_admin_preview(obj)


class AboutSectionItemInline(admin.TabularInline):
    model = AboutSectionItem
    extra = 1
    fields = ("icon", "title", "content", "url", "image", "image_alt", "badge", "is_featured", "order")
    ordering = ("order",)


@admin.register(AboutSection)
class AboutSectionAdmin(admin.ModelAdmin):
    list_display = ("section_type", "badge", "title", "order", "is_active")
    list_filter = ("section_type", "is_active")
    list_editable = ("order", "is_active")
    inlines = [AboutSectionItemInline]
    readonly_fields = ("video_preview",)
    fieldsets = (
        (None, {"fields": ("section_type", "badge", "title", "subtitle")}),
        ("Content", {"fields": ("content_format", "content")}),
        VIDEO_ADMIN_FIELDSET,
        ("Settings", {"fields": ("order", "is_active")}),
    )

    @admin.display(description="Preview")
    def video_preview(self, obj):
        return video_admin_preview(obj)


class ContactSubmissionAttachmentInline(admin.TabularInline):
    model = ContactSubmissionAttachment
    extra = 0
    can_delete = False
    fields = ("original_filename", "attachment_link", "uploaded_at")
    readonly_fields = ("original_filename", "attachment_link", "uploaded_at")

    @admin.display(description="File")
    def attachment_link(self, obj):
        if not obj.file:
            return "—"
        url = reverse("admin:pages_contactattachment_download", args=[obj.pk])
        return format_html('<a href="{}">Download</a>', url)


@admin.register(ContactSubmission)
class ContactSubmissionAdmin(admin.ModelAdmin):
    list_display = ("name", "title", "email", "submitted_at", "is_read")
    list_filter = ("is_read", "submitted_at")
    search_fields = ("name", "title", "description", "email")
    list_editable = ("is_read",)
    readonly_fields = ("name", "title", "description", "email", "submitted_at")
    inlines = [ContactSubmissionAttachmentInline]
    fieldsets = (
        (None, {"fields": ("name", "title", "email", "description")}),
        ("Meta", {"fields": ("submitted_at", "is_read")}),
    )

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path(
                "attachment/<int:attachment_id>/download/",
                self.admin_site.admin_view(self.download_attachment),
                name="pages_contactattachment_download",
            ),
        ]
        return custom_urls + urls

    def download_attachment(self, request, attachment_id):
        try:
            attachment = ContactSubmissionAttachment.objects.get(pk=attachment_id)
        except ContactSubmissionAttachment.DoesNotExist as exc:
            raise Http404 from exc
        if not attachment.file:
            raise Http404
        return FileResponse(
            attachment.file.open("rb"),
            as_attachment=True,
            filename=attachment.original_filename,
        )


@admin.register(FAQEntry)
class FAQEntryAdmin(admin.ModelAdmin):
    list_display = ("question", "order", "is_active", "created_at")
    list_filter = ("is_active",)
    search_fields = ("question", "answer")
    list_editable = ("order", "is_active")
    fieldsets = (
        (None, {"fields": ("question",)}),
        ("Answer", {"fields": ("answer_format", "answer")}),
        ("Settings", {"fields": ("order", "is_active")}),
    )


class CustomPageSectionItemInline(admin.TabularInline):
    model = CustomPageSectionItem
    extra = 1
    fields = (
        "icon",
        "badge",
        "title",
        "content_format",
        "content",
        "url",
        "image",
        "image_alt",
        "is_featured",
        "order",
    )
    ordering = ("order",)


class CustomPageSectionInline(admin.StackedInline):
    model = CustomPageSection
    extra = 1
    fields = (
        "section_type",
        "badge",
        "title",
        "subtitle",
        "description_format",
        "description",
        "content_format",
        "content",
        "link_text",
        "link_url",
        "order",
        "is_active",
    )
    ordering = ("order",)
    show_change_link = True


class CustomPageSectionItemOnPageInline(admin.TabularInline):
    model = CustomPageSectionItem
    fk_name = "page"
    extra = 1
    verbose_name = "Section item"
    verbose_name_plural = "Section items (subsections)"
    fields = (
        "section",
        "icon",
        "badge",
        "title",
        "content_format",
        "content",
        "url",
        "image",
        "order",
    )
    ordering = ("section", "order")

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "section":
            page_id = request.resolver_match.kwargs.get("object_id") if request.resolver_match else None
            if page_id:
                kwargs["queryset"] = CustomPageSection.objects.filter(page_id=page_id).order_by("order")
        return super().formfield_for_foreignkey(db_field, request, **kwargs)


class CustomPageSectionAdmin(admin.ModelAdmin):
    list_display = ("page", "section_type", "title", "order", "is_active")
    list_filter = ("section_type", "is_active", "page")
    list_editable = ("order", "is_active")
    inlines = [CustomPageSectionItemInline]
    readonly_fields = ("video_preview",)
    fieldsets = (
        (None, {"fields": ("page", "section_type", "badge", "title", "subtitle")}),
        ("Text", {"fields": ("description_format", "description", "content_format", "content")}),
        ("CTA Link", {"fields": ("link_text", "link_url"), "classes": ("collapse",)}),
        VIDEO_ADMIN_FIELDSET,
        ("Settings", {"fields": ("order", "is_active")}),
    )

    @admin.display(description="Preview")
    def video_preview(self, obj):
        return video_admin_preview(obj)

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instance in instances:
            if isinstance(instance, CustomPageSectionItem):
                instance.page = form.instance.page
            instance.save()
        for obj in formset.deleted_objects:
            obj.delete()
        formset.save_m2m()


@admin.register(CustomPage)
class CustomPageAdmin(admin.ModelAdmin):
    list_display = ("title", "slug", "show_in_nav", "menu_order", "is_published", "updated_at")
    list_filter = ("show_in_nav", "is_published")
    search_fields = ("title", "slug", "menu_label")
    list_editable = ("show_in_nav", "menu_order", "is_published")
    prepopulated_fields = {"slug": ("title",)}
    inlines = [CustomPageSectionInline, CustomPageSectionItemOnPageInline]
    fieldsets = (
        (None, {"fields": ("title", "slug", "menu_label", "meta_description")}),
        ("Navigation", {"fields": ("show_in_nav", "menu_order")}),
        ("Publishing", {"fields": ("is_published",)}),
    )

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instance in instances:
            if isinstance(instance, CustomPageSectionItem):
                instance.page = form.instance
            instance.save()
        for obj in formset.deleted_objects:
            obj.delete()
        formset.save_m2m()


admin.site.register(CustomPageSection, CustomPageSectionAdmin)


@admin.register(PageVideo)
class PageVideoAdmin(admin.ModelAdmin):
    list_display = ("page", "title", "video_source", "video_size", "order", "is_active")
    list_filter = ("page", "video_source", "is_active")
    list_editable = ("order", "is_active")
    search_fields = ("title", "description", "video_url")
    readonly_fields = ("video_preview",)
    fieldsets = (
        (None, {"fields": ("page", "badge", "title", "description_format", "description")}),
        VIDEO_ADMIN_FIELDSET,
        ("Settings", {"fields": ("order", "is_active")}),
    )

    @admin.display(description="Preview")
    def video_preview(self, obj):
        return video_admin_preview(obj)


@admin.register(DownloadItem)
class DownloadItemAdmin(admin.ModelAdmin):
    list_display = ("name", "platform", "version", "is_active", "order")
    list_filter = ("platform", "is_active")
    search_fields = ("name", "description")
    list_editable = ("order", "is_active")
    fieldsets = (
        (None, {"fields": ("name", "platform", "version", "download_url", "description")}),
        ("Settings", {"fields": ("order", "is_active")}),
    )
