from django import forms
from django.contrib.auth.admin import UserAdmin  # Django 自带的用户管理后台基类
from django.contrib.auth.forms import UserChangeForm  # Django 默认的用户信息修改表单
from django.contrib.auth.forms import UsernameField  # Django 用于用户名字段的专用表单字段
from django.utils.translation import gettext_lazy as _  # 用于支持多语言翻译的辅助函数

# 从当前 app 的 models 导入自定义的用户模型 BlogUser
from .models import BlogUser


# ======================
# 自定义用户创建表单（用于后台添加用户时使用）
# ======================
class BlogUserCreationForm(forms.ModelForm):
    # 添加两个密码字段，用于用户注册时输入和确认密码
    password1 = forms.CharField(
        label=_('password'),  # 字段显示名称（可翻译），这里是“password”
        widget=forms.PasswordInput  # 使用密码输入框，输入内容会被隐藏
    )
    password2 = forms.CharField(
        label=_('Enter password again'),  # 确认密码的标签
        widget=forms.PasswordInput  # 同样是密码输入框
    )

    class Meta:
        model = BlogUser  # 指定该表单关联的模型是 BlogUser
        fields = ('email',)  # 在创建用户时，只显示 email 字段（可以从后台选择的字段）

    def clean_password2(self):
        """
        校验两次输入的密码是否一致
        """
        # 从 cleaned_data 中获取用户输入的两个密码
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")

        # 如果两个密码都有值，但它们不相等，则抛出验证错误
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(_("passwords do not match"))  # 提示“密码不匹配”

        # 验证通过，返回 password2（通常返回确认密码字段的值）
        return password2

    def save(self, commit=True):
        """
        保存用户对象，并对密码进行哈希处理
        """
        # 调用父类的 save 方法，但不立即提交到数据库（commit=False）
        user = super().save(commit=False)

        # 对用户输入的密码（password1）进行哈希处理，并设置到 user 对象上
        user.set_password(self.cleaned_data["password1"])

        if commit:
            # 如果 commit=True（默认），则保存到数据库
            # 同时，给用户添加一个来源标识 source = 'adminsite'，表示是通过后台添加的
            user.source = 'adminsite'
            user.save()

        # 返回保存后的用户对象
        return user


# ======================
# 自定义用户修改表单（用于后台编辑用户信息时使用）
# ======================
class BlogUserChangeForm(UserChangeForm):
    class Meta:
        model = BlogUser  # 指定关联的模型是 BlogUser
        fields = '__all__'  # 表单中包含模型的所有字段
        # 指定 username 字段使用 Django 提供的 UsernameField，它对用户名有特殊处理（如唯一性等）
        field_classes = {'username': UsernameField}

    def __init__(self, *args, ​**kwargs):
        """
        初始化方法，这里暂时没有额外逻辑，只是调用了父类的初始化
        """
        super().__init__(*args, ​**kwargs)


# ======================
# 自定义用户管理后台类（用于在 Django Admin 中管理 BlogUser 模型）
# ======================
class BlogUserAdmin(UserAdmin):
    # 指定用户修改时使用的表单类（编辑用户信息时）
    form = BlogUserChangeForm

    # 指定用户创建时使用的表单类（添加新用户时）
    add_form = BlogUserCreationForm

    # 定义在用户列表页显示哪些字段
    list_display = (
        'id',           # 用户 ID
        'nickname',     # 昵称（假设你的 BlogUser 模型中有这个字段）
        'username',     # 用户名
        'email',        # 邮箱
        'last_login',   # 上次登录时间
        'date_joined',  # 注册时间
        'source'        # 用户来源（比如 adminsite 表示后台添加）
    )

    # 定义哪些字段可以作为链接，点击后可以进入编辑页面
    # 这里 id 和 username 都可以作为链接
    list_display_links = ('id', 'username')

    # 定义默认排序方式，这里是按照 id 降序（最新的用户在前面）
    ordering = ('-id',)