from django.contrib.sitemaps import Sitemap
from django.urls import reverse

from blog.models import Article, Category, Tag


class StaticViewSitemap(Sitemap):
    """
    静态页面的站点地图（Sitemap）类。
    用于为网站的固定页面（如首页）生成 sitemap 条目。
    """

    # 默认优先级：0.5（表示普通重要性）
    priority = 0.5
    # 默认更新频率：每天
    changefreq = 'daily'

    def items(self):
        """
        定义需要包含在 sitemap 中的静态视图名称列表。

        返回:
            list: 包含 Django URL 命名的列表，此处仅包含首页 'blog:index'
        """
        return ['blog:index', ]

    def location(self, item):
        """
        根据 items() 返回的 URL 名称，生成对应的绝对路径。

        参数:
            item (str): URL 命名，如 'blog:index'

        返回:
            str: 反向解析后的 URL 路径（如 '/'）
        """
        return reverse(item)


class ArticleSiteMap(Sitemap):
    """
    文章（Article）模型的站点地图类。
    为所有已发布的文章生成 sitemap 条目。
    """

    # 更新频率：每月
    changefreq = "monthly"
    # 优先级：0.6（相对重要）
    priority = "0.6"

    def items(self):
        """
        获取所有已发布（status='p'）的文章对象。

        返回:
            QuerySet: 所有已发布文章的查询集
        """
        return Article.objects.filter(status='p')

    def lastmod(self, obj):
        """
        获取每篇文章的最后修改时间，用于搜索引擎判断内容更新。

        参数:
            obj (Article): 文章实例

        返回:
            datetime: 文章的 last_modify_time 字段值
        """
        return obj.last_modify_time


class CategorySiteMap(Sitemap):
    """
    分类（Category）模型的站点地图类。
    为所有文章分类生成 sitemap 条目。
    """

    # 更新频率：每周（注意：此处拼写应为 'weekly' 小写）
    changefreq = "Weekly"
    # 优先级：0.6
    priority = "0.6"

    def items(self):
        """
        获取所有分类对象。

        返回:
            QuerySet: 所有分类的查询集
        """
        return Category.objects.all()

    def lastmod(self, obj):
        """
        获取每个分类的最后修改时间。

        参数:
            obj (Category): 分类实例

        返回:
            datetime: 分类的 last_modify_time 字段值
        """
        return obj.last_modify_time


class TagSiteMap(Sitemap):
    """
    标签（Tag）模型的站点地图类。
    为所有标签生成 sitemap 条目。
    """

    # 更新频率：每周
    changefreq = "Weekly"
    # 优先级：0.3（相对较低）
    priority = "0.3"

    def items(self):
        """
        获取所有标签对象。

        返回:
            QuerySet: 所有标签的查询集
        """
        return Tag.objects.all()

    def lastmod(self, obj):
        """
        获取每个标签的最后修改时间。

        参数:
            obj (Tag): 标签实例

        返回:
            datetime: 标签的 last_modify_time 字段值
        """
        return obj.last_modify_time


class UserSiteMap(Sitemap):
    """
    用户（作者）的站点地图类。
    为所有发布过文章的作者生成 sitemap 条目。
    """

    # 更新频率：每周
    changefreq = "Weekly"
    # 优先级：0.3
    priority = "0.3"

    def items(self):
        """
        获取所有发布过文章的作者（去重）。

        实现方式：
        1. 查询所有文章
        2. 提取每篇文章的作者（author 字段）
        3. 使用 set 去重
        4. 转换为列表返回

        注意：此方法效率较低，尤其在文章量大时，建议优化为：
             return User.objects.filter(article__status='p').distinct()

        返回:
            list: 去重后的用户（作者）对象列表
        """
        return list(set(map(lambda x: x.author, Article.objects.all())))

    def lastmod(self, obj):
        """
        获取每个用户的最后修改时间。

        此处使用的是用户的注册时间（date_joined），而非内容更新时间。
        对于作者而言，更合理的 lastmod 可能是其发布的最后一篇文章的时间。

        参数:
            obj (User): 用户实例

        返回:
            datetime: 用户的 date_joined 字段值（注册时间）
        """
        return obj.date_joined