# -*- encoding: utf-8 -*-
"""
@File    : GatewayFamilyRoomController.py
@Time    : 2022/5/24 19:43
@Author  : stephen
@Email   : zhangdongming@asj6.wecom.work
@Software: PyCharm
"""

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

from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
from Model.models import FamilyRoomDevice, FamilyRoom, GatewaySubDevice, Device_Info
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject


# 家庭房间管理
class GatewayFamilyRoomView(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', token.lang)
        response = ResponseObject(lang)
        if token.code != 0:
            return response.json(token.code)
        app_user_id = token.userID
        # 添加设备关联房间
        if operation == 'device-changes':
            return self.room_device_save(app_user_id, request_dict, response)
        # 房间排序
        elif operation == 'sort':
            return self.room_sort_save(request_dict, response)
        # 房间删除
        elif operation == 'del':
            return self.room_del(app_user_id, request_dict, response)
        # 房间详情
        elif operation == 'details':
            return self.get_room_details(app_user_id, request_dict, response)
        elif operation == 'all-devices':  # 家庭所有设备
            return self.all_devices(request_dict, response)
        elif operation == 'devices-sort':  # 家庭设备排序
            return self.devices_sort(request_dict, response)
        elif operation == 'device-category':  # 获取设备类别
            return self.device_category(request_dict, response)
        elif operation == 'category-sort':  # 设备类别排序
            return self.category_sort(request_dict, response)
        else:
            return response.json(414)

    @classmethod
    def room_device_save(cls, app_user_id, request_dict, response):
        """
        房间加入设备or移除设备
        @param app_user_id:
        @param request_dict:
        @param response:
        @return:
        """
        family_id = request_dict.get('familyId', None)
        device_ids = request_dict.get('deviceIds', None)
        room_id = request_dict.get('roomId', None)
        if not all([family_id, room_id]):
            return response.json(444)
        family_id = int(family_id)
        room_id = int(room_id)
        is_owner = EquipmentFamilyView.get_family_owner(app_user_id, family_id)
        if not is_owner:
            return response.json(404)
        try:
            with transaction.atomic():
                room_qs = FamilyRoom.objects.filter(family_id=family_id, id=room_id)
                if not room_qs.exists():
                    return response.json(173)
                qs = FamilyRoomDevice.objects.filter(family_id=family_id, room_id=room_id)
                if qs.exists():
                    qs.update(room_id=0, sort=0)
                if device_ids:
                    device_ids = eval(device_ids)
                    for i, item in enumerate(device_ids):
                        device_id = item['id']
                        device_type = item['type']
                        device_qs = Device_Info.objects.filter(id=device_id, Type=device_type)
                        if device_qs.exists():
                            room_device_qs = FamilyRoomDevice.objects.filter(device_id=device_id)
                        else:
                            room_device_qs = FamilyRoomDevice.objects.filter(sub_device=device_id)
                        if room_device_qs.exists():
                            room_device_qs.update(room_id=room_id, sort=i)
                return response.json(0)
        except Exception as e:
            print(e)
            return response.json(177, repr(e))

    @classmethod
    def room_del(cls, user_id, request_dict, response):
        """
        房间多选删除
        @param user_id: 当前登录用户id
        @param request_dict: 请求参数
        @param response: 响应参数
        @return:
        """
        ids = request_dict.get('roomIds', None)
        if not ids:
            return response.json(444)
        ids = ids.split(',')
        room_id = ids[0]
        room_info = FamilyRoom.objects.filter(id=room_id)
        if not room_info.exists():
            return response.json(173)
        is_owner = EquipmentFamilyView.get_family_owner(user_id, room_info.first().family_id)
        if not is_owner:
            return response.json(404)
        try:
            with transaction.atomic():
                for item in ids:
                    room_id = int(item)
                    room_device = FamilyRoomDevice.objects.filter(room_id=room_id)
                    if room_device.exists():
                        room_device.update(room_id=0)
                    FamilyRoom.objects.filter(id=room_id).delete()
                return response.json(0)
        except Exception as e:
            print(e)
            return response.json(177, repr(e))

    @classmethod
    def room_sort_save(cls, request_dict, response):
        """
        房间排序
        @param request_dict: 请求参数
        @param response: 响应参数
        @return:
        """
        ids = request_dict.get('ids', None)
        if not ids:
            return response.json(444)
        items = ids.split(',')
        for item in items:
            item = item.split('-')
            room_id, sort = item[0], item[1]
            family_room = FamilyRoom.objects.filter(id=int(room_id))
            if family_room.exists():
                family_room.update(sort=int(sort))
        return response.json(0)

    @classmethod
    def get_room_details(cls, app_user_id, request_dict, response):
        """
        房间设备详情(所在当前房间下，和所在家庭不在当前房间下的主设备)
        @param app_user_id:
        @param request_dict:
        @param response:
        @return:
        """
        family_id = request_dict.get('familyId', None)
        room_id = request_dict.get('roomId', None)
        if not all([family_id, room_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)
        room_id = int(room_id)
        room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id, room_id=room_id).values(
            'device_id', 'device__Type', 'device__NickName', 'sub_device').order_by('sort', '-device__data_joined')
        device_room = []
        if room_device_qs.exists():
            room_name = FamilyRoom.objects.filter(id=room_id)
            for item in room_device_qs:
                if not item['sub_device']:
                    device_dict = {
                        'deviceId': item['device_id'],
                        'deviceType': item['device__Type'],
                        'nickName': item['device__NickName'],
                        'roomName': room_name.first().name if room_name.exists() else '',
                    }
                else:
                    sub_device_qs = GatewaySubDevice.objects.filter(id=item['sub_device']).values('id',
                                                                                                  'device_type',
                                                                                                  'nickname')
                    if not sub_device_qs.exists():
                        continue
                    device_dict = {
                        'deviceId': sub_device_qs[0]['id'],
                        'deviceType': sub_device_qs[0]['device_type'],
                        'nickName': sub_device_qs[0]['nickname'],
                        'roomName': room_name.first().name if room_name.exists() else '',
                    }

                device_room.append(device_dict)

        device_not_room = []
        device_not_room_qs = FamilyRoomDevice.objects.filter(family_id=family_id)
        device_not_room_qs = device_not_room_qs.filter(~Q(room_id=room_id)).values('room_id', 'device_id',
                                                                                   'device__Type', 'device__NickName',
                                                                                   'sub_device').order_by('sort',
                                                                                                          '-device__data_joined')
        if device_not_room_qs.exists():
            for item in device_not_room_qs:
                name = ''
                family_room_qs = FamilyRoom.objects.filter(id=item['room_id'])
                if family_room_qs.exists():
                    name = family_room_qs.first().name
                if not item['sub_device']:
                    device_not_room.append({
                        'deviceId': item['device_id'],
                        'deviceType': item['device__Type'],
                        'nickName': item['device__NickName'],
                        'roomName': name
                    })
                else:
                    sub_device_qs = GatewaySubDevice.objects.filter(id=item['sub_device']).values('id',
                                                                                                  'device_type',
                                                                                                  'nickname')
                    if not sub_device_qs.exists():
                        continue
                    device_not_room.append({
                        'deviceId': sub_device_qs[0]['id'],
                        'deviceType': sub_device_qs[0]['device_type'],
                        'nickName': sub_device_qs[0]['nickname'],
                        'roomName': name
                    })
        return response.json(0, {'deviceRooms': device_room, 'deviceNotRooms': device_not_room})

    @staticmethod
    def all_devices(request_dict, response):
        """
        家庭所有设备(网关和摄像头设备)
        @param request_dict: 请求参数
        @request_dict familyId: 家庭id
        @param response: 响应参数
        @return:
        """
        family_id = request_dict.get('familyId', None)
        if not family_id:
            return response.json(444)
        device_room = {
            'gateways': [],
            'cameras': [],
            'sort': []
        }
        try:
            family_room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id)
            family_room_device_qs = family_room_device_qs.filter(~Q(device__isExist=2)) \
                .values('device_id', 'device__Type', 'device__NickName', 'room_id',
                        'sub_device', 'category', ).order_by('sort', '-device__data_joined')

            if not family_room_device_qs.exists():
                return response.json(0, device_room)
            sort = FamilyRoomDevice.objects.filter(family_id=family_id).values('category').annotate(
                count=Count('category')).values('category', 'category_sort').order_by('category_sort')
            for item in sort:
                if item['category'] == 0:
                    item['category_name'] = '网关子设备类'
                else:
                    item['category_name'] = '摄像头类'
            gateways = []
            cameras = []
            # 查询房间名称
            for device in family_room_device_qs:
                room_id = device['room_id']
                device_type = device['device__Type']
                category = device['category']
                room_name = FamilyRoom.objects.filter(id=room_id)
                if category == 0:  # 网关子设备
                    if not device['sub_device']:
                        device_dict = {
                            'deviceId': device['device_id'],
                            'deviceType': device_type,
                            'nickName': device['device__NickName'],
                            'roomName': room_name.first().name if room_name.exists() else '',
                        }
                    else:
                        sub_device_qs = GatewaySubDevice.objects.filter(id=device['sub_device']).values('device_type',
                                                                                                        'nickname')
                        if not sub_device_qs.exists():
                            continue
                        device_dict = {
                            'deviceId': device['sub_device'],
                            'deviceType': sub_device_qs[0]['device_type'],
                            'nickName': sub_device_qs[0]['nickname'],
                            'roomName': room_name.first().name if room_name.exists() else '',
                        }

                    gateways.append(device_dict)

                else:  # 摄像头设备
                    cameras.append({
                        'deviceId': device['device_id'],
                        'deviceType': device_type,
                        'nickName': device['device__NickName'],
                        'roomName': room_name.first().name if room_name.exists() else '',
                    })

            device_room['gateways'] = gateways
            device_room['cameras'] = cameras
            device_room['sort'] = list(sort)
            return response.json(0, device_room)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @staticmethod
    def devices_sort(request_dict, response):
        """
        家庭设备排序
        @param request_dict: 请求参数
        @request_dict 设备id: deviceIds
        @param response: 响应参数
        @return:
        """
        device_ids = request_dict.get('deviceIds', None)
        if not device_ids:
            return response.json(444)
        try:
            device_ids = eval(device_ids)
            with transaction.atomic():
                for i, item in enumerate(device_ids):
                    device_id = item['id']
                    device_type = item['type']
                    device_qs = Device_Info.objects.filter(id=device_id, Type=device_type)
                    if device_qs.exists():  # 更新主设备排序
                        FamilyRoomDevice.objects.filter(device_id=device_id).update(sort=i)
                    else:  # 更新子设备排序
                        FamilyRoomDevice.objects.filter(sub_device=device_id).update(sort=i)
            return response.json(0)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @staticmethod
    def device_category(request_dict, response):
        """
        获取设备类别排序
        @param request_dict: 请求参数
        @request_dict 家庭id: family_id
        @param response: 响应参数
        @return:
        """
        family_id = request_dict.get('familyId', None)
        if not family_id:
            return response.json(444)
        try:
            family_room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id).values('category').annotate(
                count=Count('category')).values('category', 'category_sort').order_by('category_sort')
            for item in family_room_device_qs:
                if item['category'] == 0:
                    item['category_name'] = '网关子设备类'
                else:
                    item['category_name'] = '摄像头类'
            return response.json(0, list(family_room_device_qs))
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @staticmethod
    def category_sort(request_dict, response):
        """
        家庭设备排序
        @param request_dict: 请求参数
        @request_dict 家庭id: family_id
        @request_dict 排序列表: category_sort
        @param response: 响应参数
        @return:
        """
        family_id = request_dict.get('familyId', None)
        category_sort = request_dict.get('categorySort', None)
        if not all([family_id, category_sort]):
            return response.json(444)
        try:
            category_sort_list = eval(category_sort)
            family_room_device_qs = FamilyRoomDevice.objects.filter(family_id=family_id)
            if family_room_device_qs.exists():
                with transaction.atomic():
                    for item in category_sort_list:
                        category = item['category']
                        category_sort = item['category_sort']
                        family_room_device_qs.filter(category=category).update(category_sort=category_sort)
            return response.json(0)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
