from django.contrib import auth
from django.db.models import QuerySet
from django_filters.rest_framework import DjangoFilterBackend
from django.shortcuts import get_object_or_404, get_list_or_404
from rest_framework import generics
from rest_framework import permissions
from rest_framework import views
from rest_framework.exceptions import ValidationError
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.serializers import Serializer

from . import models
from . import serializers


class User(generics.ListCreateAPIView):
    """
    获得user列表
    添加user
    """
    serializer_class = serializers.UserSerializer
    queryset = models.User.objects.all().order_by('id')
    permission_classes = (permissions.IsAdminUser,)
    pagination_class = PageNumberPagination
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
    filterset_fields = [
        'role',
    ]
    search_fields = [
        'id',
        'username',
        'email',
    ]
    ordering_fields = [
        'id',
        'username',
        'date_joined',
        'last_login',
    ]

    def perform_create(self, serializer):
        user = serializer.validated_data
        models.User.objects.create_user(**user)


class UserDetail(generics.RetrieveUpdateDestroyAPIView):
    """
    获得指定user
    更新指定user
    删除指定user
    """
    serializer_class = serializers.UserSerializer
    queryset = models.User.objects.all()
    permission_classes = (permissions.IsAdminUser,)

    def perform_update(self, serializer):
        serializer.save()
        data = serializer.validated_data
        password = data.get('password')
        if password:
            user = get_object_or_404(models.User, id=self.kwargs['pk'])
            user.set_password(password)
            user.save()


class RoleList(generics.GenericAPIView):
    """
    获得角色列表
    """
    queryset = QuerySet()
    permission_classes = (permissions.IsAuthenticated,)

    def get(self, request):
        role_list = []
        for role in models.User.ROLE_CHOICE:
            role_list.append({
                'id': role[0],
                'name': role[1]
            })
        return Response(role_list)


class Login(generics.GenericAPIView):
    """
    登陆
    """
    serializer_class = serializers.LoginSerializer

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data
        user = auth.authenticate(username=data.get('username'), password=data.get("password"))
        if user:
            if not user.is_active:
                raise ValidationError('您的账户未激活或被关闭，请检查邮箱或者联系管理员')
            else:
                auth.login(request, user)
                return Response(serializers.UserSerializer(user).data)
        else:
            raise ValidationError('用户名不存在或密码不正确')


class Logout(generics.GenericAPIView):
    """
    注销
    """
    permission_classes = (permissions.IsAuthenticated,)

    def get(self, request):
        auth.logout(request)
        return Response("")


class GetInfo(generics.GenericAPIView):
    """
    获得当前用户信息
    """
    serializer_class = serializers.UserSerializer
    permission_classes = (permissions.IsAuthenticated,)

    def get(self, request):
        s = self.get_serializer(request.user)
        return Response(s.data)


class ResetPassword(generics.GenericAPIView):
    """
    重置密码
    """
    serializer_class = Serializer
    permission_classes = (permissions.IsAuthenticated,)

    def post(self, request):
        new_password = request.data.get('new_password')
        if new_password:
            request.user.set_password(new_password)
            request.user.save()
            auth.logout(request)
        else:
            raise ValidationError('新密码不正确')
        return Response("")


class CheckUsername(views.APIView):
    """
    检查username是否重复
    """

    def get(self, request):
        username = request.query_params.get('username')
        if username:
            return Response(models.User.objects.filter(username=username).exists())
        else:
            raise ValidationError("Did not get username.")
