from rest_framework import viewsets
from .models import ListModel, TypeListModel
from . import serializers
from utils.page import MyPageNumberPagination
from rest_framework.filters import OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.response import Response
from .filter import Filter, TypeFilter
from rest_framework.exceptions import APIException
from .serializers import FileRenderSerializer
from django.http import StreamingHttpResponse
from .files import FileRenderCN, FileRenderEN
from rest_framework.settings import api_settings
from rest_framework import permissions
from staff.models import ListModel as staff
from utils.md5 import Md5
import random
from django.contrib.auth.models import User


class APIViewSet(viewsets.ModelViewSet):
    """
        retrieve:
            Response a data list(get)

        list:
            Response a data list(all)

        create:
            Create a data line(post)

        delete:
            Delete a data line(delete)

        partial_update:
            Partial_update a data(patch:partial_update)

        update:
            Update a data(put:update)
    """
    pagination_class = MyPageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
    ordering_fields = ['id', "create_time", "update_time", ]
    filter_class = Filter

    def list(self, request, *args, **kwargs):
        # staff_name = str(request.GET.get('staff_name'))
        # check_code = request.GET.get('check_code')
        # if staff_name == None and check_code == None:
        #     return super().list(request, *args, **kwargs)
        # elif staff_name != None and check_code == None:
        #     return super().list(request, *args, **kwargs)
        # else:
        #     staff_name_obj = ListModel.objects.filter(openid=self.request.auth.openid, staff_name=staff_name,
        #                                               is_delete=False).first()
        #     if staff_name_obj is None:
        #         raise APIException({"detail": "用户名不存在"})
        #     elif staff_name_obj.is_lock is True:
        #         raise APIException({"detail": "用户已被锁定,请联系管理员"})
        #     elif staff_name_obj.error_check_code_counter == 3:
        #         staff_name_obj.is_lock = True
        #         staff_name_obj.error_check_code_counter = 0
        #         staff_name_obj.save()
        #         raise APIException({"detail": "用户已被锁定,请联系管理员"})

        #     if type(check_code) == str:
        #         check_code = int(check_code)
        #     if check_code != None:
        #         if staff_name_obj.check_code != check_code:
        #             staff_name_obj.error_check_code_counter = int(staff_name_obj.error_check_code_counter) + 1
        #             staff_name_obj.save()
        #             raise APIException({"detail": "验证码错误"})
        #         else:
        #             staff_name_obj.error_check_code_counter = 0
        #             staff_name_obj.save()
        #             return super().list(request, *args, **kwargs)
        #     else:
                return super().list(request, *args, **kwargs)


    def get_project(self):
        try:
            id = self.kwargs.get('pk')
            return id
        except:
            return None

    def get_queryset(self):
        id = self.get_project()
        if self.request.user:
            if id is None:               
                return ListModel.objects.filter(is_delete=False)
            else:
                return ListModel.objects.filter(id=id, is_delete=False)
        else:
            return ListModel.objects.none()

    def get_serializer_class(self):
        appid = self.request.META.get('HTTP_APPID')
        token = self.request.META.get('HTTP_TOKEN')
        if appid != token :
            if self.action in ['list', 'retrieve', 'destroy']:
                return serializers.userStaffGetSerializer
            elif self.action in ['create']:
                return serializers.userStaffPostSerializer
            elif self.action in ['update']:
                return serializers.userStaffUpdateSerializer
            elif self.action in ['partial_update']:
                return serializers.userStaffPartialUpdateSerializer
            else:
                return self.http_method_not_allowed(request=self.request)
        else:  
            if self.action in ['list', 'retrieve', 'destroy']:
                return serializers.StaffGetSerializer
            elif self.action in ['create']:
                return serializers.StaffPostSerializer
            elif self.action in ['update']:
                return serializers.StaffUpdateSerializer
            elif self.action in ['partial_update']:
                return serializers.StaffPartialUpdateSerializer
            else:
                return self.http_method_not_allowed(request=self.request)

    def create(self, request, *args, **kwargs):
        data = self.request.data
        data['openid'] = self.request.auth.openid
        if ListModel.objects.filter(openid=data['openid'], staff_name=data['staff_name'], is_delete=False).exists():
            raise APIException({"detail": "Data exists"})
        else:
            app_code =Md5.md5(data['staff_name']+ '1')
            data['appid'] = app_code
            check_code = random.randint(1000, 9999)
           
            data['check_code'] = check_code
            user = User.objects.create_user(username=str(data['staff_name']),
                                password=str(check_code))
            serializer = self.get_serializer(data=data)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)

    def update(self, request, pk):
        qs = self.get_object()
        if qs.openid != self.request.auth.openid:
            creator = ListModel.objects.filter(openid=self.request.auth.openid, is_delete=False)
            raise APIException({"detail": "该用户不是您创建的,不能修改"})
        else:
            data = self.request.data
            serializer = self.get_serializer(qs, data=data)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)

    def partial_update(self, request, pk):
        qs = self.get_object()
        if qs.openid != self.request.auth.openid:
            raise APIException({"detail": "Cannot Update Data Which Not Yours"})
        else:
            data = self.request.data
            serializer = self.get_serializer(qs, data=data, partial=True)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)

    def destroy(self, request, pk):

        qs = self.get_object()
        if qs.openid != self.request.auth.openid:
            raise APIException({"detail": "Cannot Delete Data Which Not Yours"})
        else:
            qs.is_delete = True
            qs.save()
            serializer = self.get_serializer(qs, many=False)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)



     


class TypeAPIViewSet(viewsets.ModelViewSet):
    """
        list:
            Response a data list(all)
    """
    pagination_class = MyPageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
    ordering_fields = ['id', "create_time", "update_time", ]
    filter_class = TypeFilter

    def get_queryset(self):
        if self.request.user:
            return TypeListModel.objects.filter(openid='init_data')
        else:
            return TypeListModel.objects.none()

    def get_serializer_class(self):
        if self.action in ['list']:
            return serializers.StaffTypeGetSerializer
        else:
            return self.http_method_not_allowed(request=self.request)


class FileDownloadView(viewsets.ModelViewSet):
    renderer_classes = (FileRenderCN,) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
    ordering_fields = ['id', "create_time", "update_time", ]
    filter_class = Filter

    def get_project(self):
        try:
            id = self.kwargs.get('pk')
            return id
        except:
            return None

    def get_queryset(self):
        id = self.get_project()
        if self.request.user:
            if id is None:
                return ListModel.objects.filter(openid=self.request.auth.openid, is_delete=False)
            else:
                return ListModel.objects.filter(openid=self.request.auth.openid, id=id, is_delete=False)
        else:
            return ListModel.objects.none()

    def get_serializer_class(self):
        if self.action in ['list']:
            return serializers.FileRenderSerializer
        else:
            return self.http_method_not_allowed(request=self.request)

    def get_lang(self, data):
        lang = self.request.META.get('HTTP_LANGUAGE')
        if lang:
            if lang == 'zh-hans':
                return FileRenderCN().render(data)
            else:
                return FileRenderEN().render(data)
        else:
            return FileRenderEN().render(data)

    def list(self, request, *args, **kwargs):
        from datetime import datetime
        dt = datetime.now()
        data = (
            FileRenderSerializer(instance).data
            for instance in self.filter_queryset(self.get_queryset())
        )
        renderer = self.get_lang(data)
        response = StreamingHttpResponse(
            renderer,
            content_type="text/csv"
        )
        response['Content-Disposition'] = "attachment; filename='staff_{}.csv'".format(
            str(dt.strftime('%Y%m%d%H%M%S%f')))
        return response