from django.core.exceptions import ValidationError
from django.core.validators import MinLengthValidator, RegexValidator
from django.db import models
from django.utils.translation import gettext_lazy as _  # 添加导入

from .common import ConfigCommonModel


class UrlStyle(ConfigCommonModel):
    URL_FRONT_CHOICES = [
        ("model", _("模型路径")),
        ("slug", _("单级Slug")),
        ("random", _("随机字符")),
        ("custom", _("自定义路径")),
    ]

    IDENTIFIER_CHOICES = [("id", _("数字ID")), ("hash", _("哈希值"))]

    SUFFIX_CHOICES = [(".html", ".html"), (".htm", ".htm"), (".shtml", ".shtml"), ("", _("无后缀"))]

    url_front = models.CharField(
        verbose_name=_("路径方案"), max_length=20, choices=URL_FRONT_CHOICES, default="model"
    )

    url_mid = models.CharField(
        verbose_name=_("标识类型"),
        max_length=10,
        blank=True,
        choices=IDENTIFIER_CHOICES,
        default="id",
    )

    random_length = models.CharField(
        verbose_name=_("随机长度"),
        max_length=7,
        default="6-8",
        validators=[
            RegexValidator(r"^\d+-\d+$", _("格式：最小-最大（例6-8）")),
            MinLengthValidator(3),
        ],
        blank=True,
        help_text=_("随机字符串长度范围（示例：6-8 生成6到8位字符）"),
    )

    custom_slug = models.CharField(
        verbose_name=_("自定义路径段"),
        max_length=50,
        blank=True,
        validators=[RegexValidator(r"^[a-z0-9\-]+$", _("仅允许小写字母、数字和连字符"))],
    )

    custom_article = models.CharField(
        verbose_name=_("文章路径段"),
        max_length=50,
        blank=True,
        validators=[RegexValidator(r"^[a-z0-9\-]+$", _("仅允许小写字母、数字和连字符"))],
    )

    url_suffix = models.CharField(
        verbose_name=_("URL后缀"),
        max_length=10,
        blank=True,
        choices=SUFFIX_CHOICES,
        default=".html",
    )
    tag_identifier = models.CharField(
        verbose_name=_("Tag自定义标识"),
        max_length=50,
        blank=True,
        validators=[RegexValidator(r"^[a-z0-9\-]+$", _("仅允许小写字母、数字和连字符"))],
        help_text=_(
            "用于替换Tag URL中的默认'tag'路径段，留空则使用默认值。该设置不需要使用上面的自定义路径。"
        ),
    )

    def clean(self):
        """数据验证方法"""
        # 先保存当前实例的字段值
        current_values = {
            "url_front": self.url_front,
            "custom_slug": self.custom_slug,
            "custom_article": self.custom_article,
            "tag_identifier": self.tag_identifier,
            "random_length": self.random_length,
        }

        # 自定义路径必须填写所有字段
        super().clean()

        if self.url_front == "custom":
            if not self.custom_slug:
                raise ValidationError({"custom_slug": _("自定义路径段不能为空")})
            if not self.custom_article:
                raise ValidationError({"custom_article": _("文章路径段不能为空")})

        if self.tag_identifier and len(self.tag_identifier) < 2:
            raise ValidationError({"tag_identifier": _("自定义标识长度至少2个字符")})

        # 随机长度有效性验证
        if self.url_front == "random":
            if not self.random_length:
                raise ValidationError({"random_length": _("随机字符方案必须设置长度范围")})
            try:
                min_len, max_len = map(int, self.random_length.split("-"))
                if min_len > max_len or min_len < 4 or max_len > 12:
                    raise ValueError
            except ValueError:
                raise ValidationError({"random_length": _("长度范围需在4-12之间且最小≤最大")})

        # 安全获取数据库中的当前实例值
        current_instance_values = self._get_current_instance_values_safely(current_values)

        from apps.core.utils.restricted_term_manager import RestrictedTermManager

        # 验证 custom_slug 字段
        if self.custom_slug:
            RestrictedTermManager.validate_term_for_singleton(
                value=self.custom_slug,
                current_instance_value=current_instance_values.get("custom_slug"),
                field_name="custom_slug",
            )

        # 验证 custom_article 字段
        if self.custom_article:
            RestrictedTermManager.validate_term_for_singleton(
                value=self.custom_article,
                current_instance_value=current_instance_values.get("custom_article"),
                field_name="custom_article",
            )

        # 验证 tag_identifier 字段
        if self.tag_identifier:
            RestrictedTermManager.validate_term_for_singleton(
                value=self.tag_identifier,
                current_instance_value=current_instance_values.get("tag_identifier"),
                field_name="tag_identifier",
            )

    def _get_current_instance_values_safely(self, current_values):
        """
        安全获取数据库中的当前实例值，避免影响当前实例状态
        """
        if not self.pk:
            # 如果是新实例，返回空值
            return {field: None for field in current_values}

        try:
            # 使用 values() 方法只获取需要的字段，避免加载完整实例
            db_values = (
                UrlStyle.objects.filter(pk=self.pk)
                .values(
                    "url_front", "custom_slug", "custom_article", "tag_identifier", "random_length"
                )
                .first()
            )

            if db_values:
                return db_values
            else:
                return {field: None for field in current_values}

        except Exception:
            # 如果查询失败，返回保存的当前值（保守策略）
            return current_values

    class Meta:
        verbose_name = _("URL样式配置")
        verbose_name_plural = _("URL样式配置")
        db_table = "url_style"

    def __str__(self):
        return str(_("URL样式配置"))
