from django.db import models
from django.core.exceptions import ValidationError
from .common import ConfigCommonModel
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from apps.core.utils.get_models import autoload_user_apps


class SearchConfig(ConfigCommonModel):
    # 添加choices选项的翻译
    STATIC_CHOICES = [
        (True, _('是')),
        (False, _('否')),
    ]

    content_models = models.JSONField(verbose_name=_('内容模型'),
                                      default=list,
                                      help_text=mark_safe(
                                          _('选择要包含的content应用模型')))

    content_fields = models.JSONField(verbose_name=_('可搜索字段'),
                                      default=list,
                                      help_text=mark_safe(
                                          _('''可多选的字段列表，格式示例：<br>
        ["title", "content", "meta_description"]''')))

    user_space_search = models.JSONField(verbose_name=_('自定义模型'),
                                         default=dict,
                                         blank=True,
                                         help_text=mark_safe(
                                             _('''格式示例:<br>
        {<br>
        &nbsp;&nbsp;"app.model1": "field1,field2",<br>
        &nbsp;&nbsp;"app.model2": "field3"<br>
        }<br><br>
        可用模型:<br>
        ''')))

    update_switch = models.BooleanField(default=False,
                                        verbose_name=_("是否保存搜索数据"),
                                        choices=STATIC_CHOICES,
                                        help_text=_("启用后将记录搜索历史到SearchData模型"))

    search_engine = models.BooleanField(
        default=False,
        verbose_name=_("搜索引擎式拆词"),
        choices=STATIC_CHOICES,
        help_text=_("可模仿搜索引擎式拆词。我们会以空格拆词、提取引号内容等方法取词搜索。"))

    class Meta:
        verbose_name = _('搜索中心配置')
        verbose_name_plural = _('搜索中心配置')

    def __str__(self):
        return str(_('搜索中心配置'))

    @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()
                    if model._meta.model_name not in
                    ['tag', 'category', 'searchhistory', 'contentmanager']]
        except LookupError:
            return []

    @staticmethod
    def get_available_fields():
        """获取所有模型可用的标准字段"""
        standard_fields = [('title', _('标题')), ('content', _('内容')),
                           ('meta_description', _('简介'))]
        return standard_fields

    @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 clean(self):
        super().clean()
        if len(self.content_models) < 1:
            raise ValidationError({'content_models': _("必须至少选择1个内容模型")})

    def save(self, *args, **kwargs):
        if self.user_space_search == '':
            self.user_space_search = {}
        if self.pk is None:
            if self.content_models == []:
                self.content_models = [
                    "content.article", "content.tag", "content.category"
                ]
            if self.content_fields == []:
                self.content_fields = [
                    "title",
                ]
        return super().save(*args, **kwargs)
