from django.db import models
from apps.system.models import User
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver

class Category(models.Model):
    name = models.CharField(max_length=50, verbose_name="分类名称")
    color = models.CharField(max_length=50, verbose_name="颜色类名", help_text="例如: bg-blue-100 text-blue-600")
    
    class Meta:
        verbose_name = "课程分类"
        verbose_name_plural = verbose_name
        
    def __str__(self):
        return self.name

class Teacher(models.Model):
    name = models.CharField(max_length=50, verbose_name="教学与管理中心")
    phone = models.CharField(max_length=20, verbose_name="联系电话", null=True, blank=True)
    bio = models.TextField(verbose_name="简介", blank=True, default="")
    
    class Meta:
        verbose_name = "教学与管理中心"
        verbose_name_plural = verbose_name
        
    def __str__(self):
        return self.name

class TeachingCenter(models.Model):
    name = models.CharField(max_length=100, verbose_name="教学中心名称")
    address = models.CharField(max_length=200, verbose_name="地址", null=True, blank=True)
    phone = models.CharField(max_length=20, verbose_name="联系电话", null=True, blank=True)
    
    class Meta:
        verbose_name = "教学中心"
        verbose_name_plural = verbose_name
    
    def __str__(self):
        return self.name

class Project(models.Model):
    PROJECT_TYPE_CHOICES = (
        ('training', '在职项目'),
        ('competition', '典礼&论坛'),
        ('grading', '校友活动'),
    )
    title = models.CharField(max_length=100, verbose_name="项目名称")
    project_type = models.CharField(max_length=20, choices=PROJECT_TYPE_CHOICES, default='training', verbose_name="项目类型")
    # category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name="所属分类", related_name="projects")
    teacher = models.ForeignKey(Teacher, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="教学中心", related_name="projects")
    custom_teacher = models.CharField(max_length=100, verbose_name="自定义教学中心", default="", blank=True)
    image = models.CharField(max_length=500, verbose_name="封面图片URL", default="https://images.unsplash.com/photo-1526379095098-d400fd0bf935")
    detail = models.TextField(verbose_name="项目详情", blank=True, default="")
    students = models.IntegerField(default=0, verbose_name="学习人数")
    address = models.CharField(max_length=200, verbose_name="地址", default="", blank=True)
    duration = models.CharField(max_length=20, verbose_name="时长", default="4 周")
    price = models.DecimalField(max_digits=10, decimal_places=2, default=299.00, verbose_name="价格")
    show_price = models.BooleanField(default=True, verbose_name="显示价格")
    sort_order = models.IntegerField(default=0, verbose_name="排序")
    is_top = models.BooleanField(default=False, verbose_name="是否置顶")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "项目课程"
        verbose_name_plural = verbose_name
        ordering = ['-is_top', 'sort_order', '-created_at']

    def __str__(self):
        return self.title

class Coupon(models.Model):
    STATUS_CHOICES = (
        ('available', '可领取'),
        ('claimed', '已领取'),
        ('used', '已使用'),
        ('expired', '已过期'),
    )
    ISSUE_CHOICES = (
        ('manual', '手动发放'),
        ('registration', '注册赠送'),
        ('project', '指定项目'),
    )
    
    amount = models.CharField(max_length=10, verbose_name="面额")
    unit = models.CharField(max_length=10, verbose_name="单位", default="元")
    title = models.CharField(max_length=50, verbose_name="优惠券标题")
    desc = models.CharField(max_length=100, verbose_name="描述")
    expiry = models.DateField(verbose_name="过期时间")
    is_time_limited = models.BooleanField(default=False, verbose_name="是否限时优惠")
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='available', verbose_name="状态")
    issue_type = models.CharField(max_length=20, choices=ISSUE_CHOICES, default='manual', verbose_name="发放类型")
    applicable_projects = models.ManyToManyField(Project, blank=True, related_name="coupons", verbose_name="适用项目")
    
    # UI样式字段
    color = models.CharField(max_length=100, verbose_name="渐变色类名", default="from-blue-500 to-cyan-400")
    bgStart = models.CharField(max_length=50, verbose_name="背景起始色", default="from-blue-50")
    bgEnd = models.CharField(max_length=50, verbose_name="背景结束色", default="to-cyan-50")
    shadow = models.CharField(max_length=50, verbose_name="阴影类名", default="shadow-blue-100")

    class Meta:
        verbose_name = "优惠券"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.title

class Banner(models.Model):
    image = models.CharField(max_length=500, verbose_name="图片URL")
    project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="关联项目")
    link = models.CharField(max_length=200, blank=True, null=True, verbose_name="跳转链接")
    sort_order = models.IntegerField(default=0, verbose_name="排序")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")

    class Meta:
        verbose_name = "轮播图"
        verbose_name_plural = verbose_name
        ordering = ['sort_order']

    def __str__(self):
        return f"Banner {self.id}"

class Student(models.Model):
    name = models.CharField(max_length=50, verbose_name="学员姓名")
    phone = models.CharField(max_length=20, verbose_name="联系电话", null=True, blank=True)
    age = models.IntegerField(verbose_name="年龄", null=True, blank=True)
    wechat_nickname = models.CharField(max_length=100, verbose_name="微信昵称", null=True, blank=True)
    # 已经有了openid字段，所以这里不需要重复添加，只需要确保名称正确即可。
    # 原有 openid 字段定义： openid = models.CharField(max_length=100, verbose_name="微信OpenID", null=True, blank=True, unique=True)
    # 用户需求是“微信唯一标识”，这通常指 OpenID。
    openid = models.CharField(max_length=100, verbose_name="微信唯一标识", null=True, blank=True, unique=True)
    # parent = models.CharField(max_length=50, verbose_name="家长", null=True, blank=True)
    responsible_teacher = models.ForeignKey(Teacher, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="负责老师", related_name="students")
    address = models.CharField(max_length=200, verbose_name="地址", null=True, blank=True)
    city = models.CharField(max_length=50, verbose_name="城市", null=True, blank=True)
    # 已经有avatar字段，对应微信头像
    avatar = models.CharField(max_length=500, verbose_name="微信头像", default="https://images.unsplash.com/photo-1535713875002-d1d0cf377fde")
    is_active = models.BooleanField(default=True, verbose_name="是否活跃")
    
    enrolled_projects = models.ManyToManyField(Project, through='StudentProject', related_name='enrolled_students', verbose_name="已报名项目", blank=True)
    
    # 新增字段
    teaching_center = models.ForeignKey(TeachingCenter, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="关联教学中心")
    company_name = models.CharField(max_length=100, verbose_name="公司名称", null=True, blank=True)
    position = models.CharField(max_length=100, verbose_name="职位", null=True, blank=True)

    STATUS_CHOICES = (
        ('ordinary', '普通用户'),
        ('intention', '意向用户'),
        ('reading', '在读'),
        ('graduated', '毕业'),
    )
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='ordinary', verbose_name="状态")

    # 统计数据
    learning_count = models.IntegerField(default=0, verbose_name="在学课程数")
    coupon_count = models.IntegerField(default=0, verbose_name="优惠券数")
    study_hours = models.IntegerField(default=0, verbose_name="学习时长(小时)")
    
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="录入时间")

    class Meta:
        verbose_name = "学员信息"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class StudentCoupon(models.Model):
    STATUS_CHOICES = (
        ('assigned', '已分配'),
        ('used', '已使用'),
        ('expired', '已过期'),
        ('revoked', '已回收'),
        ('suspended', '暂停使用'),
    )
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name="student_coupons", verbose_name="学员")
    coupon = models.ForeignKey(Coupon, on_delete=models.CASCADE, related_name="assignments", verbose_name="优惠券")
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='assigned', verbose_name="状态")
    assigned_at = models.DateTimeField(auto_now_add=True, verbose_name="分配时间")
    used_at = models.DateTimeField(null=True, blank=True, verbose_name="使用时间")

    class Meta:
        verbose_name = "学员优惠券"
        verbose_name_plural = verbose_name
        ordering = ['-assigned_at']

    def __str__(self):
        return f"{self.student.name} - {self.coupon.title}"

@receiver(post_save, sender=StudentCoupon)
def update_student_coupon_count_on_save(sender, instance, created, **kwargs):
    student = instance.student
    student.coupon_count = StudentCoupon.objects.filter(student=student, status='assigned').count()
    student.save(update_fields=['coupon_count'])

@receiver(post_delete, sender=StudentCoupon)
def update_student_coupon_count_on_delete(sender, instance, **kwargs):
    try:
        student = instance.student
        # Only update if student still exists (avoid error when deleting student triggers cascade)
        if Student.objects.filter(pk=student.pk).exists():
            student.coupon_count = StudentCoupon.objects.filter(student=student, status='assigned').count()
            student.save(update_fields=['coupon_count'])
    except Exception:
        pass

class StudentProject(models.Model):
    STATUS_CHOICES = (
        ('enrolled', '已报名'),
        ('studying', '在读'),
        ('graduated', '毕业'),
        ('finished', '结束'),
    )
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name="enrollments", verbose_name="学员")
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="enrollments", verbose_name="项目")
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='enrolled', verbose_name="状态")
    enrolled_at = models.DateTimeField(auto_now_add=True, verbose_name="报名时间")
    completed_at = models.DateTimeField(blank=True, null=True, verbose_name="完成时间")

    class Meta:
        verbose_name = "学员项目报名"
        verbose_name_plural = verbose_name
        ordering = ['-enrolled_at']
        unique_together = ('student', 'project')

    def __str__(self):
        return f"{self.student.name} - {self.project.title}"

@receiver(post_save, sender=StudentProject)
def update_student_learning_count_on_save(sender, instance, created, **kwargs):
    student = instance.student
    # Count projects with status 'enrolled' or 'studying'
    count = StudentProject.objects.filter(
        student=student, 
        status__in=['enrolled', 'studying']
    ).count()
    student.learning_count = count
    student.save(update_fields=['learning_count'])

@receiver(post_delete, sender=StudentProject)
def update_student_learning_count_on_delete(sender, instance, **kwargs):
    try:
        student = instance.student
        if Student.objects.filter(pk=student.pk).exists():
            count = StudentProject.objects.filter(
                student=student, 
                status__in=['enrolled', 'studying']
            ).count()
            student.learning_count = count
            student.save(update_fields=['learning_count'])
    except Exception:
        pass

class StudentHonor(models.Model):
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name="honors", verbose_name="学员")
    title = models.CharField(max_length=100, verbose_name="荣誉标题")
    image = models.CharField(max_length=500, verbose_name="证书图片URL", default="https://images.unsplash.com/photo-1579548122080-c35fd6820ecb")
    date = models.DateField(verbose_name="获得日期")
    description = models.TextField(verbose_name="荣誉描述", blank=True, default="")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "学员荣誉"
        verbose_name_plural = verbose_name
        ordering = ['-date']

    def __str__(self):
        return f"{self.student.name} - {self.title}"

class StudentShowcase(models.Model):
    title = models.CharField(max_length=100, verbose_name="标题")
    cover_image = models.CharField(max_length=500, verbose_name="封面图片URL")
    video_url = models.CharField(max_length=500, verbose_name="视频链接URL", blank=True, null=True)
    description = models.TextField(verbose_name="描述", blank=True, default="")
    student = models.ForeignKey(Student, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="关联学员", related_name="showcases")
    sort_order = models.IntegerField(default=0, verbose_name="排序")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "精彩视频"
        verbose_name_plural = verbose_name
        ordering = ['sort_order', '-created_at']

    def __str__(self):
        return self.title

@receiver(post_save, sender=Student)
def activate_coupons_on_phone_bind(sender, instance, created, **kwargs):
    # If we are just updating coupon_count or learning_count, do not trigger coupon issuance
    update_fields = kwargs.get('update_fields')
    if update_fields:
        # Allow if other fields are present, but if ONLY these statistics are updated, skip.
        ignored_fields = {'coupon_count', 'learning_count'}
        if set(update_fields).issubset(ignored_fields):
            return

    if instance.phone:
        # 自动发放注册类型的优惠券
        reg_coupons = Coupon.objects.filter(issue_type='registration', status='available')
        for coupon in reg_coupons:
             # Use filter().exists() to check for existence to avoid MultipleObjectsReturned error
             if not StudentCoupon.objects.filter(student=instance, coupon=coupon).exists():
                 StudentCoupon.objects.create(
                     student=instance,
                     coupon=coupon,
                     status='assigned'
                 )

class NotificationBatch(models.Model):
    SEND_MODE_CHOICES = (
        ('custom', '自定义发送'),
        ('project', '按项目发送'),
        ('coupon', '按优惠券发送'),
    )
    # Using choices from Notification class requires Notification to be defined, 
    # but NotificationBatch is defined before Notification.
    # So I will redefine choices or use strings.
    TYPE_CHOICES = (
        ('system', '系统通知'),
        ('activity', '活动提醒'),
        ('course', '课程通知'),
    )

    title = models.CharField(max_length=100, verbose_name="标题")
    content = models.TextField(verbose_name="内容")
    notification_type = models.CharField(max_length=20, choices=TYPE_CHOICES, default='system', verbose_name="通知类型")
    send_mode = models.CharField(max_length=20, choices=SEND_MODE_CHOICES, default='custom', verbose_name="发送方式")
    # SQLite version issue with JSONField, using TextField with manual JSON handling
    target_criteria = models.TextField(verbose_name="发送条件", default="{}")
    recipient_count = models.IntegerField(default=0, verbose_name="接收人数")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="发送时间")
    
    class Meta:
        verbose_name = "通知发送记录"
        verbose_name_plural = verbose_name
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.title} ({self.get_send_mode_display()})"

class Notification(models.Model):
    TYPE_CHOICES = (
        ('system', '系统通知'),
        ('activity', '活动提醒'),
        ('course', '课程通知'),
    )
    
    student = models.ForeignKey('Student', on_delete=models.CASCADE, related_name='notifications', verbose_name="接收学员")
    batch = models.ForeignKey(NotificationBatch, on_delete=models.CASCADE, null=True, blank=True, related_name="notifications", verbose_name="关联批次")
    title = models.CharField(max_length=100, verbose_name="标题")
    content = models.TextField(verbose_name="内容")
    notification_type = models.CharField(max_length=20, choices=TYPE_CHOICES, default='system', verbose_name="通知类型")
    is_read = models.BooleanField(default=False, verbose_name="是否已读")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="发送时间")

    class Meta:
        verbose_name = "消息通知"
        verbose_name_plural = verbose_name
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.title} - {self.student.name}"
