# -*- coding: utf-8 -*-
"""
@Time ： 2020/12/16 8:44
@Auth ： Locky
@File ：CloudTransfer.py
@IDE ：PyCharm
"""
import json
import time

from django.db import transaction
from django.db.models import Q
from django.views.generic.base import View

from Model.models import Device_User, Device_Info, Order_Model, UID_Bucket, StsCrdModel, VodHlsModel, Unused_Uid_Meal, \
    VodBucketModel, UnicomDeviceInfo, LogModel, UidPushModel, AiService, UidSetModel, UserFamily, FamilyRoomDevice, \
    UserAudioVideoPush, GatewayPush
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Service.CommonService import CommonService
from Service.ModelService import ModelService
from Service.VodHlsService import SplitVodHlsObject
from Ansjer.config import LOGGER


class cloudTestView(View):

    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        return self.validation(request.GET, request, operation)

    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        return self.validation(request.POST, request, operation)

    def validation(self, request_dict, request, operation):
        lang = request_dict.get('lang', None)
        response = ResponseObject(lang) if lang else ResponseObject()
        if operation is None:
            return response.json(444, 'error path')
        else:
            token = request_dict.get('token', None)
            # 设备主键uid
            tko = TokenObject(token)
            if tko.code != 0:
                return response.json(tko.code)
            userID = tko.userID
            if operation == 'deviceTransfer':
                return self.deviceTransfer(request, request_dict, response)
            elif operation == 'mealTransfer':
                return self.mealTransfer(request, request_dict, response, userID)
            elif operation == 'expireMeal':
                return self.expireMeal(request_dict, response)

    def deviceTransfer(self, request, request_dict, response):
        # 设备转移,一个用户下的设备转移到另一个用户
        oldUserID = request_dict.get("oldUserID", None)
        username = request_dict.get("username", None)
        uid = request_dict.get('uid', None)
        lang = request_dict.get('lang', None)
        now_time_stamp = int(time.time())
        now_time = CommonService.timestamp_to_str(now_time_stamp)

        try:
            # 查询该userID下是否存在此设备
            old_deviceInfo_qs = Device_Info.objects.filter(userID_id=oldUserID, UID=uid, isExist=1) \
                .values('isShare', 'vodPrimaryUserID', 'serial_number', 'userID__username', 'id')
            if not old_deviceInfo_qs.exists():
                return response.json(10008)
            old_user_name = old_deviceInfo_qs[0]['userID__username']
            newUserID = ModelService.get_userID_byname(username)  # 根据username获取userID
            if newUserID is None:  # 没有此用户
                return response.json(104)
            if newUserID == oldUserID:  # 新用户的userID跟旧用户的一样
                return response.json(10009)
            # 分享的设备不能转移
            isShare = old_deviceInfo_qs[0]['isShare']
            if isShare:
                return response.json(10015)
            # 旧用户是设备主用户才能转移
            vodPrimaryUserID = old_deviceInfo_qs[0]['vodPrimaryUserID']
            if vodPrimaryUserID != '' and vodPrimaryUserID != oldUserID:
                return response.json(10037)

            # uid_mian = UIDMainUser.objects.filter(UID=uid).values('UID', 'user_id')
            # if uid_mian.exists():
            #     vodPrimaryUserID = uid_mian[0]['user_id']
            #     if vodPrimaryUserID != '' and vodPrimaryUserID != oldUserID:
            #         return response.json(10037)

            # 判断新用户是否已有此设备
            new_deviceInfo_qs = Device_Info.objects.filter(userID_id=newUserID, UID=uid, isExist=1)
            if new_deviceInfo_qs.exists():
                return response.json(10009)

            # 旧用户如果开启云存自动续费，不可转移
            hasCycle = Order_Model.objects.filter(userID=oldUserID, UID=uid)
            hasCycle = hasCycle.filter(~Q(agreement_id=''))
            if hasCycle.exists():
                return response.json(10056)

            # 获取新设备的username、userEmail
            newUserQs = Device_User.objects.get(userID=newUserID)
            newUserName = newUserQs.username
            newUserEmail = newUserQs.userEmail
            vodPrimaryUserID = newUserID
            vodPrimaryMaster = newUserName

            # 获取用户家庭信息
            device_id = old_deviceInfo_qs[0]['id']
            user_family_qs = UserFamily.objects.filter(user_id=newUserID).values('id')
            with transaction.atomic():
                serial_number = old_deviceInfo_qs[0]['serial_number']
                # 删除旧用户此设备的uid_push数据
                UidPushModel.objects.filter(userID_id=oldUserID, uid_set__uid=uid).delete()
                # 更新旧设备的userID,设备添加时间,关闭推送消息提醒
                old_deviceInfo_qs.update(userID=newUserID, data_joined=now_time, NotificationMode=0)
                # 更新设备的主用户信息
                Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID=vodPrimaryUserID,
                                                           vodPrimaryMaster=vodPrimaryMaster,
                                                           primaryUserID=vodPrimaryUserID,
                                                           primaryMaster=vodPrimaryMaster)
                VodHlsModel.objects.filter(uid=uid).delete()
                # 删除vod_hls分表数据
                split_vod_hls_obj = SplitVodHlsObject()
                split_vod_hls_obj.del_vod_hls_data(uid=uid)
                if not serial_number:
                    serial_number = CommonService.query_serial_with_uid(uid)
                u_dev_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number)
                if u_dev_info_qs.exists():
                    now_time = int(time.time())
                    u_dev_info_qs.update(user_id=newUserID, updated_time=now_time)
                # 转移设备到家庭
                if user_family_qs.exists():
                    family_id = user_family_qs[0]['id']

                else:
                    family_name = newUserName if newUserName else newUserEmail
                    family_name = family_name + "的家" if lang == 'cn' else family_name + " home"
                    user_family = UserFamily.objects.create(user_id=newUserID, name=family_name,
                                                            updated_time=now_time_stamp,
                                                            created_time=now_time_stamp)
                    family_id = user_family.id
                family_device = FamilyRoomDevice.objects.filter(family_id=family_id, category=1).values('category_sort')
                category_sort = family_device[0]['category_sort'] if family_device.exists() else 0
                old_family_device = FamilyRoomDevice.objects.filter(device_id=device_id)
                if old_family_device.exists():
                    old_family_device.update(family_id=family_id, category_sort=category_sort,
                                             updated_time=now_time_stamp, room_id=0, sort=0)
                else:
                    FamilyRoomDevice.objects.create(family_id=family_id, category=1, device_id=device_id,
                                                    updated_time=now_time_stamp, created_time=now_time_stamp)

                # 双通话键设备
                UserAudioVideoPush.objects.filter(uid=uid).update(buttonUser1=newUserID, buttonUser2=newUserID,
                                                                  updated_time=int(time.time()))
                self.add_user_phone_push(newUserID, uid)

                # 记录设备转移日志
                ip = CommonService.get_ip_address(request)
                content = json.loads(json.dumps(request_dict))
                log = {
                    'ip': ip,
                    'user_id': 1,
                    'status': 200,
                    'time': int(time.time()),
                    'url': 'cloudTransfer/deviceTransfer',
                    'content': json.dumps(content),
                    'operation': '用户{}的设备{}转移给了用户{}'.format(old_user_name, uid, newUserName),
                }
                LogModel.objects.create(**log)
                # UIDMainUser.objects.filter(UID=uid).delete()
                # uid_main_dict = {
                #     'UID': uid,
                #     'user_id': newUserID
                # }
                # UIDMainUser.objects.create(**uid_main_dict)

        except Exception as e:
            # print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
        else:
            return response.json(0)

    @classmethod
    def add_user_phone_push(cls, userID, UID):
        """
        根据userID查询用户手机推送令牌信息
        """
        try:
            uid_set_qs = UidSetModel.objects.filter(uid=UID).values('id')
            if uid_set_qs.exists():
                uid_set_id = uid_set_qs[0]['id']
                now_time = int(time.time())
                uid_push_qs = UidPushModel.objects.filter(userID=userID).values_list('appBundleId', 'app_type',
                                                                                     'push_type', 'token_val',
                                                                                     'jg_token_val', 'm_code',
                                                                                     'lang', 'tz').order_by('-updTime')
                count = 0
                if uid_push_qs.exists():
                    for item in set(list(uid_push_qs)):
                        UidPushModel.objects.create(userID_id=userID, appBundleId=item[0], app_type=item[1],
                                                    push_type=item[2], token_val=item[3], jg_token_val=item[4],
                                                    m_code=item[5], lang=item[6], tz=item[7], addTime=now_time,
                                                    updTime=now_time, uid_set_id=uid_set_id)
                        count += 1
                        if count >= 4:
                            break
                else:
                    gateway_push_qs = GatewayPush.objects.filter(user_id=userID, logout=False).values(
                        'app_bundle_id', 'm_code', 'app_type', 'push_type', 'token_val', 'lang', 'jg_token_val',
                        'tz').order_by('-id')
                    for item in gateway_push_qs:
                        UidPushModel.objects.create(userID_id=userID, appBundleId=item['app_bundle_id'],
                                                    app_type=item['app_type'], addTime=now_time,
                                                    push_type=item['push_type'], updTime=now_time,
                                                    token_val=item['token_val'], uid_set_id=uid_set_id,
                                                    jg_token_val=item['jg_token_val'], lang=item['lang'],
                                                    m_code=item['m_code'], tz=item['tz'])
                        count += 1
                        if count >= 4:
                            break

        except Exception as e:
            LOGGER.error('添加用户设备推送异常,uid:{},error_line:{}, error_msg:{}'
                         .format(UID, e.__traceback__.tb_lineno, repr(e)))

    def mealTransfer(self, request, request_dict, response, userID):
        # 云存套餐转移,同一用户下不同设备间的云存套餐转移
        old_uid = request_dict.get("old_uid", None)
        new_uid = request_dict.get("new_uid", None)
        nowTime = int(time.time())

        try:
            # 查询两个UID是否在同一账号下
            old_deviceInfo_qs = Device_Info.objects.filter(userID_id=userID, UID=old_uid).values('isExist',
                                                                                                 'vodPrimaryUserID',
                                                                                                 'userID__username')
            new_deviceInfo_qs = Device_Info.objects.filter(userID_id=userID, UID=new_uid).values('isExist')
            if not (old_deviceInfo_qs.exists() and new_deviceInfo_qs.exists()):
                return response.json(10010)
            username = old_deviceInfo_qs[0]['userID__username']

            # 不是主用户无法转移
            vodPrimaryUserID = old_deviceInfo_qs[0]['vodPrimaryUserID']
            if vodPrimaryUserID != '' and vodPrimaryUserID != userID:
                return response.json(10038)
            vodPrimaryUserID = userID
            vodPrimaryMaster = ModelService.get_user_name(userID)

            new_isExist = new_deviceInfo_qs[0]['isExist']
            if not new_isExist:
                return response.json(10011)

            # 查询转出设备正在使用的套餐
            old_using_uid_bucket = UID_Bucket.objects.filter(uid=old_uid, endTime__gte=nowTime).values('id',
                                                                                                       'bucket_id',
                                                                                                       'has_unused',
                                                                                                       'bucket__content').order_by(
                'addTime')
            if not old_using_uid_bucket.exists():
                return response.json(10013)
            bucket_content = old_using_uid_bucket[0]['bucket__content']

            # 免费存储桶不可转移
            old_vod_bucket_id = old_using_uid_bucket[0]['bucket_id']
            is_free = VodBucketModel.objects.get(id=old_vod_bucket_id).is_free
            if is_free == 1:
                return response.json(10012)

            # 查询转入设备是否存在正在使用的套餐和未使用的套餐
            new_using_uid_bucket = UID_Bucket.objects.filter(uid=new_uid, endTime__gte=nowTime)
            new_unused_uid_bucket = Unused_Uid_Meal.objects.filter(uid=new_uid)
            if new_using_uid_bucket.exists() or new_unused_uid_bucket.exists():
                return response.json(10014)
            old_ai_service = AiService.objects.filter(uid=old_uid, endTime__gte=nowTime, use_status=1).values('id',
                                                                                                              'detect_interval',
                                                                                                              'detect_status',
                                                                                                              'detect_group')
            new_ai_service = AiService.objects.filter(uid=new_uid, endTime__gte=nowTime, use_status=1)
            if new_ai_service.exists():  # 转入设备有开通AI功能，不能转
                return response.json(10014)
            new_uid_set = UidSetModel.objects.filter(uid=new_uid).values('is_ai')
            if old_ai_service.exists() and new_uid_set[0]['is_ai'] == 2:  # 转出设备有开通AI，但是转入设备不支持AI，不能转
                return response.json(10016)
            with transaction.atomic():
                # 如果转出设备有未使用套餐,更改第一个未使用套餐为正在使用
                if old_using_uid_bucket[0]['has_unused'] == 1:
                    old_unused_uid_bucket = Unused_Uid_Meal.objects.filter(uid=old_uid).values('id', 'channel',
                                                                                               'bucket_id',
                                                                                               'addTime', 'expire',
                                                                                               'is_ai',
                                                                                               'order_id')
                    count = old_unused_uid_bucket.count()
                    unused = old_unused_uid_bucket[0]
                    has_unused = 1 if count > 1 else 0  # 如果存在不止一个未使用套餐,has_unused=1
                    endTime = CommonService.calcMonthLater(unused['expire'])
                    data_dict = {
                        'uid': old_uid,
                        'channel': unused['channel'],
                        'bucket_id': unused['bucket_id'],
                        'addTime': unused['addTime'],
                        'endTime': endTime,
                        'updateTime': nowTime,
                        'status': 1,
                        'use_status': 1,
                        'has_unused': has_unused
                    }
                    UID_Bucket.objects.create(**data_dict)  # 正在使用套餐表添加数据
                    Unused_Uid_Meal.objects.filter(uid=old_uid).first().delete()  # 删除未使用套餐表中的数据
                    if unused['is_ai']:  # 开通AI服务
                        AiService.objects.create(uid=old_uid, channel=unused['channel'],
                                                 detect_status=old_ai_service[0]['detect_status'],
                                                 addTime=nowTime, updTime=nowTime, endTime=endTime, use_status=1,
                                                 orders_id=unused['order_id'],
                                                 detect_group=old_ai_service[0]['detect_group'],
                                                 detect_interval=old_ai_service[0]['detect_interval'])
                # 更新转入设备的主用户信息
                Device_Info.objects.filter(UID=new_uid).update(vodPrimaryUserID=vodPrimaryUserID,
                                                               vodPrimaryMaster=vodPrimaryMaster)
                # 更新正在使用套餐的uid,重置拥有未使用套餐
                old_using_uid_bucket_id = old_using_uid_bucket[0]['id']
                UID_Bucket.objects.filter(id=old_using_uid_bucket_id).update(uid=new_uid, has_unused=0)
                StsCrdModel.objects.filter(uid=old_uid).delete()  # 删除转出设备stscrd表关联数据
                # 转移AI服务
                if old_ai_service.exists() and new_uid_set[0]['is_ai'] != 2:
                    AiService.objects.filter(id=old_ai_service[0]['id']).update(uid=new_uid, detect_status=0,
                                                                                detect_group='', detect_interval=60)
                    msg = {'commandType': 'AIDisable'}
                    thing_name = CommonService.query_serial_with_uid(old_uid)  # 存在序列号则为使用序列号作为物品名
                    topic_name = 'ansjer/generic/{}'.format(thing_name)
                    req_success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
                    if not req_success:
                        return response.json(10044)

                # 记录套餐转移日志
                ip = CommonService.get_ip_address(request)
                content = json.loads(json.dumps(request_dict))
                log = {
                    'ip': ip,
                    'user_id': 1,
                    'status': 200,
                    'time': int(time.time()),
                    'url': 'cloudTransfer/mealTransfer',
                    'content': json.dumps(content),
                    'operation': '用户{}的设备{}的套餐{}转移给设备{}'.format(username, old_uid, bucket_content, new_uid),
                }
                LogModel.objects.create(**log)
            return response.json(0)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def expireMeal(self, request_dict, response):
        UID_Bucket_id = request_dict.get("UID_Bucket_id", None)
        # 修改endTime让当前设备套餐过期
        if UID_Bucket_id:
            try:
                UID_Bucket.objects.filter(id=UID_Bucket_id).update(use_status=2)
            except Exception as e:
                # print(e)
                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            else:
                return response.json(0)
        response.json(404)
