# -*- encoding: utf-8 -*-
"""
@File    : GatewayFamilyMemberController.py
@Time    : 2022/5/25 10:21
@Author  : stephen
@Email   : zhangdongming@asj6.wecom.work
@Software: PyCharm
"""

import json
import time

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

from Ansjer.config import SERVER_DOMAIN
from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
from Model.models import UserFamily, FamilyMemberJoin, FamilyMember, SysMsgModel, FamilyMemberPermission, \
    Device_User, FamilyRoomDevice, FamilyRoom
from Object.RedisObject import RedisObject
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Service.CommonService import CommonService


# 家庭房间管理
class GatewayFamilyMemberView(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):
        token = request.META.get('HTTP_AUTHORIZATION')
        token = TokenObject(token)
        lang = request_dict.get('lang', None)
        response = ResponseObject(lang) if lang else ResponseObject(token.lang)
        if token.code != 0:
            return response.json(token.code)
        app_user_id = token.userID
        # 添加设备关联房间
        if operation == 'join':
            return self.member_join(app_user_id, request_dict, response)
        elif operation == 'join/page':
            return self.member_join_page(request_dict, response)
        elif operation == 'qrcode/generate':
            return self.family_generate_token(app_user_id, request_dict, response)
        elif operation == 'qrcode/check':
            return self.check_qrcode(request_dict, response)
        elif operation == 'join/info':
            return self.member_join_info(request_dict, response)
        elif operation == 'join/update':
            return self.user_join_confirm(request_dict, response)
        elif operation == 'del':
            return self.member_del(app_user_id, request_dict, response)
        elif operation == 'created':
            return self.family_created(app_user_id, request_dict, response)
        elif operation == 'del/home':
            return self.del_home(app_user_id, request_dict, response)
        elif operation == 'join/del':
            return self.member_join_del(app_user_id, request_dict, response)

    @classmethod
    def member_join_del(cls, app_user_id, request_dict, response):
        """
        删除最近联系人
        @param app_user_id:
        @param request_dict:
        @param response:
        @return:
        """
        join_ids = request_dict.get('joinIds', None)
        family_id = request_dict.get('familyId', None)
        if not join_ids:
            return response.json()
        is_owner = EquipmentFamilyView.get_family_owner(app_user_id, family_id)
        if not is_owner:
            return response.json(404)
        try:
            with transaction.atomic():
                items = join_ids.split(',')
                for item in items:
                    family_member_join_qs = FamilyMemberJoin.objects.filter(id=int(item))
                    if family_member_join_qs.exists():
                        sys_msg_qs = SysMsgModel.objects.filter(eventType=705, uid=item)
                        if sys_msg_qs.exists():
                            sys_msg_qs.delete()
                        family_member_join_qs.delete()
            return response.json(0)
        except Exception as e:
            print(e)
            return response.json(177, repr(e))

    @classmethod
    def del_home(cls, app_user_id, request_dict, response):
        """
        删除家庭
        @param app_user_id:
        @param request_dict:
        @param response:
        @return:
        """
        family_id = request_dict.get('familyId', None)
        if not family_id:
            return response.json(444)
        is_owner = EquipmentFamilyView.get_family_owner(app_user_id, family_id)
        if not is_owner:
            return response.json(404)
        family_id = int(family_id)
        try:
            with transaction.atomic():
                family_count = UserFamily.objects.filter(user_id=app_user_id).count()
                if family_count <= 1:
                    return response.json(10058)
                family_member_qs = FamilyMember.objects.filter(family_id=family_id, identity=0)
                if family_member_qs.exists():
                    return response.json(10057)
                family_room_dev_qs = FamilyRoomDevice.objects.filter(family_id=family_id)
                if family_room_dev_qs.exists():
                    return response.json(10057)
                family_room_qs = FamilyRoom.objects.filter(family_id=family_id)
                if family_room_qs.exists():
                    family_room_qs.delete()
                FamilyMember.objects.filter(family_id=family_id).delete()
                user_family_qs = UserFamily.objects.filter(id=family_id)
                if user_family_qs.exists():
                    user_family_qs.delete()
                    return response.json(0)
            return response.json(176)
        except Exception as e:
            print(e)
            return response.json(177, repr(e))

    @classmethod
    def family_created(cls, app_user_id, request_dict, response):
        """
        创建家庭
        @param app_user_id:
        @param request_dict:
        @param response:
        @return:
        """
        family_name = request_dict.get('familyName', None)
        if not family_name:
            return response.json(444)
        n_time = int(time.time())
        location = request_dict.get('location', '')
        room_names = request_dict.get('roomNames', None)
        user_family_qs = UserFamily.objects.filter(name=family_name, user_id=app_user_id)
        if user_family_qs.exists():
            return response.json(174)
        try:
            with transaction.atomic():
                member_permission_qs = FamilyMemberPermission.objects.filter(no='001').values('id')
                user_family = UserFamily.objects.create(user_id=app_user_id, name=family_name,
                                                        location=location,
                                                        updated_time=n_time,
                                                        created_time=n_time)
                if user_family.id:
                    device_user = Device_User.objects.get(userID=app_user_id)
                    permission_id = member_permission_qs.first()['id']
                    FamilyMember.objects.create(family_id=user_family.id, user_id=app_user_id,
                                                user_name=device_user.username, identity=1,
                                                permission_id=int(permission_id), sort=1, updated_time=n_time,
                                                created_time=n_time)
                if room_names:
                    names = room_names.split(',')
                    rooms = []
                    for index, item in enumerate(names):
                        rooms.append(FamilyRoom(
                            name=item,
                            family_id=user_family.id,
                            sort=index,
                            updated_time=n_time,
                            created_time=n_time
                        ))
                    FamilyRoom.objects.bulk_create(rooms)
                return response.json(0)
        except Exception as e:
            print(e)
            return response.json(177, repr(e))

    @classmethod
    def member_del(cls, app_user_id, request_dict, response):
        """
        成员删除或退出
        @param app_user_id:
        @param request_dict:
        @param response:
        @return:
        """
        member_id = request_dict.get('memberId', None)
        family_id = request_dict.get('familyId', None)
        if not family_id:
            return response.json(444)
        try:
            family_id = int(family_id)
            with transaction.atomic():
                # 家庭所有者删除成员
                if member_id:
                    is_owner = EquipmentFamilyView.get_family_owner(app_user_id, family_id)
                    if not is_owner:
                        return response.json(404)
                    member_id = int(member_id)
                    family_member_qs = FamilyMember.objects.filter(id=member_id)
                    if not family_member_qs.exists():
                        return response.json(173)
                    family_member_qs.delete()
                    return response.json(0)
                else:
                    # 成员退出当前家庭
                    family_member = FamilyMember.objects.filter(family_id=family_id, user_id=app_user_id, identity=1)
                    if family_member.exists():
                        return response.json(173)
                    family_member_qs = FamilyMember.objects.filter(family_id=family_id, user_id=app_user_id)
                    if not family_member_qs.exists():
                        return response.json(173)
                    family_member_qs.delete()
                    return response.json(0)
        except Exception as e:
            return response.json(177, repr(e))

    @classmethod
    def user_join_confirm(cls, request_dict, response):
        """
        用户加入家庭确认
        @param request_dict:
        @param response:
        @return:
        """
        join_id = request_dict.get('joinId', None)
        confirm = request_dict.get('confirm', None)
        lang = request_dict.get('lang', 'en')
        if not all([join_id, confirm]):
            return response.json(444)
        join_id = int(join_id)
        family_join = FamilyMemberJoin.objects.filter(id=join_id, status=0)
        if not family_join.exists():
            return response.json(173)
        family_member = FamilyMember.objects.filter(family_id=family_join.first().family_id,
                                                    user_id=family_join.first().user_id)
        if family_member.exists():
            return response.json(174)
        try:
            now_time = int(time.time())
            with transaction.atomic():
                family_join.update(status=2 if confirm == 'confirm' else 1)
                family_join = FamilyMemberJoin.objects.filter(id=join_id)
                family_join = family_join.values('id', 'user_id', 'user__username', 'user__NickName', 'family__name',
                                                 'family_id', 'family__user_id', 'status', 'type', 'updated_time')
                family_join = family_join.first()
                nick_name = family_join['user__NickName']
                family_name = family_join['family__name']
                join_type = family_join['type']
                data = {
                    'addTime': now_time,
                    'updTime': now_time,
                    'userID_id': family_join['user_id'] if join_type == 1 else family_join['family__user_id'],
                    'eventType': 0
                }
                if confirm == 'confirm':
                    msg_text = cls.get_confirm_text(nick_name, family_name, join_type, True, lang)
                    p_id = FamilyMemberPermission.objects.filter(no='002').values('id').first()
                    p_id = p_id['id']
                    FamilyMember.objects.create(family_id=family_join['family_id'], updated_time=now_time,
                                                user_id=family_join['user_id'],
                                                created_time=now_time,
                                                permission_id=p_id,
                                                user_name=family_join['user__username'])
                elif confirm == 'refusal':
                    msg_text = cls.get_confirm_text(nick_name, family_name, join_type, False, lang)
                else:
                    ex = Exception("data is null")
                    raise ex
                data['msg'] = msg_text
                data['uid'] = family_join['id']
                SysMsgModel.objects.create(**data)
            return response.json(0)
        except Exception as e:
            print(e)
            return response.json(177, repr(e))

    @classmethod
    def get_confirm_text(cls, nick_name, family_name, join_type, is_confirm, lang='en'):
        # join_type == 1等于扫码请求加u人
        if is_confirm:
            if join_type == 1:
                if lang == 'cn':
                    msg_text = '{} 同意你的请求'.format(family_name)
                else:
                    msg_text = '{} confirm to your request'.format(family_name)
            else:
                if lang == 'cn':
                    msg_text = '{}同意加入{}'.format(nick_name, family_name)
                else:
                    msg_text = '{} confirm to join {}'.format(nick_name, family_name)
        else:
            if join_type == 1:
                if lang == 'cn':
                    msg_text = '{}拒绝你的请求'.format(family_name)
                else:
                    msg_text = '{} refused your request'.format(family_name)

            else:
                if lang == 'cn':
                    msg_text = '{}拒绝加入{}'.format(nick_name, family_name)
                else:
                    msg_text = '{} refused to join '.format(family_name)
        return msg_text

    @classmethod
    def member_join_info(cls, request_dict, response):
        """
        查询加入家庭信息
        @param request_dict:
        @param response:
        @return:
        """
        join_id = request_dict.get('joinId', None)
        if not join_id:
            return response.json(444)
        join_id = int(join_id)
        family_join_qs = FamilyMemberJoin.objects.filter(id=join_id)
        if not family_join_qs.exists():
            return response.json(173)
        family_join_qs = family_join_qs.values('type', 'user__NickName', 'family__name', 'status', 'id',
                                               'family__user__NickName')
        family_join_qs = family_join_qs.first()
        nick_name = family_join_qs['user__NickName']
        if family_join_qs['type'] == 0:
            nick_name = family_join_qs['family__user__NickName']
        return response.json(0, {
            'id': family_join_qs['id'],
            'type': family_join_qs['type'],
            'nickName': nick_name,
            'familyName': family_join_qs['family__name'],
            'status': family_join_qs['status'],
        })

    @classmethod
    def member_join(cls, app_user_id, request_dict, response):
        """
        家庭成员加入
        @param app_user_id:
        @param request_dict:
        @param response:
        @return:
        """
        family_id = request_dict.get('familyId', None)
        invite = request_dict.get('QRCodeInvite', 0)
        user_id = request_dict.get('app_user_id', None)
        lang = request_dict.get('lang', 'en')
        if not all([family_id, invite]):
            return response.json(444)
        invite = int(invite)
        family_id = int(family_id)
        now_time = int(time.time())
        # 判断当前家庭是否已有该成员
        if invite == 1:
            family_qs = FamilyMember.objects.filter(family_id=family_id, user_id=app_user_id)
        elif user_id:
            family_qs = FamilyMember.objects.filter(family_id=family_id, user_id=user_id)
        else:
            return response.json(173)
        if family_qs.exists():
            return response.json(174)
        try:
            user_family_qs = UserFamily.objects.filter(id=family_id)
            if not user_family_qs:
                return response.json(173)
            user_family = user_family_qs.first()
            family_name = user_family.name
            data = {
                'addTime': now_time,
                'updTime': now_time,
                'eventType': 705
            }
            # 请求加入家庭，用户信息
            user_qs = Device_User.objects.filter(userID=app_user_id)
            nick_name = user_qs.first().NickName

            if invite == 1:
                msg_text = cls.get_msg_text(nick_name, family_name, lang, True)
                # 通知对象 家庭所有者
                join_user_id = app_user_id
                data['userID_id'] = user_family.user_id
            elif app_user_id:
                msg_text = cls.get_msg_text(nick_name, family_name, lang, False)
                # 通知对象 被邀请人
                join_user_id = user_id
                data['userID_id'] = user_id
            else:
                return response.json(173)
            data['msg'] = msg_text
            with transaction.atomic():
                member_user_id = user_id if user_id else app_user_id
                member_join_qs = FamilyMemberJoin.objects.filter(family_id=family_id, user_id=member_user_id)
                if member_join_qs.exists():
                    member_join_qs.update(status=0, updated_time=now_time)
                    data['uid'] = member_join_qs.first().id
                    SysMsgModel.objects.create(**data)
                    return response.json(0)
                family_user_join = FamilyMemberJoin.objects.create(family_id=family_id, user_id=join_user_id,
                                                                   status=0,
                                                                   updated_time=now_time,
                                                                   created_time=now_time,
                                                                   type=invite)
                data['uid'] = family_user_join.id
                SysMsgModel.objects.create(**data)
                return response.json(0)
        except Exception as e:
            print(e)
            return response.json(177, repr(e))

    @classmethod
    def get_msg_text(cls, nick_name, family_name, lang, is_invite=False):
        """
        系统消息通知内容，中英文判断
        @param nick_name:
        @param family_name:
        @param lang:
        @param is_invite:
        @return:
        """
        if lang and lang == 'cn':
            if is_invite:
                msg_text = '{}请求加入你的{}'.format(nick_name, family_name)
            else:
                msg_text = '{}邀请你加入{}'.format(nick_name, family_name)
        else:
            if is_invite:
                msg_text = '{} Request to join your Homegroup {}'.format(nick_name, family_name)
            else:
                msg_text = '{} invite you to join the Homegroup {}'.format(nick_name, family_name)

        return msg_text

    @classmethod
    def member_join_page(cls, request_dict, response):
        """
        家庭成员邀请记录
        @param request_dict:
        @param response:
        @return:
        """
        page_no = request_dict.get('pageNo', None)
        page_size = request_dict.get('pageSize', None)
        family_id = request_dict.get('familyId', None)
        if not all([page_no, page_size, family_id]):
            return response.json(444)
        member_join = FamilyMemberJoin.objects.filter(family_id=family_id).values('id', 'status', 'user__username',
                                                                                  'user__userIconUrl', 'user__phone',
                                                                                  'user__userEmail', 'updated_time',
                                                                                  'created_time',
                                                                                  'user__NickName')

        page_no = int(page_no)
        page_size = int(page_size)
        member_join = member_join.order_by('-updated_time')[(page_no - 1) * page_size: page_no * page_size]
        if not member_join.exists():
            return response.json(0, [])
        result = []
        for item in member_join:
            result.append({
                'joinId': item['id'],
                'status': item['status'],
                'userName': item['user__username'],
                'userIconUrl': item['user__userIconUrl'],
                'phone': item['user__phone'],
                'nickName': item['user__NickName'],
                'userEmail': item['user__userEmail'],
                'updatedTime': item['updated_time'],
                'createdTime': item['created_time']
            })
        return response.json(0, result)

    @classmethod
    def family_generate_token(cls, app_user_id, request_dict, response):
        """
        获取家庭令牌信息
        @param app_user_id:
        @param request_dict:
        @param response:
        @return:
        """
        family_id = request_dict.get('familyId', None)
        if not family_id:
            return response.json(444)
        family_id = int(family_id)
        family_qs = UserFamily.objects.filter(id=family_id, user_id=app_user_id) \
            .values('name', 'user__userEmail',
                    'user__userIconUrl',
                    'user__phone', 'user__NickName',
                    'user__username')
        if not family_qs.exists():
            return response.json(173)
        family_qs = family_qs.first()
        data = {'sharer': app_user_id, 'familyId': family_id}
        # -----------------
        # share_token = jwt.encode(data, '.#^^&', algorithm='HS256').decode('utf-8')
        # +++++++++++++++++
        redisObj = RedisObject()
        share_token = str(int(time.time())) + CommonService.RandomStr(22)
        if not redisObj.set_data(key=share_token, val=json.dumps(data), expire=300):
            return response.json(10, '生成失败')
        return response.json(0, {
            'shareToken': share_token,
            'userPhone': family_qs['user__phone'],
            'nickName': family_qs['user__NickName'],
            'userIconUrl': family_qs['user__userIconUrl'],
            'userName': family_qs['user__username'],
            'familyName': family_qs['name'],
            'userEmail': family_qs['user__userEmail'],
        })

    @classmethod
    def check_qrcode(cls, request_dict, response):
        """
        检查二维码是否过期
        @param request_dict:
        @param response:
        @return:
        """
        share_token = request_dict.get('shareToken', None)
        if not share_token:
            return response.json(444)
        redisObj = RedisObject()
        share_data = redisObj.get_data(key=share_token)
        if not share_data:
            return response.json(119)
        data = json.loads(share_data)
        sharer = data.get('sharer', None)
        family_id = data.get('familyId', None)
        if not all([sharer, family_id]):
            return response.json(173)
        family_id = int(family_id)
        user_family_qs = UserFamily.objects.filter(id=family_id)
        if not user_family_qs.exists():
            return response.json(173)
        user_family_qs = user_family_qs.values('id', 'name', 'user__userEmail',
                                               'user__userIconPath',
                                               'user__phone', 'user__NickName',
                                               'user__username')
        user_icon_url = ''
        userIconPath = str(user_family_qs[0]['user__userIconPath'])
        if userIconPath and userIconPath.find('static/') != -1:
            userIconPath = userIconPath.replace('static/', '').replace('\\', '/')
            user_icon_url = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
        return response.json(0, {
            'familyId': user_family_qs[0]['id'],
            'userPhone': user_family_qs[0]['user__phone'],
            'nickName': user_family_qs[0]['user__NickName'],
            'userIconUrl': user_icon_url,
            'userName': user_family_qs[0]['user__username'],
            'familyName': user_family_qs[0]['name'],
            'userEmail': user_family_qs[0]['user__userEmail'],
        })
