from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from rest_framework import viewsets, status
from .models import *
from .serializers import *
from rest_framework.decorators import api_view, action
from rest_framework.response import Response
from django.views import View
from rest_framework.views import APIView
from rest_framework import generics
from rest_framework import mixins
from rest_framework import permissions
from . import permissions as mypermissions

from rest_framework import throttling
from .throttling import MyAnon, MyUser

# django过滤类
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters

from .pagination import MyPagination
from rest_framework_simplejwt.authentication import JWTAuthentication


@api_view(["GET"])
def getuserinfo(request):
    user = JWTAuthentication().authenticate(request)
    seria = UserSerializer(instance=user[0])
    return Response(seria.data, status=status.HTTP_200_OK)


class CategoryListView(generics.ListCreateAPIView):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer


class CategoryDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer


class CategoryViewSets2(viewsets.ModelViewSet):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer


class CategoryListView2(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin):
    # def get_queryset(self):
    #     return Category.objects.all()
    #
    # def get_serializer_class(self):
    #     return CategorySerializer

    queryset = Category.objects.all()
    serializer_class = CategorySerializer

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)


class CategoryDetailView2(generics.GenericAPIView, mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                          mixins.DestroyModelMixin):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer

    def get(self, request, pk):
        return self.retrieve(request, pk)

    def put(self, request, pk):
        return self.update(request, pk)

    def patch(self, request, pk):
        return self.update(request, pk)

    def delete(self, request, pk):
        return self.delete(request, pk)


class CategoryListView1(APIView):
    """
    继承django自带的View类需要重写对应http方法
    继承DRF自带的APIView类即可完成请求响应的封装  APIWiew继承封装了Django的View
    """

    def get(self, request):
        # print(request, type(request))
        # instance 从数据库取数据
        seria = CategorySerializer(instance=Category.objects.all(), many=True)
        return Response(seria.data, status=status.HTTP_200_OK)

    def post(self, request):
        # data从请求中取数据
        seria = CategorySerializer(data=request.data, )
        # if seria.is_valid():
        #     seria.save()
        #     return Response(seria.data,status=status.HTTP_201_CREATED)
        # else:
        #     return Response(seria.errors,status=status.HTTP_400_BAD_REQUEST)
        seria.is_valid(raise_exception=True)
        seria.save()
        return Response(seria.data, status=status.HTTP_201_CREATED)


class CategoryDetailView1(View):
    def get(self, request, cid):
        seria = CategorySerializer(instance=get_object_or_404(Category, pk=cid))
        return Response(seria.data, status=status.HTTP_200_OK)

    def put(self, request, cid):
        seria = CategorySerializer(instance=get_object_or_404(Category, pk=cid), data=request.data)
        if seria.is_valid():
            seria.save()
            return Response(seria.data, status=status.HTTP_200_OK)
        else:
            return Response(seria.data, status=status.HTTP_200_OK)
        # return HttpResponse("修改成功put")

    def patch(self, request, cid):
        return HttpResponse("修改成功")

    def delete(self, request, cid):
        get_object_or_404(Category, pk=cid).delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


@api_view(['GET', 'POST'])
def categoryList(request):
    if request.method == 'GET':
        seria = CategorySerializer(instance=Category.objects.all(), many=True)
        return Response(seria.data, status=status.HTTP_200_OK)
    elif request.method == 'POST':
        #  data 为序列化对象  来源于请求中提取的数据
        seria = CategorySerializer(data=request.data)
        # 从请求中提取的数据序列化之前需要进行校验
        if seria.is_valid():
            seria.save()
            return Response(seria.data, status=status.HTTP_201_CREATED)
        else:
            return Response(seria.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'POST', 'PATCH', 'DELETE'])
def categoryDetail(request, cid):
    model = get_object_or_404(Category, pk=cid)
    if request.method == 'GET':
        seria = CategorySerializer(instance=model)
        return Response(seria.data, status=status.HTTP_200_OK)
    elif request.method == 'PUT' or request.method == 'PATCH':
        #  更新就是从请求中提取参数  替换掉数据库中取出的数据
        seria = CategorySerializer(instance=model, data=request.data)
        #  验证是否合法
        if seria.is_valid():
            seria.save()
            return Response(seria.data, status=status.HTTP_200_OK)
        else:
            return Response(seria.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        model.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    else:
        return HttpResponse('当前路由不允许' + request.method + '操作')


class CategoryViewSets(viewsets.ModelViewSet):
    """
    分类试图类
    继承ModelViewSet之后拥有GET POST PUT PATCH DELETE等HTTP动词操作
    queryset 指明需要操作的模型列表
    serializer_class 指明序列化类
    """
    queryset = Category.objects.all()
    serializer_class = CategorySerializer

    # 授权的前提是认证
    # permissions_classes = [permissions.IsAdminUser]
    # 超级管理员可以创建分类  普通用户可以查看分类
    def get_permissions(self):
        if self.action == 'create' or self.action == 'update' or self.action == 'partial_update' or self.action == 'destroy':
            return [permissions.IsAdminUser()]
        else:
            return []

    # throttle_classes = [MyAnon, MyUser]
    # pagination_class = MyPagination

    # 局部过滤配置
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['name']
    search_fields = ['name']
    ordering_firlds = ['id']


class GoodViewSets(viewsets.ModelViewSet):
    queryset = Good.objects.all()
    serializer_class = GoodSerializer
    filterset_fields = ['name']


class GoodImgsViewSets(viewsets.ModelViewSet):
    queryset = GoodImgs.objects.all()
    serializer_class = GoodImgsSerializer


class UserViewSets1(viewsets.GenericViewSet, mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin):
    """
    声明用户资源类  用户操作 获取个人信息 更新个人信息 删除账户
    扩展出action路由  用户操作：创建账户
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @action(methods=["POST"], detail=False)
    def regist(self, request):
        seria = UserRegistSerializer(data=request.data)
        seria.is_valid(raise_exception=True)
        seria.save()
        return Response(seria.data, status=status.HTTP_201_CREATED)


class UserViewSets(viewsets.GenericViewSet, mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin):
    """
    声明用户资源类  用户操作 获取个人信息 更新个人信息 删除账户
    扩展出action路由  用户操作：创建账户
    """
    queryset = User.objects.all()

    # serializer_class = UserSerializer
    def get_serializer_class(self):
        print('action代表http方法', self.action)
        if self.action == 'create':
            return UserRegistSerializer
        return UserSerializer


class OrderViewSets(viewsets.ModelViewSet):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer

    # permission_classes = [OrdersPermission]
    def get_permissions(self):
        """
        超级管理员只可以展示所有订单
        普通用户 可以创建修改订单  不可以操作其他用户订单
        :return:
        """
        print("http方法为：", self.action)
        if self.action == 'create':
            return [permissions.IsAuthenticated()]
        elif self.action == 'update' or self.action == 'partial_update' or self.action == 'retrieve' or self.action == 'destroy':
            return [mypermissions.OrdersPermission()]
        else:
            return [permissions.IsAdminUser()]


# http方法                       混合类关键字             action关键字
# get列表                           List                      get
# post创建对象                      Create                   create
# get单个对象                       retrieve                retrieve
# put修改对象提供全属性             update                   update
# patch 修改对象提供部分属性        update                 partial_update
# delete 删除对象                   destroy                  destroy
from urllib import request
from urllib import parse

import urllib.request
import time
import hashlib
import random


def getnums():
    s = ""
    for i in range(6):
        s += str(random.randrange(0, 9))
    return s


@api_view(['POST'])
def sendmsg(req):
    try:
        print(req.data)
        """
        向数据库中写入数据 
        手机号 验证码  发送时间
        """
        print("python demo starting...")

        url = "https://openapi.miaodiyun.com/distributor/sendSMS"
        accountSid = "5ddd6bfa5d1195eb16d160e64d5dbb8c"
        to = req.data["telephone"]
        templateid = "241019"
        param = getnums()
        print("发送验证码为", param)
        auth_token = "cc8baf390e4f5e8ea9ee4a7df9cbd464"

        t = time.time()
        timestamp = str((int(round(t * 1000))))
        sig = accountSid + auth_token + timestamp
        m1 = hashlib.md5()
        m1.update(sig.encode("utf-8"))
        sig = m1.hexdigest()

        data = "accountSid=" + accountSid + "&to=" + to + "&templateid=" + templateid + "&param=" + param + "&timestamp=" + timestamp + "&sig=" + sig
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36'
        }
        data = str.encode(data)

        print("data sent to SMS server is:")
        print(data)
        req = request.Request(url, headers=headers, data=data)  # POST方法
        page = request.urlopen(req).read()
        page = page.decode('utf-8')
        print("response from SMS server is:")
        print(page)

        print("python demo finished")

        ver = Verify()
        ver.code = param
        ver.telephone = to
        ver.save()

        return Response("发送成功")


    except Exception as e:
        print(e)
        return Response(status=status.HTTP_400_BAD_REQUEST)
