from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.mixins import UpdateModelMixin, RetrieveModelMixin
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from apps.hrm.models import Employee
from apps.hrm.serializers import EmployeeSerializer, FaceLoginSerializer
import face_recognition
from django.conf import settings
from django.core.cache import cache
import logging
from rest_framework.generics import CreateAPIView
from rest_framework import status
from rest_framework_simplejwt.tokens import RefreshToken

from apps.system.models import User
logger = logging.getLogger('log')


def load_face_data(username:int, path:str):
    """
    将某用户face_encoding加载进缓存
    """
    face_datas = cache.get_or_set('face_datas', {}, timeout=None)
    photo_path = settings.BASE_DIR + path
    picture_of_me = face_recognition.load_image_file(photo_path)
    my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
    face_datas[username] = my_face_encoding
    cache.set('face_datas', face_datas, timeout=None)
    return my_face_encoding

# Create your views here.
class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, RetrieveModelMixin, GenericViewSet):
    """
    员工详细信息
    """
    perms_map = {'get': '*', 'put': 'employee_update'}
    queryset = Employee.objects.all()
    serializer_class = EmployeeSerializer
    ordering = ['-pk']
    
    def perform_update(self, serializer):
        instance = serializer.save(update_by = self.request.user)
        try:
            photo_path = settings.BASE_DIR + instance.photo
            picture_of_me = face_recognition.load_image_file(photo_path)
            my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
            instance.face_data = my_face_encoding.tolist()
            instance.save()
        except:
            logger.error('人脸识别出错')

import uuid
import base64
import os

def tran64(s):
    missing_padding = len(s) % 4
    if missing_padding != 0:
        s = s+'='* (4 - missing_padding)
    return s

class FaceLogin(CreateAPIView):
    authentication_classes = []
    permission_classes = []
    serializer_class = FaceLoginSerializer


    def create(self, request, *args, **kwargs):
        """
        人脸识别登录
        """
        # serializer = FaceLoginSerializer(data=request.data)
        # serializer.is_valid(raise_exception=True)
        filename = str(uuid.uuid4())
        filepath = settings.BASE_DIR +'/temp/' + filename +'.png'
        with open(filepath, 'wb') as f:
            data = tran64(request.data.get('base64').replace(' ', '+'))
            f.write(base64.urlsafe_b64decode(data))
       # picture_of_me = face_recognition.load_image_file(settings.BASE_DIR +'/temp/me.png')
       # my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
        #results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2)
        try:
            unknown_picture = face_recognition.load_image_file(filepath)
            unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0]
            os.remove(filepath)
        except:
            return Response('头像解码失败', status=status.HTTP_400_BAD_REQUEST)

        # 匹配人脸库
        user_faces = Employee.objects.filter(face_data__isnull=False, user__is_active=True).values('user', 'face_data')
        user_l = []
        face_l = []
        for i in user_faces:
            user_l.append(i['user'])
            face_l.append(i['face_data'])

        results = face_recognition.compare_faces(face_l, unknown_face_encoding, tolerance=0.5)
        for index, value in enumerate(results):
            if value:
                # 识别成功
                user = User.objects.get(id=user_l[index])
                refresh = RefreshToken.for_user(user)
                return Response({
                    'refresh': str(refresh),
                    'access': str(refresh.access_token),
                    'username':user.username
                })      
        return Response('未找到对应用户', status=status.HTTP_400_BAD_REQUEST)