# 文章版本管理 Admin 界面

from django.contrib import admin
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from django.shortcuts import redirect, render
from django.contrib import messages
from django.template.response import TemplateResponse

from blog.models_version import ArticleVersion


@admin.register(ArticleVersion)
class ArticleVersionAdmin(admin.ModelAdmin):
    """文章版本管理界面"""

    list_display = [
        'version_number',
        'article_link',
        'title_display',
        'created_by',
        'creation_time',
        'change_summary_display',
        'is_auto_save',
        'action_buttons'
    ]

    list_filter = [
        'is_auto_save',
        'creation_time',
        'created_by'
    ]

    search_fields = [
        'title',
        'change_summary',
        'article__title'
    ]

    readonly_fields = [
        'article',
        'version_number',
        'title',
        'body',
        'pub_time',
        'status',
        'comment_status',
        'type',
        'category_id',
        'category_name',
        'created_by',
        'creation_time',
        'is_auto_save'
    ]

    fields = [
        'article',
        'version_number',
        'title',
        'body',
        'pub_time',
        'status',
        'comment_status',
        'type',
        'category_name',
        'created_by',
        'creation_time',
        'change_summary',
        'is_auto_save'
    ]

    list_per_page = 50

    def has_add_permission(self, request):
        """禁止手动添加版本"""
        return False

    def has_delete_permission(self, request, obj=None):
        """禁止删除版本（保持历史完整性）"""
        return False

    def article_link(self, obj):
        """文章链接"""
        url = reverse('admin:blog_article_change', args=[obj.article.id])
        return format_html('<a href="{}">{}</a>', url, obj.article.title)

    article_link.short_description = '文章'

    def title_display(self, obj):
        """显示标题（截断）"""
        if len(obj.title) > 50:
            return obj.title[:47] + '...'
        return obj.title

    title_display.short_description = '标题'

    def change_summary_display(self, obj):
        """显示变更说明"""
        if obj.change_summary:
            return obj.change_summary
        return format_html('<span style="color: #999;">自动保存</span>')

    change_summary_display.short_description = '变更说明'

    def action_buttons(self, obj):
        """操作按钮"""
        restore_url = reverse('admin:restore_article_version', args=[obj.id])
        compare_url = reverse('admin:compare_article_version', args=[obj.id])

        return format_html(
            '<a class="button" href="{}">恢复此版本</a> '
            '<a class="button" href="{}">对比</a>',
            restore_url,
            compare_url
        )

    action_buttons.short_description = '操作'

    def get_urls(self):
        """添加自定义URL"""
        from django.urls import path
        urls = super().get_urls()
        custom_urls = [
            path(
                '<int:version_id>/restore/',
                self.admin_site.admin_view(self.restore_version),
                name='restore_article_version',
            ),
            path(
                '<int:version_id>/compare/',
                self.admin_site.admin_view(self.compare_version),
                name='compare_article_version',
            ),
        ]
        return custom_urls + urls

    def restore_version(self, request, version_id):
        """恢复版本"""
        try:
            version = ArticleVersion.objects.get(id=version_id)
        except ArticleVersion.DoesNotExist:
            messages.error(request, '版本不存在')
            return redirect('admin:blog_articleversion_changelist')

        if request.method == 'POST':
            # 在恢复前先保存当前版本
            ArticleVersion.create_version(
                article=version.article,
                user=request.user,
                change_summary=f'恢复前的版本（准备恢复到 v{version.version_number}）',
                is_auto_save=False
            )

            if version.restore_to_article():
                messages.success(
                    request,
                    f'已成功将文章恢复到版本 v{version.version_number}'
                )
                return redirect('admin:blog_article_change', version.article.id)
            else:
                messages.error(request, '恢复版本失败')
                return redirect('admin:blog_articleversion_changelist')

        # 显示确认页面
        context = {
            **self.admin_site.each_context(request),
            'version': version,
            'current': version.article,
            'opts': self.model._meta,
            'title': f'恢复版本 v{version.version_number}',
        }
        return TemplateResponse(
            request,
            'admin/blog/articleversion/restore_confirmation.html',
            context
        )

    def compare_version(self, request, version_id):
        """对比版本"""
        try:
            version = ArticleVersion.objects.get(id=version_id)
        except ArticleVersion.DoesNotExist:
            messages.error(request, '版本不存在')
            return redirect('admin:blog_articleversion_changelist')

        current = version.article
        diff = version.get_diff_with_current()

        # 生成正文差异（如果有变化）
        body_diff_html = None
        if diff['body_changed']:
            import difflib
            d = difflib.HtmlDiff()
            body_diff_html = d.make_table(
                version.body.splitlines(),
                current.body.splitlines(),
                f'版本 v{version.version_number}',
                '当前版本',
                context=True,
                numlines=3
            )

        context = {
            **self.admin_site.each_context(request),
            'version': version,
            'current': current,
            'diff': diff,
            'body_diff_html': body_diff_html,
            'opts': self.model._meta,
            'title': f'对比版本 v{version.version_number}',
        }
        return TemplateResponse(
            request,
            'admin/blog/articleversion/compare.html',
            context
        )
