# 文章草稿自动保存模型
# 用于在编辑文章时自动保存草稿，防止内容丢失

from django.conf import settings
from django.db import models
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _

from blog.models import Article, Category


class ArticleDraft(models.Model):
    """
    文章草稿模型
    用于自动保存编辑中的文章，防止内容丢失
    """
    # 关联的文章（可为空，表示新建文章的草稿）
    article = models.ForeignKey(
        Article,
        verbose_name='文章',
        on_delete=models.CASCADE,
        related_name='drafts',
        null=True,
        blank=True
    )

    # 草稿创建者
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        verbose_name='作者',
        on_delete=models.CASCADE,
        related_name='article_drafts'
    )

    # 草稿标题
    title = models.CharField('标题', max_length=200, blank=True, default='')

    # 草稿正文
    body = models.TextField('正文', blank=True, default='')

    # 分类ID（保存时的分类）
    category_id = models.IntegerField('分类ID', null=True, blank=True)

    # 标签（JSON 格式保存标签ID列表）
    tags_data = models.JSONField('标签数据', default=list, blank=True)

    # 状态
    status = models.CharField('状态', max_length=1, default='d')

    # 评论状态
    comment_status = models.CharField('评论状态', max_length=1, default='o')

    # 类型
    type = models.CharField('类型', max_length=1, default='a')

    # 创建时间
    creation_time = models.DateTimeField('创建时间', default=now, db_index=True)

    # 最后更新时间
    last_update_time = models.DateTimeField('最后更新时间', auto_now=True, db_index=True)

    # 草稿会话ID（用于区分不同的编辑会话）
    session_id = models.CharField('会话ID', max_length=64, blank=True, default='')

    # 是否已发布（草稿应用到文章后标记为已发布）
    is_published = models.BooleanField('已发布', default=False)

    class Meta:
        ordering = ['-last_update_time']
        verbose_name = '文章草稿'
        verbose_name_plural = '文章草稿'
        indexes = [
            models.Index(fields=['author', '-last_update_time'], name='draft_author_time_idx'),
            models.Index(fields=['article', '-last_update_time'], name='draft_article_time_idx'),
            models.Index(fields=['is_published', '-last_update_time'], name='draft_published_time_idx'),
        ]

    def __str__(self):
        title = self.title or '(无标题)'
        return f"{title} - {self.author.username} - {self.last_update_time.strftime('%Y-%m-%d %H:%M')}"

    @classmethod
    def save_draft(cls, user, title='', body='', article_id=None, category_id=None,
                   tags_data=None, status='d', comment_status='o', type='a', session_id=''):
        """
        保存或更新草稿

        Args:
            user: 用户对象
            title: 文章标题
            body: 文章正文
            article_id: 文章ID（如果是编辑现有文章）
            category_id: 分类ID
            tags_data: 标签数据列表
            status: 文章状态
            comment_status: 评论状态
            type: 文章类型
            session_id: 会话ID

        Returns:
            ArticleDraft 实例
        """
        if tags_data is None:
            tags_data = []

        # 查找是否存在相同会话的草稿
        if session_id:
            draft = cls.objects.filter(
                author=user,
                session_id=session_id,
                is_published=False
            ).first()
        elif article_id:
            # 如果是编辑现有文章，查找该文章的最新未发布草稿
            draft = cls.objects.filter(
                author=user,
                article_id=article_id,
                is_published=False
            ).first()
        else:
            # 新建文章，查找最新的未关联文章的草稿
            draft = cls.objects.filter(
                author=user,
                article__isnull=True,
                is_published=False
            ).first()

        # 更新或创建草稿
        if draft:
            draft.title = title
            draft.body = body
            draft.category_id = category_id
            draft.tags_data = tags_data
            draft.status = status
            draft.comment_status = comment_status
            draft.type = type
            if session_id:
                draft.session_id = session_id
            draft.save()
        else:
            article = None
            if article_id:
                try:
                    article = Article.objects.get(id=article_id)
                except Article.DoesNotExist:
                    pass

            draft = cls.objects.create(
                author=user,
                article=article,
                title=title,
                body=body,
                category_id=category_id,
                tags_data=tags_data,
                status=status,
                comment_status=comment_status,
                type=type,
                session_id=session_id
            )

        return draft

    def apply_to_article(self, article=None):
        """
        将草稿应用到文章

        Args:
            article: Article 实例（如果为空则使用关联的文章）

        Returns:
            Article 实例
        """
        if article is None:
            article = self.article

        if article is None:
            # 创建新文章
            from blog.models import Category
            category = None
            if self.category_id:
                try:
                    category = Category.objects.get(id=self.category_id)
                except Category.DoesNotExist:
                    # 如果分类不存在，使用第一个分类
                    category = Category.objects.first()

            if category is None:
                raise ValueError("必须指定文章分类")

            article = Article.objects.create(
                title=self.title,
                body=self.body,
                author=self.author,
                category=category,
                status=self.status,
                comment_status=self.comment_status,
                type=self.type
            )
        else:
            # 更新现有文章
            article.title = self.title
            article.body = self.body
            if self.category_id:
                try:
                    from blog.models import Category
                    category = Category.objects.get(id=self.category_id)
                    article.category = category
                except Category.DoesNotExist:
                    pass
            article.status = self.status
            article.comment_status = self.comment_status
            article.type = self.type
            article.save()

        # 应用标签
        if self.tags_data:
            from blog.models import Tag
            tags = Tag.objects.filter(id__in=self.tags_data)
            article.tags.set(tags)

        # 标记草稿为已发布
        self.is_published = True
        self.article = article
        self.save()

        return article

    def get_preview_text(self, length=100):
        """
        获取草稿预览文本

        Args:
            length: 预览文本长度

        Returns:
            str: 预览文本
        """
        if self.body:
            if len(self.body) > length:
                return self.body[:length] + '...'
            return self.body
        return '(空草稿)'
