from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
import logging

from common.third_party_api.qucloud.clients import cos_client
from rest_framework import status
from common.accounts.models import Users, Accounts, UserEnterprise, Enterprise
from common.utils.return_structure import general_message, error_message
from rest_framework.response import Response
from common.utils.service_code import VERIFICATION_ERROR, PASSWORD_WRONG
from console.user_center.serializers import UserInfoSerializer, \
    CustInfoSerializer, FileUploadSerializers, MiniUserInfoSerializer, \
    UserDeleteSerializer, AccountUpdateSerializer,\
    AccountUpdateHeadImageSerializer
from django.db import transaction
from common.utils.serializers import serializer_assembly
from common.utils.service_code import PARAMETER_ERROR, SERVICE_ERROR
from django.conf import settings
from common.utils.views import BaseApiView
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import GenericAPIView
from rest_framework.parsers import FileUploadParser, MultiPartParser
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from uuid import uuid4
from django.contrib import auth
from console.customer.models import CustomerAdmin

from common.utils.exceptions import ServiceHandleException
from common.utils.service_code import THIRD_PARTY_API_ERROR

Logger = logging.getLogger('')
file_path = settings.UPLOAD_FILE_PATH


class FileUploadView(GenericAPIView):
    serializer_class = FileUploadSerializers
    permission_classes = (IsAuthenticated, )
    authentication_classes = (JSONWebTokenAuthentication, )
    parser_classes = (
        MultiPartParser,
        FileUploadParser,
    )
    renderer_classes = (JSONRenderer, BrowsableAPIRenderer)

    def post(self, request, *args, **kwargs):
        file_id = str(uuid4())

        if not request.FILES or not request.FILES.get('file'):
            return Response({"msg": "请指定需要上传的文件"},
                            status=status.HTTP_400_BAD_REQUEST)
        file = request.FILES.get('file')
        serializer = FileUploadSerializers(data=request.data)
        serializer.is_valid(raise_exception=True)
        bucket = settings.CLOUD_COS.UPLOAD_BUCKET
        key = file_id + "." + file.name.split(".")[-1]
        suffix = file.name.split(".")[-1]
        if suffix.lower() not in ["png", "jpg", "jpeg"]:
            return Response(
                error_message(code=VERIFICATION_ERROR,
                              msg_show="只支持png、jpg和jpeg格式图片"))
        response = cos_client.put_object(Bucket=bucket,
                                         Body=file,
                                         Key=key,
                                         EnableMD5=False)
        url = cos_client._conf.uri(bucket=bucket, path=key)
        if response.get("ETag"):
            return Response({"url": url}, status=status.HTTP_200_OK)
        else:
            raise ServiceHandleException(msg_show="上传失败",
                                         msg="upload error",
                                         code=THIRD_PARTY_API_ERROR)


class UserInfoGet(BaseApiView):
    '''
    个人中心
    '''
    serializer_class = UserInfoSerializer

    @swagger_auto_schema(operation_description="个人中心-获取个人信息",
                         manual_parameters=[
                             openapi.Parameter("custom_id",
                                               openapi.IN_QUERY,
                                               description="客户唯一标识",
                                               required=True,
                                               tags=["user_center"],
                                               type=openapi.TYPE_STRING)
                         ],
                         tags=["user_center"],
                         responses={
                             status.HTTP_200_OK:
                             serializer_assembly(UserInfoSerializer,
                                                 many=False)
                         })
    def get(self, request, *args, **kwargs):
        serializer = UserInfoSerializer(data=self.user)
        serializer.is_valid(raise_exception=True)
        return Response(data=general_message(msg_show="数据请求成功",
                                             bean=serializer.data),
                        status=status.HTTP_200_OK)

    @swagger_auto_schema(operation_description="个人中心-修改个人信息",
                         request_body=UserInfoSerializer,
                         tags=["user_center"],
                         responses={status.HTTP_200_OK: {}})
    def put(self, request, *args, **kwargs):
        data = request.data
        user = self.user
        try:
            name = data['name']
        except Exception as e:
            print(e)
            name = user.nickname
        try:
            phone = data['phone']
        except Exception as e:
            print(e)
            phone = user.phone
        try:
            email = data['email']
        except Exception as e:
            print(e)
            email = user.email
        if user:
            user.phone = str(phone)
            user.email = str(email)
            user.nickname = str(name)
            user.save()
            try:
                password = str(data['password'])
                accounts = Accounts.objects.filter(id=user.account.id)
                if accounts:
                    accounts = accounts.first()
                    accounts.set_password(password)
                    accounts.save()
            except Exception as e:
                print(e)
            return Response(data=general_message(msg_show="修改成功"))
        return Response(
            data=error_message(code=VERIFICATION_ERROR, msg_show="修改失败"))

    @swagger_auto_schema(operation_description="删除账号信息",
                         request_body=UserDeleteSerializer,
                         tags=["user_center"],
                         responses={status.HTTP_200_OK: {}})
    @transaction.atomic
    def delete(self, request, *args, **kwargs):
        custom_id = request.custom_id
        serializer = UserDeleteSerializer(data=custom_id)
        if serializer.is_valid():
            try:
                sid = transaction.savepoint()
                user = Users.objects.filter(id=custom_id).first()
                user.delete()
                user.save()
                Accounts.objects.filter(id=user.account).delete()
                transaction.savepoint_commit(sid)
                return Response(data=general_message(msg_show="删除成功"))
            except Exception as e:
                print(e)
                transaction.rollback(sid)
                return Response(
                    data=error_message(code=SERVICE_ERROR, msg_show="删除成功"))
        else:
            return Response(
                data=error_message(code=VERIFICATION_ERROR, msg_show="删除成功"))


class MiniUserInfo(BaseApiView):
    '''
    小程序-个人中心
    '''
    serializer_class = UserInfoSerializer

    @swagger_auto_schema(operation_description="小程序-我",
                         tags=["mini_user_center"],
                         responses={
                             status.HTTP_200_OK:
                             serializer_assembly(UserInfoSerializer,
                                                 many=False)
                         })
    def get(self, request, *args, **kwargs):
        serializer = MiniUserInfoSerializer(data=self.user_enterprise)
        serializer.is_valid(raise_exception=True)
        return Response(data=general_message(msg_show="数据请求成功",
                                             bean=serializer.data),
                        status=status.HTTP_200_OK)


class MiniUserPic(BaseApiView):
    '''
    小程序-更换头像
    '''
    serializer_class = AccountUpdateHeadImageSerializer

    @swagger_auto_schema(operation_description="小程序-更换头像",
                         tags=["mini_user_center"],
                         responses={
                             status.HTTP_200_OK:
                             serializer_assembly(UserInfoSerializer,
                                                 many=False)
                         })
    def post(self, request, *args, **kwargs):
        file_id = str(uuid4())

        if not request.FILES or not request.FILES.get('file'):
            return Response({"msg": "请指定需要上传的文件"},
                            status=status.HTTP_400_BAD_REQUEST)
        file = request.FILES.get('file')
        serializer = FileUploadSerializers(data=request.data)
        serializer.is_valid(raise_exception=True)
        bucket = settings.CLOUD_COS.UPLOAD_BUCKET
        key = file_id + "." + file.name.split(".")[-1]
        suffix = file.name.split(".")[-1]
        if suffix.lower() not in ["png", "jpg", "jpeg"]:
            return Response(
                error_message(code=VERIFICATION_ERROR,
                              msg_show="只支持png、jpg、jpeg格式的图片"))
        response = cos_client.put_object(Bucket=bucket,
                                         Body=file,
                                         Key=key,
                                         EnableMD5=False)
        url = cos_client._conf.uri(bucket=bucket, path=key)
        if response.get("ETag"):
            return Response({"url": url}, status=status.HTTP_200_OK)
        else:
            raise ServiceHandleException(msg_show="上传失败",
                                         msg="upload error",
                                         code=THIRD_PARTY_API_ERROR)


class ChangeHeadImg(BaseApiView):
    '''
    小程序-更换头像
    '''
    serializer_class = AccountUpdateHeadImageSerializer

    @swagger_auto_schema(operation_description="小程序-更换头像",
                         tags=["mini_user_center"],
                         responses={
                             status.HTTP_200_OK:
                             serializer_assembly(UserInfoSerializer,
                                                 many=False)
                         })
    def put(self, request, *args, **kwargs):
        serializer = self.get_serializer(request.user, data=request.data)
        serializer.is_valid()
        serializer.save()
        return Response(general_message("更换成功"))


class MiniUserName(BaseApiView):
    '''
    小程序-更换昵称
    '''
    @swagger_auto_schema(operation_description="小程序-更换昵称",
                         tags=["mini_user_center"],
                         responses={
                             status.HTTP_200_OK:
                             serializer_assembly(UserInfoSerializer,
                                                 many=False)
                         })
    def post(self, request, *args, **kwargs):
        data = request.data
        user = self.user
        name = data['name']
        if not user:
            raise ValueError("无用户信息", code=PARAMETER_ERROR)
        user.nickname = name
        try:
            user.save()
            return Response(data=general_message(msg_show="修改成功"))
        except Exception as e:
            print(e)
        return Response(
            data=error_message(code=VERIFICATION_ERROR, msg_show="修改失败"))


class MiniUserEname(BaseApiView):
    '''
    小程序-更换公司名
    '''
    serializer_class = UserInfoSerializer

    @swagger_auto_schema(operation_description="小程序-更换公司名",
                         tags=["mini_user_center"],
                         responses={
                             status.HTTP_200_OK:
                             serializer_assembly(UserInfoSerializer,
                                                 many=False)
                         })
    def post(self, request, *args, **kwargs):
        data = request.data
        user = self.user
        name = data['name']
        if not user:
            raise ValueError("无用户信息", code=PARAMETER_ERROR)
        ue = UserEnterprise.objects.filter(user_id=self.user.id)
        if not ue:
            raise ValueError("无用户对应的企业信息", code=PARAMETER_ERROR)
        enterprise = Enterprise.objects.filter(
            enterprise_id=ue.first().enterprise_id)
        if not enterprise:
            raise ValueError("无用户对应的企业信息", code=PARAMETER_ERROR)
        enterprise = enterprise.first()
        if user:
            enterprise.name = str(name)
            try:
                enterprise.save()
            except Exception as e:
                print(e)
            return Response(data=general_message(msg_show="修改成功"))
        return Response(
            data=error_message(code=VERIFICATION_ERROR, msg_show="修改失败"))


class SetPassword(BaseApiView):
    '''
    小程序-更换密码
    '''
    @swagger_auto_schema(operation_description="小程序-更换密码",
                         tags=["mini_user_center"],
                         responses={
                             status.HTTP_200_OK:
                             serializer_assembly(UserInfoSerializer,
                                                 many=False)
                         })
    def put(self, request, *args, **kwargs):
        data = request.data
        try:
            password = str(data['password'])
            username = self.account.username
            oldpassword = str(data['oldpassword'])
            accounts = auth.authenticate(username=username,
                                         password=oldpassword)
            if accounts:
                accounts.set_password(password)
                accounts.save()
            else:
                return Response(data=error_message(code=PASSWORD_WRONG,
                                                   msg_show="修改失败,密码不正确"))
        except Exception as e:
            print(e)
            return Response(
                data=error_message(code=PASSWORD_WRONG, msg_show="修改失败,密码不正确"))
        return Response(data=general_message(msg_show="修改成功"))


class MiniUserPhone(BaseApiView):
    '''
    小程序-更换手机号码
    '''
    @swagger_auto_schema(operation_description="小程序-更换手机号",
                         tags=["mini_user_center"],
                         responses={
                             status.HTTP_200_OK:
                             serializer_assembly(UserInfoSerializer,
                                                 many=False)
                         })
    def post(self, request, *args, **kwargs):
        data = request.data
        user = self.user
        name = data['phone']
        if not user:
            raise ValueError("无用户信息", code=PARAMETER_ERROR)
        user.phone = name
        try:
            user.save()
            return Response(data=general_message(msg_show="修改成功"))
        except Exception as e:
            print(e)
        return Response(
            data=error_message(code=VERIFICATION_ERROR, msg_show="修改失败"))


class CssMe(BaseApiView):
    '''
    客服平台-个人中心
    '''
    serializer_class = UserInfoSerializer

    @swagger_auto_schema(operation_description="客服平台-个人中心-获取个人信息",
                         tags=["css_user_center"],
                         responses={
                             status.HTTP_200_OK:
                             serializer_assembly(UserInfoSerializer,
                                                 many=False)
                         })
    def get(self, request, *args, **kwargs):
        ca = CustomerAdmin.objects.filter(user_id=self.user.id)
        if not ca:
            return Response(
                data=error_message(code=VERIFICATION_ERROR, msg_show="无账号信息"))
        serializer = CustInfoSerializer(data=ca.first())
        serializer.is_valid(raise_exception=True)
        return Response(data=general_message(msg_show="数据请求成功",
                                             bean=serializer.data),
                        status=status.HTTP_200_OK)

    @swagger_auto_schema(operation_description="个人中心-修改个人信息",
                         request_body=UserInfoSerializer,
                         tags=["css_user_center"],
                         responses={status.HTTP_200_OK: {}})
    def put(self, request, *args, **kwargs):
        serializer = AccountUpdateSerializer(request.user, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(general_message("修改成功"))
        return Response(
            error_message(code=VERIFICATION_ERROR,
                          msg_show="修改失败",
                          msg=serializer.errors))
