import random

from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils.safestring import mark_safe

from .common import ConfigCommonModel


class TagPageConfig(ConfigCommonModel):
    """
    标签页面配置模型
    控制标签页面的标题多样性、简介多样性等设置
    """

    # 标题多样性开关
    title_diversity_enabled = models.BooleanField(
        verbose_name="标题多样性开关",
        default=False,
        help_text="开启后，标签页面标题将使用多样性模板",
    )

    # 标题多样性模板
    title_templates = models.TextField(
        verbose_name="标题多样性模板",
        default="""{标签名称}：全面解读
{标签名称}是什么意思
{标签名称}指南：从入门到精通
详解{标签名称}的含义
什么是{标签名称}
一文读懂{标签名称}的相关知识
{标签名称}全解析
{标签名称}的完整指南
探索{标签名称}的奥秘
{标签名称}入门教程
{标签名称}深度分析""",
        help_text="每行一个标题模板，支持{标签名称}占位符",
    )

    # 拼接模板配置
    title_connector_templates = models.TextField(
        verbose_name="拼接模板配置",
        default="""{标题1}？{标题2}
{标题1}VS{标题2}
{标题1}--{标题2}
{标题1}（{标题2}）
{标题1}，{标题2}
{标题1}：{标题2}
{标题1}｜{标题2}
{标题1}→{标题2}
{标题1}·{标题2}
{标题1}——{标题2}
{标题1}？答案在这里：{标题2}
{标题1}与{标题2}的完美结合
关于{标题1}的深度探讨：{标题2}
{标题1}：揭秘{标题2}
{标题1} vs {标题2}：全面对比
{标题1}？不如看看{标题2}
{标题1}和{标题2}的关联解析
{标题1}？这里告诉你{标题2}
{标题1} → {标题2}：完整指南
{标题1}（内含：{标题2}）
{标题1}？{标题2}给你答案""",
        help_text="每行一个拼接模板，支持{标题1}和{标题2}占位符，系统随机选择",
    )

    # 分词策略开关
    word_split_enabled = models.BooleanField(
        verbose_name="分词策略开关",
        default=True,
        help_text=mark_safe(
            """<div class="alert alert-info">
            <strong>标签没有相关内容时，将标签title分词后全文搜索相关文章</strong>
                <p>之前我们是将标签title分词，然后使用分词去全表like文章title,效率比较低，比较耗时，比较吃资源</p>      
                <p>在你看到这个功能的时候，我们就开始加入中间表策略，文章title分词关联中间表，标签title分词关联中间表，这样我们再以后在标签内容页当中分词查找文章的时候，就可以直接通过中间表索引快速找到使用的文章。性能将升一个量级。</p>    
                <p>这种新的分词找文章的策略正处于过度测试阶段，须前后兼顾，如遇什么不适可以及时提出。</p>                 
                </div>"""
        ),
    )
    concurrent_update_enabled = models.BooleanField(
        verbose_name="启用并发更新",
        default=False,  # 默认关闭以确保安全
        help_text=mark_safe(
            """<div class="alert alert-info">
                <p>开启后，访问内容页，发现没有分词过，我们则需要进行title的分词操作。当进行分词更新时，将使用多线程/进程处理以堵塞http主进程，（仅在'分词策略开关'开启时有效）。<br>标签分词采用的是之前的逻辑和现在有的逻辑的结合，智能使用相关的分词逻辑，为保证相关文章列表的查找结果并不会使用并发更新分词情况<br>目前只作用于已经入库的文章被首次打开的时候。打开并发更新后，pid进程数会偶尔增加。执行操作后会自行关闭，不必担心。<br>即使不打开并发，只有每个项目主线程首次打开的时候会慢一点，其他时候分词仅影响0.1-0.3秒，甚至更少的时间。<br>分词只执行1次，不会出现多次分词的情况</p>                      
                </div>"""
        ),
    )

    # 补空策略设置
    fill_empty_strategy = models.CharField(
        verbose_name="补空策略",
        max_length=20,
        choices=[("random", "随机文章"), ("recent", "近期文章"), ("none", "不补充")],
        default="recent",
        help_text="分词后没有找到相关内容时的补充策略",
    )

    # 补空文章数量
    fill_empty_count = models.IntegerField(
        verbose_name="补空文章数量",
        default=20,
        validators=[MinValueValidator(1), MaxValueValidator(50)],
        help_text="随机或近期文章的数量",
    )

    # 标签简介多样性开关
    intro_diversity_enabled = models.BooleanField(
        verbose_name="简介多样性开关", default=False, help_text="开启后，标签简介将使用多样性模板"
    )

    # 简介多样性模板（使用占位符代替直接变量）
    intro_templates = models.TextField(
        verbose_name="简介多样性模板",
        default="""<div class="alert alert-success" role="alert">
    <h2 class="alert-heading fs-5">“{标签名称}”简介</h2>
    <p>{网站名称}通过对网友关注问题进行分析，发现很多朋友想了解一些有关“<strong class="text-danger">{标签名称}</strong>”的内容，我们为大家找到了以下内容，希望可以解决您的疑惑。</p>
    <p class="mb-0 text-end">——{网站名称}站长敬上</p>
    <hr>
</div>

<div class="alert alert-info" role="alert">
    <p>关于“{标签名称}”的疑问，{网站名称}为您整理了全面的资料。无论是基本概念还是深入解析，这里都有您需要的信息。</p>
</div>

<div class="alert alert-warning" role="alert">
    <p>您是否在寻找“{标签名称}”的相关信息？{网站名称}汇集了众多优质内容，帮助您快速理解这一主题。</p>
</div>

<div class="alert alert-light" role="alert">
    <h3 class="alert-heading fs-5">快速了解“{标签名称}”</h3>
    <p class="mb-0">本页面旨在为您提供关于“{标签名称}”的核心信息和详细解读，让您能快速抓住重点。</p>
</div>

<div class="alert alert-secondary" role="alert">
    <p>在{网站名称}，我们注意到“<strong>{标签名称}</strong>”是许多用户关注的热点。为此，我们专门汇总了相关信息，希望能成为您了解此话题的得力助手。</p>
</div>

<div class="alert alert-success" role="alert">
    <p>您对“{标签名称}”感到好奇吗？您来对地方了！{网站名称}致力于将复杂的概念变得通俗易懂，本文将带您一步步揭开“{标签名称}”的神秘面纱。</p>
</div>

<div class="alert alert-primary" role="alert">
    <h4 class="alert-heading fs-5">为什么选择我们来了解“{标签名称}”？</h4>
    <p class="mb-0">因为{网站名称}提供由大家共同关注的问题所提炼出的高质量内容，直击要害，避免信息过载。</p>
</div>

<div class="alert alert-dark" role="alert">
    <p>探索“{标签名称}”的世界：无论您是初次接触还是希望深化理解，{网站名称}准备的资料都能满足您的需求，引导您发现更多。</p>
</div>

<div class="alert alert-info" role="alert">
    <p>“<strong>{标签名称}</strong>”可能涉及多个方面，这很正常。{网站名称}的任务就是为您梳理脉络，呈现清晰的全貌，节省您宝贵的时间。</p>
</div>

<div class="alert alert-warning" role="alert">
    <p>鉴于近期用户对“{标签名称}”的搜索量显著上升，{网站名称}特此提供本专题页面，以便您集中获取有效信息。</p>
</div>""",
        help_text="支持HTML标签，每段用空行分隔，支持{标签名称}和{网站名称}占位符",
    )

    # 默认简介模板（使用占位符代替直接变量）
    default_intro_template = models.TextField(
        verbose_name="默认简介模板",
        default="""<div class="alert alert-success" role="alert">
    <h2 class="alert-heading fs-5">"{标签名称}"简介</h2>
    <p>{网站名称}通过对网友关注问题进行分析，发现很多朋友想了解一些有关"<strong class="text-danger">{标签名称}</strong>"的内容，我们为大家找到了以下内容，希望可以解决您的疑惑</p>
    <p class="mb-0 text-end">——{网站名称}站长敬上</p>
    <hr>
</div>""",
        help_text="当简介多样性关闭时使用的默认模板，支持{标签名称}和{网站名称}占位符",
    )

    class Meta:
        verbose_name = "标签页面配置"
        verbose_name_plural = verbose_name

    def __str__(self):
        return f"标签页面配置"

    def get_title_templates_list(self):
        """获取标题模板列表"""
        return [line.strip() for line in self.title_templates.split("\n") if line.strip()]

    def get_connector_templates_list(self):
        """获取拼接模板列表"""
        templates = [
            line.strip() for line in self.title_connector_templates.split("\n") if line.strip()
        ]
        # 容灾处理：如果配置为空，使用默认拼接模板
        if not templates:
            return ["{标题1}，{标题2}"]
        return templates

    def get_intro_templates_list(self):
        """获取简介模板列表（按空行分割）"""
        templates = []
        current_template = []

        for line in self.intro_templates.split("\n"):
            if line.strip() == "" and current_template:
                templates.append("\n".join(current_template))
                current_template = []
            else:
                current_template.append(line)

        if current_template:
            templates.append("\n".join(current_template))

        return templates

    def _replace_placeholders(self, text, tag_title):
        """替换模板中的占位符"""
        from apps.core.models import SiteSettings

        site_name = SiteSettings.get_solo().site_name
        return text.replace("{标签名称}", tag_title).replace("{网站名称}", site_name)

    def _replace_title_placeholders(self, text, title1, title2):
        """替换标题拼接模板中的占位符"""
        return text.replace("{标题1}", title1).replace("{标题2}", title2)

    def generate_diverse_title(self, tag_title):
        """
        生成多样性标题 - 拼接模板版
        只替换原标题中的「{标签名称}相关内容介绍、详解，{标签名称}是什么意思」部分
        """
        if not self.title_diversity_enabled:
            # 使用原始标题格式（只返回核心部分，不包含pagenum）
            return ""
        title_templates = self.get_title_templates_list()
        connector_templates = self.get_connector_templates_list()

        if len(title_templates) < 2:
            # 如果模板不足，使用默认行为
            print(
                "标签页面配置中标题模板过少，不可以进行拼接，请至少保持2条以上模板，模板越多拼接的模板样式越多"
            )
            return ""

        # 随机选择两个不同的标题模板
        selected_templates = random.sample(title_templates, 2)

        # 替换占位符生成实际标题
        title1 = self._replace_placeholders(selected_templates[0], tag_title)
        title2 = self._replace_placeholders(selected_templates[1], tag_title)

        # 随机选择一个拼接模板
        connector_template = random.choice(connector_templates)

        # 使用拼接模板生成最终标题
        final_title = self._replace_title_placeholders(connector_template, title1, title2)

        return final_title

    def get_complete_title(self, tag_title):
        """
        生成完整的页面标题（包含分页信息）
        用于模板中的 {% block title %} 标签
        """
        if not self.title_diversity_enabled:
            # 如果多样性关闭，返回''，由调用方决定默认行为
            return ""

        try:
            # 生成多样性标题核心部分
            core_title = self.generate_diverse_title(tag_title)
            if core_title:

                return core_title
            return ""
        except Exception as e:
            # 记录日志
            print(f"生成多样性标题时出错: {e}")
            return ""

    def generate_diverse_intro(self, tag_title, obj_intro=None):
        """
        生成多样性简介（使用占位符系统）
        """
        if not self.intro_diversity_enabled:
            return ""
        try:
            if obj_intro:
                # 如果有自定义简介，直接返回
                return obj_intro

            templates = self.get_intro_templates_list()
            if not templates:
                # 如果没有模板，使用默认
                return self._replace_placeholders(self.default_intro_template, tag_title)

            # 随机选择一个模板并替换占位符
            selected_template = random.choice(templates)
            return self._replace_placeholders(selected_template, tag_title)
        except Exception as e:
            print(f"生成多样性简介时出错: {e}")
            return ""
