import time
import traceback

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.base import View

from Model.models import Device_Info, Equipment_Info, UidPushModel
from Model.models import Device_User
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Service.CommonService import CommonService
from Service.EquipmentInfoService import EquipmentInfoService
from Service.ModelService import ModelService


class EquipmentInfo(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(EquipmentInfo, self).dispatch(*args, **kwargs)

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

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

    def validation(self, request_dict, *args, **kwargs):
        token = request_dict.get('token', None)
        response = ResponseObject()
        tko = TokenObject(token)
        if tko.code != 0:
            return response.json(tko.code)
        userID = tko.userID
        operation = request_dict.get('operation', None)
        if not userID:
            return response.json(309)
        if operation == 'query':    # 查询推送消息
            return self.query_info(request_dict, userID, response)
        elif operation == 'add':
            return self.add_info(request_dict, userID, response)
        elif operation == 'update':     # 已读推送消息
            return self.update_info(request_dict, userID, response)
        elif operation == 'update-answer-status':   # 已接听一键通话消息
            return self.update_answer_status(request_dict, userID, response)
        elif operation == 'delete':     # 删除推送消息
            return self.delete_info(request_dict, response)
        elif operation == 'findByTime':
            return self.findByTime_info(request_dict, userID, response)
        if operation == 'queryByAdmin':
            return self.query_all_info(request_dict, userID, response)
        if operation == 'deleteByAdmin':
            return self.delete_by_admin(request_dict, userID, response)
        else:
            return response.json(444, {"parm": "operation"})

    def add_info(self, request_dict, userID, response):
        return response.json(0)

    def query_info(self, request_dict, userID, response):
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        if not page or not line:
            return response.json(444, 'page,line')
        qs = Equipment_Info.objects.filter(userID_id=userID)
        uid = request_dict.get('uid', None)
        if uid:
            qs = qs.filter(devUid=uid)
            dvqs = Device_Info.objects.filter(UID=uid).values('Type', 'NickName')
            uid_type_dict = {uid: {'type': dvqs[0]['Type'], 'NickName': dvqs[0]['NickName']}}
        else:
            dvqs = Device_Info.objects.filter(userID_id=userID).values('UID', 'Type', 'NickName')
            uid_type_dict = {}
            for dv in dvqs:
                uid_type_dict[dv['UID']] = {'type': dv['Type'], 'NickName': dv['NickName']}
        if not qs.exists():
            return response.json(0, {'datas': [], 'count': 0})
        count = qs.count()
        res = qs[(page - 1) * line:page * line]
        send_json = CommonService.qs_to_dict(res)
        res = []
        for p in send_json['datas']:
            p['fields']['viewAccont'] = ''
            p['fields']['viewPwd'] = ''
            devUid = p['fields']['devUid']
            if devUid in uid_type_dict.keys():
                p['fields']['uid_type'] = uid_type_dict[devUid]['type']
                p['fields']['devNickName'] = uid_type_dict[devUid]['NickName']
            else:
                p['uid_type'] = ''
            res.append(p)
        return response.json(0, {'datas': res, 'count': count})

    @staticmethod
    def update_info(request_dict, userID, response):
        is_update_all = int(request_dict.get('is_update_all', 0))
        event_type = request_dict.get('eventType', None)
        if is_update_all == 1:
            kwargs = {
                'device_user_id': userID,
                'status': 0
            }
            if event_type:
                kwargs['event_type'] = int(event_type)
            try:
                EquipmentInfoService.all_read_equipment_info(**kwargs)
            except Exception as e:
                print(repr(e))
        else:
            id_list = request_dict.getlist('id[]', None)
            if id_list is None or len(id_list) < 1:
                id_list = request_dict.getlist('id', None)
            if not id_list:
                return response.json(444)
            for full_id in id_list:
                try:
                    ei_id = int(full_id[2:])
                    equipment_info_model = EquipmentInfoService.get_equipment_info_model_with_full_id(full_id)
                    equipment_info_model.objects.filter(id=ei_id).update(status=1)
                except Exception as e:
                    print(repr(e))
        return response.json(0)

    @staticmethod
    def update_answer_status(request_dict, user_id, response):
        """
        更新一键通话消息状态为已接听
        @param request_dict:
        @param user_id: 用户id
        @param response:
        @return:
        """
        uid = request_dict.get('uid', None)
        event_time = request_dict.get('event_time', None)
        if not all([uid, event_time]):
            return response.json(444)

        kwargs = {
            'device_user_id': user_id,
            'device_uid': uid,
            'event_time': event_time,
            'event_type__in': [606, 607]
        }
        try:
            EquipmentInfoService.update_equipment_info_answer_status(**kwargs)
        except Exception as e:
            print(repr(e))
        return response.json(0)

    @staticmethod
    def delete_info(request_dict, response):
        id_list = request_dict.getlist('id[]', None)
        if id_list is None or len(id_list) < 1:
            id_list = request_dict.getlist('id', None)
        if not id_list:
            return response.json(444)
        try:
            for full_id in id_list:
                ei_id = int(full_id[2:])
                equipment_info_model = EquipmentInfoService.get_equipment_info_model_with_full_id(full_id)
                equipment_info_model.objects.filter(id=ei_id).delete()
        except Exception as e:
            print(repr(e))
        return response.json(0)

    def findByTime_info(self, request_dict, userID, response):
        startTime = request_dict.get('startTime')
        endTime = request_dict.get('endTime')
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        if not startTime or not endTime or not page or not line:
            return response.json(444, 'startTime, endTime, page, line')
        uid_list = Device_Info.objects.filter(userID_id=userID).values_list('UID', flat=True)
        if not len(uid_list):
            return response.json(0, {'datas': [], 'count': 0})
        qs = Equipment_Info.objects.filter(userID_id=userID,
                                           eventTime__range=(startTime, endTime)).order_by('-id')
        if qs.exists():
            count = qs.count()
            res = qs[(page - 1) * line:page * line]
            send_json = CommonService.qs_to_dict(res)
            send_json['count'] = count
            return response.json(0, send_json)

    # 管理员查询指定用户的推送信息接口
    def query_all_info(self, request_dict, userID, response):
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        username = request_dict.get('username', None)
        uid = request_dict.get('uid', None)
        devNickName = request_dict.get('devNickName', None)
        Channel = request_dict.get('Channel', None)
        if not page or not line:
            return response.json(444, 'page,line')
        check_perm = ModelService.check_perm(userID=userID, permID=30)
        if not check_perm:
            return response.json(404)

        if not username and not uid and not devNickName and not Channel:
            qs = Equipment_Info.objects.all().order_by('-id')
        elif username:
            user = Device_User.objects.filter(username=username)
            users = CommonService.qs_to_dict(user)
            # 从字典类型中找到对应的pk值，即是userID
            user_id = users.get('datas')[0].get('pk')
            if not user.exists():
                return response.json(104)

            uid_list = Device_Info.objects.filter(userID_id=user_id).values_list('UID', flat=True)
            if not len(uid_list):
                return response.json(0, {'datas': [], 'count': 0})
            qs = Equipment_Info.objects.filter(userID_id=user_id).order_by('-id')
        elif uid:
            qs = Equipment_Info.objects.filter(devUid=uid).order_by('-id')
        elif devNickName:
            qs = Equipment_Info.objects.filter(devNickName=devNickName).order_by('-id')
        elif Channel:
            qs = Equipment_Info.objects.filter(Channel=Channel).order_by('-id')
        if not qs.exists():
            return response.json(0, {'datas': [], 'count': 0})
        count = qs.count()
        res = qs[(page - 1) * line:page * line]
        send_json = CommonService.qs_to_dict(res)
        send_json['count'] = count
        return response.json(0, send_json)

    # 管理员的删除推送信息的接口
    def delete_by_admin(self, request_dict, userID, response):
        id_list = request_dict.getlist('id', None)
        if not len(id_list):
            return response.json(444, 'id is None or not list')
        check_perm = ModelService.check_perm(userID=userID, permID=10)
        if check_perm is True:
            try:
                is_delete = Equipment_Info.objects.filter(id__in=id_list).delete()
            except Exception as e:
                errorInfo = traceback.format_exc()
                print(errorInfo)
                return response.json(424, {'details': repr(e)})
            else:
                return response.json(0, {'delete_count': is_delete[0]})
        else:
            return response.json(404)


'''
use information_schema;
select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='Ansjer81';
'''


# 按季度删除访问日志
def deleteExpireEquipmentInfoById(request):
    response = ResponseObject()
    id = int(request.GET.get('id', None))

    if id is None:
        return response.json(0)

    Equipment_Info.objects.filter(id__lte=id).delete()
    return response.json(0)
