#lsx 账号管理视图模块

from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import PasswordResetView, PasswordResetConfirmView
from django.http import JsonResponse
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse_lazy
from django.views import View
from django.utils.translation import gettext_lazy as _
from django.utils import timezone

from accounts.models import BlogUser
from accounts.forms import (UserLoginForm, UserRegisterForm, UserChangeForm,
                           UserPasswordChangeForm, ProfileForm)
from djangoblog.utils import get_blog_setting, send_email, get_sha256

#lsx 注册视图
class RegisterView(View):
    #lsx 用户注册处理
    def get(self, request):
        #lsx 检查是否已登录
        if request.user.is_authenticated:
            return redirect('/')
        #lsx 创建注册表单
        form = UserRegisterForm()
        #lsx 构建上下文
        context = {
            'form': form,
            'blog_setting': get_blog_setting()
        }
        #lsx 渲染注册页面
        return render(request, 'accounts/register.html', context)
    
    def post(self, request):
        #lsx 检查是否已登录
        if request.user.is_authenticated:
            return JsonResponse({'status': 'success', 'msg': _('您已登录')})
        #lsx 获取表单数据
        form = UserRegisterForm(request.POST)
        #lsx 验证表单
        if form.is_valid():
            #lsx 获取表单数据
            username = form.cleaned_data['username']
            email = form.cleaned_data['email']
            password = form.cleaned_data['password']
            #lsx 创建用户
            user = BlogUser.objects.create_user(
                username=username,
                email=email,
                password=password
            )
            #lsx 生成激活码
            user.activation_key = get_sha256(email + str(timezone.now()))
            user.key_expires = timezone.now() + timezone.timedelta(days=2)
            user.save()
            #lsx 发送激活邮件
            try:
                send_email(email, _('激活您的账号'), 'accounts/activate_email.html', {
                    'user': user,
                    'site': get_blog_setting(),
                    'activation_key': user.activation_key
                })
                return JsonResponse({'status': 'success', 'msg': _('注册成功，请查收邮件激活账号')})
            except Exception as e:
                return JsonResponse({'status': 'fail', 'msg': _('发送激活邮件失败')})
        else:
            return JsonResponse({'status': 'fail', 'msg': _('表单验证失败'), 'errors': form.errors})

#lsx 登录视图
class LoginView(View):
    #lsx 用户登录处理
    def get(self, request):
        #lsx 检查是否已登录
        if request.user.is_authenticated:
            return redirect('/')
        #lsx 创建登录表单
        form = UserLoginForm()
        #lsx 构建上下文
        context = {
            'form': form,
            'blog_setting': get_blog_setting()
        }
        #lsx 渲染登录页面
        return render(request, 'accounts/login.html', context)
    
    def post(self, request):
        #lsx 检查是否已登录
        if request.user.is_authenticated:
            return JsonResponse({'status': 'success', 'msg': _('您已登录')})
        #lsx 获取表单数据
        form = UserLoginForm(request.POST)
        #lsx 验证表单
        if form.is_valid():
            #lsx 获取用户名和密码
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            #lsx 认证用户
            user = authenticate(username=username, password=password)
            if user:
                #lsx 检查用户是否激活
                if user.is_active:
                    #lsx 登录用户
                    login(request, user)
                    #lsx 更新登录时间
                    user.last_login = timezone.now()
                    user.save()
                    return JsonResponse({'status': 'success', 'msg': _('登录成功')})
                else:
                    return JsonResponse({'status': 'fail', 'msg': _('账号未激活')})
            else:
                return JsonResponse({'status': 'fail', 'msg': _('用户名或密码错误')})
        else:
            return JsonResponse({'status': 'fail', 'msg': _('表单验证失败'), 'errors': form.errors})

#lsx 登出视图
class LogoutView(View):
    #lsx 用户登出处理
    def get(self, request):
        #lsx 登出用户
        logout(request)
        #lsx 重定向到首页
        return redirect('/')

#lsx 个人信息视图
class ProfileView(LoginRequiredMixin, View):
    #lsx 查看和编辑个人信息
    def get(self, request):
        #lsx 获取用户对象
        user = request.user
        #lsx 创建表单
        user_form = UserChangeForm(instance=user)
        profile_form = ProfileForm(instance=user)
        #lsx 构建上下文
        context = {
            'user_form': user_form,
            'profile_form': profile_form,
            'blog_setting': get_blog_setting()
        }
        #lsx 渲染个人信息页面
        return render(request, 'accounts/profile.html', context)
    
    def post(self, request):
        #lsx 获取用户对象
        user = request.user
        #lsx 获取表单数据
        user_form = UserChangeForm(request.POST, instance=user)
        profile_form = ProfileForm(request.POST, request.FILES, instance=user)
        #lsx 验证表单
        if user_form.is_valid() and profile_form.is_valid():
            #lsx 保存用户信息
            user_form.save()
            profile_form.save()
            return JsonResponse({'status': 'success', 'msg': _('个人信息更新成功')})
        else:
            return JsonResponse({'status': 'fail', 'msg': _('表单验证失败'), 'errors': {
                'user_form': user_form.errors,
                'profile_form': profile_form.errors
            }})

#lsx 密码修改视图
class PasswordChangeView(LoginRequiredMixin, View):
    #lsx 修改用户密码
    def get(self, request):
        #lsx 创建密码修改表单
        form = UserPasswordChangeForm(request.user)
        #lsx 构建上下文
        context = {
            'form': form,
            'blog_setting': get_blog_setting()
        }
        #lsx 渲染密码修改页面
        return render(request, 'accounts/password_change.html', context)
    
    def post(self, request):
        #lsx 获取表单数据
        form = UserPasswordChangeForm(request.user, request.POST)
        #lsx 验证表单
        if form.is_valid():
            #lsx 保存新密码
            user = form.save()
            #lsx 更新登录状态
            login(request, user)
            return JsonResponse({'status': 'success', 'msg': _('密码修改成功')})
        else:
            return JsonResponse({'status': 'fail', 'msg': _('表单验证失败'), 'errors': form.errors})

#lsx 密码重置视图
class CustomPasswordResetView(PasswordResetView):
    #lsx 自定义密码重置视图
    template_name = 'accounts/password_reset.html'
    email_template_name = 'accounts/password_reset_email.html'
    success_url = reverse_lazy('accounts:password_reset_done')
    
    def get_context_data(self, **kwargs):
        #lsx 添加博客设置到上下文
        context = super().get_context_data(**kwargs)
        context['blog_setting'] = get_blog_setting()
        return context

#lsx 密码重置确认视图
class CustomPasswordResetConfirmView(PasswordResetConfirmView):
    #lsx 自定义密码重置确认视图
    template_name = 'accounts/password_reset_confirm.html'
    success_url = reverse_lazy('accounts:login')
    
    def get_context_data(self, **kwargs):
        #lsx 添加博客设置到上下文
        context = super().get_context_data(**kwargs)
        context['blog_setting'] = get_blog_setting()
        return context

#lsx 账号激活视图
class ActivateView(View):
    #lsx 激活用户账号
    def get(self, request, activation_key):
        #lsx 查找对应的用户
        try:
            user = BlogUser.objects.get(activation_key=activation_key)
            #lsx 检查激活码是否过期
            if user.key_expires > timezone.now():
                #lsx 激活账号
                user.is_active = True
                user.activation_key = None
                user.key_expires = None
                user.save()
                #lsx 登录用户
                login(request, user)
                #lsx 构建成功上下文
                context = {
                    'status': 'success',
                    'msg': _('账号激活成功'),
                    'blog_setting': get_blog_setting()
                }
            else:
                #lsx 激活码过期
                context = {
                    'status': 'fail',
                    'msg': _('激活码已过期'),
                    'blog_setting': get_blog_setting()
                }
        except BlogUser.DoesNotExist:
            #lsx 无效的激活码
            context = {
                'status': 'fail',
                'msg': _('无效的激活码'),
                'blog_setting': get_blog_setting()
            }
        #lsx 渲染激活页面
        return render(request, 'accounts/activate.html', context)

#lsx 用户列表视图（管理员）
class UserListView(LoginRequiredMixin, View):
    #lsx 检查是否为超级用户
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_superuser:
            return redirect('/')
        return super().dispatch(request, *args, **kwargs)
    
    def get(self, request):
        #lsx 获取所有用户
        users = BlogUser.objects.all()
        #lsx 构建上下文
        context = {
            'users': users,
            'blog_setting': get_blog_setting()
        }
        #lsx 渲染用户列表页面
        return render(request, 'accounts/user_list.html', context)

#lsx 用户详情视图（管理员）
class UserDetailView(LoginRequiredMixin, View):
    #lsx 检查是否为超级用户
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_superuser:
            return redirect('/')
        return super().dispatch(request, *args, **kwargs)
    
    def get(self, request, user_id):
        #lsx 获取用户对象
        user = get_object_or_404(BlogUser, id=user_id)
        #lsx 构建上下文
        context = {
            'user': user,
            'blog_setting': get_blog_setting()
        }
        #lsx 渲染用户详情页面
        return render(request, 'accounts/user_detail.html', context)

#lsx 用户删除视图（管理员）
class UserDeleteView(LoginRequiredMixin, View):
    #lsx 检查是否为超级用户
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_superuser:
            return redirect('/')
        return super().dispatch(request, *args, **kwargs)
    
    def post(self, request, user_id):
        #lsx 不能删除自己
        if request.user.id == int(user_id):
            return JsonResponse({'status': 'fail', 'msg': _('不能删除自己')})
        #lsx 获取用户对象
        user = get_object_or_404(BlogUser, id=user_id)
        #lsx 删除用户
        user.delete()
        return JsonResponse({'status': 'success', 'msg': _('用户删除成功')})

#lsx 用户状态切换视图（管理员）
class UserStatusChangeView(LoginRequiredMixin, View):
    #lsx 检查是否为超级用户
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_superuser:
            return redirect('/')
        return super().dispatch(request, *args, **kwargs)
    
    def post(self, request, user_id):
        #lsx 不能修改自己的状态
        if request.user.id == int(user_id):
            return JsonResponse({'status': 'fail', 'msg': _('不能修改自己的状态')})
        #lsx 获取用户对象
        user = get_object_or_404(BlogUser, id=user_id)
        #lsx 切换用户状态
        user.is_active = not user.is_active
        user.save()
        return JsonResponse({'status': 'success', 'msg': _('用户状态更新成功')})
