# coding=utf-8
import traceback
import json
import datetime
from django.db.models import Q
from rest_framework.decorators import action
from django.db import transaction
from rest_framework.views import APIView
from rest_framework.serializers import ValidationError
from utils.permission import permission_required, isLogin, check_permission
from django.contrib.auth.models import Group, Permission
from rest_framework_jwt.views import ObtainJSONWebToken, RefreshJSONWebToken
from utils import response_error, response_ok
from django.contrib.auth import get_user_model

User = get_user_model()
from apps.account.serializers import JWTSerializer, EmployeeSerializer, \
    WechatLoginSerializer, WechatBindSerializer
from utils.custom_modelviewset import CustomModelViewSet
from apps.account.filters import UserFilter
from apps.log.models import BizLog
from utils.exceptions import CustomError
from apps.account.models import CustomerWechat
from utils.wx.WXBizDataCrypt import WXBizDataCrypt

class LoginView(ObtainJSONWebToken):
    serializer_class = JWTSerializer

    def post(self, request, *args, **kwargs):
        try:
            ser = self.serializer_class(data=request.data)
            ser.request = request
            if ser.is_valid(raise_exception=True):
                return response_ok(ser.validated_data)
        except ValidationError as e:
            return response_error(e.detail['error'][0])
        except CustomError as e:
            return response_error(str(e))

class RefreshTokenView(RefreshJSONWebToken):

    def post(self, request, *args, **kwargs):
        try:
            ser = self.serializer_class(data=request.data)
            if ser.is_valid(raise_exception=True):
                return response_ok({'token': ser.validated_data['token']})
        except ValidationError as e:
            return response_ok({'error':True})
        except CustomError as e:
            return response_error(str(e))

class ChangePassword(APIView):

    def post(self, request, *args, **kwargs):
        id = request.GET.get('id')
        data = json.loads(request.body)
        try:
            with transaction.atomic():
                user = User.objects.filter(id=id).first()
                if not user:
                    raise CustomError(u'用户信息错误，请刷新重试！')
                user.change_password(data['new_password'], data['confirm_password'], data['old_password'])
                BizLog.objects.addnew(request.user, BizLog.UPDATE, u"修改密码[%s],id=%d" % (user.username, user.id))
        except CustomError as e:
            return response_error(str(e))
        except Exception as e:
            traceback.print_exc()
            return response_error(u'保存失败！')
        return response_ok()


class EmployeeViewSet(CustomModelViewSet):
    permission_classes = [isLogin, ]
    queryset = User.objects.filter(type=User.EMPLOYEE)
    serializer_class = EmployeeSerializer

    def filter_queryset(self, queryset):
        queryset = queryset.filter()
        user = self.request.user
        queryset = queryset.filter(
            Q(id=user.id) |
            Q(create_user=user)
        )

        f = UserFilter(self.request.GET, queryset=queryset)
        return f.qs

    def perform_create(self, serializer):
        super(EmployeeViewSet, self).perform_create(serializer)
        instance = serializer.instance
        validated_data = serializer.validated_data
        BizLog.objects.addnew(self.request.user, BizLog.INSERT,
                              u'添加用户[%s]，id=%d' % (instance.name, instance.id), validated_data)

    def perform_update(self, serializer):
        super(EmployeeViewSet, self).perform_update(serializer)
        instance = serializer.instance
        validated_data = serializer.validated_data
        BizLog.objects.addnew(self.request.user, BizLog.UPDATE,
                              u'修改用户[%s]，id=%d' % (instance.name, instance.id), validated_data)


class SetUserInfoView(APIView):
    permission_classes = [isLogin, ]

    def post(self, request, *args, **kwargs):
        appid = request.POST.get('appid')
        openid = request.POST.get('openid')
        encryptedData = request.POST.get('encryptedData')
        iv = request.POST.get('iv')

        customer_wechat = CustomerWechat.objects.filter(openid=openid, wechat_app__authorizer_appid=appid).first()
        if not customer_wechat:
            raise CustomError(u'未找到相应的微信客户！')

        employee = self.request.user
        if customer_wechat.customer and customer_wechat.customer != employee:
            # 用户用手机号、密码登录后，同步微信信息时，customer可能会不一样
            #张三、李四都是注册、同步用户。 张三的账号，在李四小程序上登录，同步的李四微信信息，可能会两个用户不同。
            raise CustomError(u'该微信已同步其他客户！')
        if not customer_wechat.customer:
            customer_wechat.customer = employee
            customer_wechat.save()
        pc = WXBizDataCrypt(appid, customer_wechat.session_key)
        result = pc.decrypt(encryptedData, iv)
        with transaction.atomic():
            if employee.name == employee.tel:
                employee.name = result['nickName']
            employee.gender = result['gender']
            employee.face = result['avatarUrl']
            employee.save()
        return response_ok({'face':employee.face,'name':employee.name})

class WxLoginView(APIView):
    serializer_class = WechatLoginSerializer

    def post(self, request, *args, **kwargs):
        ser = self.serializer_class(data=request.data)
        if ser.is_valid():
            return response_ok(ser.validated_data)
        else:
            return response_error('参数错误')


class WxBindView(APIView):
    serializer_class = WechatBindSerializer

    def post(self, request, *args, **kwargs):
        ser = self.serializer_class(data=request.data)
        if ser.is_valid():
            return response_ok(ser.validated_data)
        else:
            return response_error('参数错误')
