# apps/core/models/sitemap.py
import os

from apps.core.utils.get_models import autoload_user_apps
from django.apps import apps
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _  # 添加导入

from .common import ConfigCommonModel


class SitemapConfig(ConfigCommonModel):
    # 核心内容模型选择
    content_models = models.JSONField(
        verbose_name=_('内容模型'),  # 使用gettext_lazy翻译
        default=list,
        help_text=_('选择要包含的content应用模型'))

    # 用户空间应用模型选择
    user_app_models = models.JSONField(verbose_name=_("用户空间模型"),
                                       default=list,
                                       help_text=_('选择要包含的用户应用模型'))

    # 配置参数
    changefreq = models.CharField(verbose_name=_('更新频率'),
                                  max_length=20,
                                  default='daily',
                                  choices=[
                                      ('always', _('总是')),
                                      ('hourly', _('每小时')),
                                      ('daily', _('每天')),
                                      ('weekly', _('每周')),
                                      ('monthly', _('每月')),
                                      ('yearly', _('每年')),
                                      ('never', _('从不')),
                                  ])
    priority = models.DecimalField(verbose_name=_('优先级'),
                                   max_digits=3,
                                   decimal_places=1,
                                   default=0.5,
                                   help_text=_('0.0 到 1.0 之间的值'))
    paginate_by = models.PositiveIntegerField(
        verbose_name=_('每页数量'),
        default=500,
        help_text=_('每个sitemap文件包含的最大URL数'))
    enable_index = models.BooleanField(verbose_name=_('启用索引模式'),
                                       default=True,
                                       help_text=_('生成分块站点地图索引'))
    protocol = models.CharField(
        verbose_name=_('URL协议'),
        max_length=5, # 'https' 或 'http'
        default='https',
        choices=[
            ('https', 'HTTPS'),
            ('http', 'HTTP'),
        ],
        help_text=_('生成站点地图URL时使用的协议。')
    )

    class Meta:
        verbose_name = _('站点地图配置')
        verbose_name_plural = _('站点地图配置')

    def __str__(self):
        return str(_("站点地图配置"))  # 使用str()确保返回字符串类型

    def save(self, *args, **kwargs):
        # 检查是否是新建对象且content_models字段为空列表
        if self.pk is None and self.content_models == []:
            self.content_models = [
                "content.article", "content.tag", "content.category"
            ]
        super().save(*args, **kwargs)

    def clean(self):
        """验证数据格式"""
        # 验证模型选择格式
        for field in ['content_models', 'user_app_models']:
            value = getattr(self, field)
            if not isinstance(value, list):
                raise ValidationError({field: _('必须为数组格式')})
            if any(not isinstance(item, str) for item in value):
                raise ValidationError({field: _('包含非字符串元素')})

    @staticmethod
    def get_content_models_choices():
        """获取content应用的可用模型选项"""
        from django.apps import apps
        try:
            app_config = apps.get_app_config('content')
            return [(f"{model._meta.app_label}.{model._meta.model_name}",
                     model._meta.verbose_name)
                    for model in app_config.get_models()]
        except LookupError:
            return []

    @staticmethod
    def get_user_space_choices():
        """获取用户空间应用的可用模型选项"""
        from django.apps import apps
        models = []
        for app_name in autoload_user_apps():
            try:
                app_config = apps.get_app_config(app_name.split('.')[-1])
                models.extend([
                    (f"{model._meta.app_label}.{model._meta.model_name}",
                     f"{app_config.verbose_name} - {model._meta.verbose_name}")
                    for model in app_config.get_models()
                ])
            except (LookupError, ImportError):
                continue
        return models

    def get_active_models(self):
        """
        获取合并后的模型列表
        返回: 包含所有选中模型类的列表
        """
        combined = []

        # 合并两个字段的模型标识
        all_models = self.content_models + self.user_app_models

        # 去重处理
        seen = set()
        unique_models = [
            x for x in all_models if not (x in seen or seen.add(x))
        ]

        # 转换为模型类
        for model_str in unique_models:
            try:
                app_label, model_name = model_str.split('.')
                model_class = apps.get_model(app_label, model_name)
                combined.append(model_class)
            except (ValueError, LookupError, AttributeError) as e:
                # 处理无效模型标识
                print(f"无效的模型标识 {model_str}: {str(e)}")
                continue

        return combined


# def autoload_user_apps():
#     """基于 settings.BASE_DIR 自动扫描用户应用"""
#     user_apps = []
#     base_dir = os.path.join(settings.BASE_DIR, "user_space")
#     apps_dir = os.path.join(base_dir, "apps")
#     os.makedirs(apps_dir, mode=0o755, exist_ok=True)
#
#     if not os.access(apps_dir, os.W_OK):
#         raise PermissionError(f"目录 {apps_dir} 不可写，请检查权限！")
#     print('os.listdir(apps_dir)=>', os.listdir(apps_dir))
#     for app_name in os.listdir(apps_dir):
#         app_path = os.path.join(apps_dir, app_name)
#         if (os.path.isdir(app_path)
#                 and os.path.exists(os.path.join(app_path, "__init__.py"))
#                 and os.path.exists(os.path.join(app_path, "apps.py"))):
#             user_apps.append(f"user_space.apps.{app_name}")
#     print(user_apps)
#     return user_apps
