import re
from django.db import models
from jsonschema import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator


class AdDeliveryRule(models.Model):
    """ 广告投放策略规则配置 """
    DEVICE_CHOICES = (('pc', '电脑端'), ('mobile', '移动端'), ('all', '全平台'))

    advertisement = models.ForeignKey('Advertisement',
                                      on_delete=models.CASCADE,
                                      related_name='delivery_rules',
                                      help_text="关联的广告主体内容")

    time_ranges = models.JSONField('投放时段',
                                   default=list,
                                   help_text="""指定广告展示时间段规则，格式为包含时间区间的列表：
        - 使用24小时制时间格式
        - 示例：["09:00-12:00", "14:00-18:00"]表示上午9点到12点和下午2点到6点投放
        - 空列表表示全天候投放""")

    devices = models.CharField('设备限制',
                               max_length=20,
                               choices=DEVICE_CHOICES,
                               default='all',
                               help_text="""限制广告展示的设备类型：
        - 电脑端：仅在PC浏览器展示
        - 移动端：仅在手机/平板设备展示
        - 全平台：不限制设备类型""")

    regions = models.TextField('地区限制',
                               null=True,
                               blank=True,
                               help_text="""指定允许展示的地区代码（逗号分隔）：
        - 使用国家标准地区编码（如CN-110000表示北京）
        - 支持ISO国家代码（如CN,US）
        - 示例：CN-110000,CN-310000 表示仅在北京和上海展示
        - 留空表示不限制地区""")

    display_weight = models.FloatField(
        '展示权重',
        default=1.0,
        validators=[MinValueValidator(0.1),
                    MaxValueValidator(10.0)],
        help_text="""控制广告展示概率的相对权重（0.1-10.0）：
        - 权重值越大展示概率越高
        - 示例：当两个广告权重分别为2.0和1.0时，前者展示概率是后者的两倍
        - 系统会自动进行归一化计算""")

    class Meta:
        verbose_name = '广告投放规则'
        verbose_name_plural = verbose_name
        ordering = ['-display_weight']

    def clean(self):
        if not isinstance(self.time_ranges, list):
            raise ValidationError("时间区间必须为列表格式")
        for tr in self.time_ranges:
            if not re.match(r'^\d{2}:\d{2}-\d{2}:\d{2}$', tr):
                raise ValidationError("时间格式应为HH:MM-HH:MM")

    def __str__(self):
        return f"{self.advertisement.title} 投放规则"
