"""djangoblog URL Configuration

主 URL 配置文件，定义了整个网站的 URL 路由规则。
将不同的 URL 模式映射到对应的视图函数或类，实现请求分发。
"""

# 导入必要的模块
from django.conf import settings
from django.conf.urls.i18n import i18n_patterns  # 支持国际化 URL 模式
from django.conf.urls.static import static  # 用于在开发环境提供静态和媒体文件服务
from django.contrib.sitemaps.views import sitemap  # 生成站点地图（sitemap.xml）的视图
from django.urls import path, include  # 标准 URL 映射工具
from django.urls import re_path  # 支持正则表达式匹配的 URL 映射
from haystack.views import search_view_factory  # Haystack 搜索框架的视图工厂

# 导入项目内自定义组件
from blog.views import EsSearchView  # 自定义的 Elasticsearch 搜索视图
from djangoblog.admin_site import admin_site  # 自定义的 Django 管理后台实例
from djangoblog.elasticsearch_backend import ElasticSearchModelSearchForm  # 搜索表单类
from djangoblog.feeds import DjangoBlogFeed  # RSS 订阅源
from djangoblog.sitemap import ArticleSiteMap, CategorySiteMap, StaticViewSitemap, TagSiteMap, UserSiteMap  # 站点地图类


# 定义站点地图（sitemap）的映射字典
# 将不同的 sitemap 类按类别注册，用于生成 sitemap.xml
sitemaps = {
    'blog': ArticleSiteMap,        # 文章内容地图
    'Category': CategorySiteMap,   # 分类地图
    'Tag': TagSiteMap,             # 标签地图
    'User': UserSiteMap,           # 用户（作者）地图
    'static': StaticViewSitemap    # 静态页面地图（如首页）
}

# 自定义错误页面处理视图
# 当发生相应错误时，Django 会调用这些视图函数来渲染错误页面
handler404 = 'blog.views.page_not_found_view'      # 404 页面未找到
handler500 = 'blog.views.server_error_view'        # 500 服务器内部错误
handle403 = 'blog.views.permission_denied_view'    # 403 权限拒绝（注意：变量名应为 handler403 才生效）

# 主 URL 模式列表
urlpatterns = [
    # 提供 Django 内置的国际化（i18n）URL 支持，如 /i18n/setlang/ 用于切换语言
    path('i18n/', include('django.conf.urls.i18n')),
]

# 使用 i18n_patterns 包裹一组 URL，使其支持多语言前缀（如 /en/, /zh-hans/）
# prefix_default_language=False 表示默认语言不添加前缀
urlpatterns += i18n_patterns(
    # 管理后台 URL，访问路径为 /admin/
    re_path(r'^admin/', admin_site.urls),

    # 博客应用主 URL，包含 blog 应用的所有路由，命名空间为 'blog'
    # 注意：空正则 r'' 会匹配根路径，但由于在 i18n_patterns 内，实际路径为 /<lang>/ 或 /（默认语言）
    re_path(r'', include('blog.urls', namespace='blog')),

    # Markdown 编辑器（mdeditor）的资源和上传路由
    re_path(r'mdeditor/', include('mdeditor.urls')),

    # 评论系统路由，命名空间为 'comment'
    re_path(r'', include('comments.urls', namespace='comment')),

    # 用户账户系统路由（注册、登录、个人中心等），命名空间为 'account'
    re_path(r'', include('accounts.urls', namespace='account')),

    # 第三方登录（OAuth）路由，命名空间为 'oauth'
    re_path(r'', include('oauth.urls', namespace='oauth')),

    # 站点地图路由：访问 /sitemap.xml 时，调用 sitemap 视图并传入 sitemaps 字典
    re_path(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
            name='django.contrib.sitemaps.views.sitemap'),

    # RSS 订阅源路由：访问 /feed/ 或 /rss/ 时，返回 DjangoBlogFeed 生成的 RSS 内容
    re_path(r'^feed/$', DjangoBlogFeed()),
    re_path(r'^rss/$', DjangoBlogFeed()),

    # 搜索功能路由：使用 Haystack 的视图工厂创建基于 Elasticsearch 的搜索视图
    # 搜索表单使用自定义的 ElasticSearchModelSearchForm
    # 访问路径如 /search?q=关键词
    re_path('^search', search_view_factory(view_class=EsSearchView, form_class=ElasticSearchModelSearchForm),
            name='search'),

    # 服务器管理模块路由（可能用于系统监控或运维），命名空间为 'servermanager'
    re_path(r'', include('servermanager.urls', namespace='servermanager')),

    # OwnTracks 路由（可能用于位置追踪服务），命名空间为 'owntracks'
    re_path(r'', include('owntracks.urls', namespace='owntracks'))
    , prefix_default_language=False)  # i18n_patterns 的结束和参数

# 为静态文件 URL 添加处理规则
# 在开发模式下（DEBUG=True），Django 自动提供 STATIC_URL 和 MEDIA_URL 的文件服务
# static() 会将 URL 前缀映射到指定的文件系统路径
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

# 如果处于调试模式，额外添加媒体文件（如用户上传的图片）的 URL 映射
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)