from django.contrib import admin
from django.utils.html import format_html
from django.utils.safestring import mark_safe

from .models import Config, Guestbook, Memory, MemoryPhoto


class JournalStaffAccessMixin:
    """
    手账站点多为小项目：凡 is_staff 即可在后台增删改查（无需在「用户」里逐项勾选 journal.* 权限）。
    生产环境若需细分权限，可移除此 Mixin 并改回 Django 默认的 has_perm 校验。
    """

    def has_module_permission(self, request):
        u = request.user
        return bool(getattr(u, "is_active", False) and getattr(u, "is_staff", False))

    def has_view_permission(self, request, obj=None):
        u = request.user
        return bool(getattr(u, "is_active", False) and getattr(u, "is_staff", False))

    def has_change_permission(self, request, obj=None):
        u = request.user
        return bool(getattr(u, "is_active", False) and getattr(u, "is_staff", False))

    def has_add_permission(self, request):
        u = request.user
        return bool(getattr(u, "is_active", False) and getattr(u, "is_staff", False))

    def has_delete_permission(self, request, obj=None):
        u = request.user
        return bool(getattr(u, "is_active", False) and getattr(u, "is_staff", False))


class MemoryPhotoInline(admin.TabularInline):
    model = MemoryPhoto
    extra = 1
    fields = ("image", "sort_order")


@admin.register(Memory)
class MemoryAdmin(JournalStaffAccessMixin, admin.ModelAdmin):
    inlines = (MemoryPhotoInline,)
    list_display = (
        "event_title",
        "story_order",
        "date",
        "unique_feature_type",
        "nepal_art_style",
        "is_finale",
        "thumb_preview",
    )
    list_display_links = ("event_title",)
    list_filter = ("unique_feature_type", "nepal_art_style", "is_finale", "date")
    list_editable = ("story_order",)
    search_fields = ("event_title", "main_text")
    readonly_fields = ("image_preview",)
    ordering = ("story_order", "id")

    fieldsets = (
        (
            "叙事",
            {
                "fields": (
                    "story_order",
                    "date",
                    "event_title",
                    "is_finale",
                )
            },
        ),
        (
            "版式",
            {
                "fields": (
                    "unique_feature_type",
                    "nepal_art_style",
                    "image",
                    "image_preview",
                    "main_text",
                )
            },
        ),
    )

    @admin.display(description="缩略图")
    def thumb_preview(self, obj: Memory) -> str:
        url = None
        if obj.image:
            url = obj.image.url
        else:
            first = obj.photos.order_by("sort_order", "id").first()
            if first:
                url = first.image.url
        if not url:
            return "—"
        return format_html(
            '<img src="{}" style="max-height:48px;border-radius:4px;" />',
            url,
        )

    @admin.display(description="配图预览")
    def image_preview(self, obj: Memory) -> str:
        chunks: list[str] = []
        if obj.image:
            chunks.append(
                format_html(
                    '<div class="mb-2"><span style="font-size:11px;color:#666">主图</span><br>'
                    '<img src="{}" style="max-width:280px;border-radius:8px;" /></div>',
                    obj.image.url,
                )
            )
        for p in obj.photos.order_by("sort_order", "id"):
            chunks.append(
                format_html(
                    '<img src="{}" style="max-width:200px;border-radius:6px;margin:4px;" />',
                    p.image.url,
                )
            )
        if not chunks:
            return "—"
        return mark_safe("".join(str(c) for c in chunks))


@admin.register(Guestbook)
class GuestbookAdmin(JournalStaffAccessMixin, admin.ModelAdmin):
    list_display = ("nickname", "short_message", "created_at")
    search_fields = ("nickname", "message")
    readonly_fields = ("created_at",)

    @admin.display(description="留言")
    def short_message(self, obj: Guestbook) -> str:
        return obj.message[:80] + ("…" if len(obj.message) > 80 else "")


@admin.register(Config)
class ConfigAdmin(admin.ModelAdmin):
    """
    站点配置单独写权限：不继承 JournalStaffAccessMixin，避免 MRO/多重继承下
    has_change_permission 未按预期生效，导致 change 页全部为只读且 submit_row 不显示「保存」。
    """

    save_on_top = True

    list_display = (
        "site_title",
        "together_since",
        "unlock_at",
    )
    list_display_links = ("site_title",)
    fieldsets = (
        (
            "站点",
            {"fields": ("site_title",)},
        ),
        (
            "时间",
            {
                "fields": (
                    "together_since",
                    "unlock_at",
                ),
                "description": "「在一起」时间用于首页计数。unlock_at 已不使用，可留空。",
            },
        ),
    )

    def _staff_ok(self, request) -> bool:
        u = request.user
        return bool(
            getattr(u, "is_active", False)
            and getattr(u, "is_authenticated", False)
            and (getattr(u, "is_staff", False) or getattr(u, "is_superuser", False))
        )

    def has_module_permission(self, request):
        return self._staff_ok(request)

    def has_view_permission(self, request, obj=None):
        return self._staff_ok(request)

    def has_change_permission(self, request, obj=None):
        return self._staff_ok(request)

    def has_add_permission(self, request):
        if not self._staff_ok(request):
            return False
        return not Config.objects.exists()

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