"""
用户模块模型
"""
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models


class UserManager(BaseUserManager):
    """用户管理器"""
    
    def create_user(self, phone, password=None, **extra_fields):
        if not phone:
            raise ValueError('手机号不能为空')
        user = self.model(phone=phone, **extra_fields)
        if password:
            user.set_password(password)
        user.save(using=self._db)
        return user
    
    def create_superuser(self, phone, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self.create_user(phone, password, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
    """用户模型"""
    
    id = models.BigAutoField(primary_key=True)
    phone = models.CharField('手机号', max_length=20, unique=True)
    nickname = models.CharField('昵称', max_length=50, blank=True, default='')
    avatar = models.URLField('头像', max_length=500, blank=True, default='')
    gender = models.CharField(
        '性别', max_length=10,
        choices=[('male', '男'), ('female', '女'), ('unknown', '未知')],
        default='unknown'
    )
    birthday = models.DateField('生日', null=True, blank=True)
    points = models.IntegerField('积分余额', default=0)
    is_active = models.BooleanField('是否激活', default=True)
    is_staff = models.BooleanField('是否管理员', default=False)
    is_pending_deletion = models.BooleanField('是否待注销', default=False)
    deletion_requested_at = models.DateTimeField('注销申请时间', null=True, blank=True)
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)
    
    objects = UserManager()
    
    USERNAME_FIELD = 'phone'
    REQUIRED_FIELDS = []
    
    class Meta:
        db_table = 'user'
        verbose_name = '用户'
        verbose_name_plural = '用户'
    
    def __str__(self):
        return self.phone


class PointsRecord(models.Model):
    """积分流水记录"""

    TYPE_CHOICES = [
        ('unlock_shelf', '解锁书架'),
        ('reward', '奖励'),
        ('admin_adjust', '管理员调整'),
        ('generate_music', '生成音乐'),
        ('refund_music', '音乐生成退款'),
    ]

    user = models.ForeignKey(
        User, on_delete=models.CASCADE,
        related_name='points_records', verbose_name='用户'
    )
    amount = models.IntegerField('变动数量')
    type = models.CharField('类型', max_length=30, choices=TYPE_CHOICES)
    description = models.CharField('描述', max_length=200, blank=True, default='')
    created_at = models.DateTimeField('创建时间', auto_now_add=True)

    class Meta:
        db_table = 'points_record'
        verbose_name = '积分流水'
        verbose_name_plural = verbose_name
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', '-created_at']),
        ]

    def __str__(self):
        return f'{self.user.phone} {self.amount:+d} ({self.type})'


class SmsCode(models.Model):
    """短信验证码"""
    phone = models.CharField('手机号', max_length=20)
    code = models.CharField('验证码', max_length=6)
    is_used = models.BooleanField('是否已使用', default=False)
    expire_at = models.DateTimeField('过期时间')
    created_at = models.DateTimeField('创建时间', auto_now_add=True)

    class Meta:
        db_table = 'sms_code'
        verbose_name = '短信验证码'
        verbose_name_plural = verbose_name
        indexes = [
            models.Index(fields=['phone', 'code']),
            models.Index(fields=['expire_at']),
        ]

    def __str__(self):
        return f"{self.phone} - {self.code}"
