#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__: vv
# Date: 2019/8/30

from datetime import datetime, timedelta
from gm_dataquery.db import DB
from gm_dataquery.dataquery import DataBuilder, DataSQLQuery

from api.models import ProtectPhone, ProtectPhoneLog, Order, PhoneServiceRecord, \
    HeraProtectPhoneHuaweiyunCallRecords, HeraProtectPhoneUserCallbackList, \
    HeraProtectPhoneHuaweiyunBindingRelationship, User, Q
from api.tool.log_tool import info_logger, exception_logger
from gm_types.gaia import USERCALL_EVENT_TYPE


class ProtectPhoneDB(DataBuilder):
    def getval_username(self, obj):
        from api.models import User
        if obj.operator:
            u = User.objects.filter(id=obj.operator).first()
            if u:
                return u.username
        else:
            return ''

    def getval_isbind(self, obj):
        return False if obj and obj.is_online and obj.bind_time else True

    def getval_wechat(self, obj):
        if obj.wechat:
            return obj.wechat
        else:
            return "-"


@DB
class ProtectPhoneDQ(DataSQLQuery):
    model = ProtectPhone
    data_model = ProtectPhoneDB

    def create(self, data, **kwargs):
        info_logger.info({'data': data})
        obj = ProtectPhone()
        obj.favor = data.pop('favor', '')
        obj.city_id = data.pop('city_id', '')
        obj.operator = data.pop('operator')
        obj.user_id = data.pop('user_id')
        obj.wechat = data.pop('wechat', None)
        obj.is_get_wechat = data.pop('is_get_wechat', '')
        obj.bind_time = datetime.now()
        obj.subscriptionid = data.pop('subscriptionId')
        obj.call_status = data.pop('call_status', 1)
        obj.event_id = data.pop('event_id')
        obj.event_type = data.pop('event_type')

        obj.save()

        ProtectPhoneLog.objects.create(
            a_user_id=obj.operator,
            b_user_id=obj.user_id,
            subscriptionid=obj.subscriptionid,
            x_phone_num=data.pop('relationNum', None),
            is_delete=False,
            event_type=obj.event_type,
            protect_phone_id=obj.id,
        )
        return {'id': obj.id}

    def update(self, updates, **kwargs):
        info_logger.info({'updates': updates, 'kwargs': kwargs})
        action = updates.pop('action', '')
        subscriptionId = updates.pop('subscriptionId', None)
        relationNum = updates.pop('relationNum', None)
        current_user_id = updates.pop('current_user_id', None)
        is_get_wechat = updates.pop('is_get_wechat', False)
        call_status = updates.pop('call_status', 1)
        wechat = updates.pop('wechat', None)
        event_type = kwargs.pop('event_type', None)
        event_id = kwargs.pop('event_id', None)

        ids = kwargs.pop('ids', [])
        if ids:
            ProtectPhone.objects.filter(id__in=ids).update(is_online=False)
            return
        if action == "mark":
            pro = ProtectPhone.objects.filter(event_id=event_id, event_type=event_type).last()
        else:
            pro = ProtectPhone.objects.filter(event_id=event_id, event_type=event_type).last()

        if action == "unbind":
            pro.unbind_time = datetime.now()
            pro.is_online = False
        if action == "mark":
            pro.is_get_wechat = bool(int(is_get_wechat))
            pro.call_status = call_status
            pro.wechat = wechat

            if event_type:
                event_type = int(event_type)
                if event_type == USERCALL_EVENT_TYPE.ORDER_CHECK:
                    Order.objects.filter(pk=event_id).update(call_result=call_status)
                elif event_type == USERCALL_EVENT_TYPE.COMMUNICATE_RECORT:
                    PhoneServiceRecord.objects.filter(pk=event_id).update(aduit_result=call_status)

        pro.save()
        if action == 'unbind':
            ProtectPhoneLog.objects.create(
                a_user_id=current_user_id,
                b_user_id=pro.user_id,
                subscriptionid=subscriptionId,
                x_phone_num=relationNum,
                is_delete=True,
                event_type=event_type,
                protect_phone_id=pro.id,
            )

        return {'id': pro.id}


# 说明:
# 该文件中对应的是hera项目中华为云私密账号通话的数据增删改查操作
# 上面的ProtectPhoneDQ是之前创建的, 供hera项目中三个页面使用:
#   1. 用户回拨列表 : http://hera.paas.env/big/list/bdtransfer/call_back_list_v1.html(测试环境链接)
#   2. 通话记录及录音 : http://hera.paas.env/big/list/doctor/show_voice_v1.html
#   3. 订单稽查列表: http://hera.paas.env/order/wait/adult_settled_v2/
#   4. 用户详情: http://hera.paas.env/user/detail/188/
# 这个四个功能列表之前被开发后,线上没有被使用（【用户详情中】的'绑定/解绑'按钮
# 现需要重新完善【用户回拨列表】功能, 但是不能影响【通话记录及录音】和【订单稽查列表】功能
# **重点:
# 所以在gaia/api/models/phone_peotect.py文件中创建了三个表供【用户回拨列表】使用, 以下是对表的增删改查操作
# **如果后者需要完善【通话记录及录音】【订单稽查列表】功能时, 可借鉴上面的操作,需使用下面逻辑**


class HeraProtectPhoneUserCallbackListDB(DataBuilder):
    def getval_username(self, obj):
        if obj and obj.operator_id:
            user = User.objects.filter(id=obj.operator_id).first()
            if user and user.id and user.username:
                return user.id, user.username

        return '', ''

    def getval_isbind(self, obj):
        session_id = obj.session_id
        subscription_id = obj.subscription_id

        bind_obj = HeraProtectPhoneHuaweiyunBindingRelationship.objects.filter(subscription_id=subscription_id).last()
        recode_obj = HeraProtectPhoneHuaweiyunCallRecords.objects.filter(session_id=session_id).last()
        is_active = True
        if recode_obj and recode_obj.active_status_time:
            befor_time = recode_obj.active_status_time.date()
            now_time = datetime.now().date()
            if befor_time > now_time:
                is_active = False
            else:
                recode_obj.active_status_time = None
                recode_obj.save()
        if not bind_obj or bind_obj.is_bind is None:
            return False, is_active

        return bind_obj.is_bind, is_active

    def getval_wechat(self, obj):
        return obj.wechat if obj.wechat else '-'


@DB
class HeraProtectPhoneUserCallbackListDQ(DataSQLQuery):
    model = HeraProtectPhoneUserCallbackList
    data_model = HeraProtectPhoneUserCallbackListDB

    def filter_username(self, field, val, regex):
        user = User.objects.filter(username=val).last()
        if user:
            q = Q(operator_id=user.id)
        else:
            q = Q(id=-1)
        return q

    def filter_bind_time(self, srch_key, srch_value, regex=False):
        """根据绑定时间过滤"""
        return self._qry_time_range(srch_key, srch_value, regex)

    def filter_unbind_time(self, srch_key, srch_value, regex=False):
        """根据解绑时间过滤"""
        return self._qry_time_range(srch_key, srch_value, regex)

    def filter_favor(self, srch_key, srch_value, regex=False):
        """根据有效状态过滤user_id"""
        call_recodes = HeraProtectPhoneHuaweiyunCallRecords.objects.filter(active_status__in=srch_value).values('user_id').distinct()
        user_ids_list = []
        for call_recode in call_recodes:
            user_ids_list.append(call_recode['user_id'])
        q = Q(user_id__in=user_ids_list)
        return q

    def update(self, updates, **kwargs):
        info_logger.info({'updates': updates, 'kwargs': kwargs})
        action = kwargs.pop('action', '')
        id = updates.pop('protectPhone_id', '')
        is_get_wechat = updates.pop('is_get_wechat', 0)
        wechat = updates.pop('wechat', None)
        try:
            if action == "mark":
                pro = HeraProtectPhoneUserCallbackList.objects.filter(id=id).last()
                if pro:
                    pro.is_get_wechat = bool(int(is_get_wechat))
                    pro.wechat = wechat
                    pro.save()
                else:
                    return {'code': -1, 'msg': '标记数据失败'}
        except Exception as e:
            exception_logger.info(e)
            return {'code': -1, 'msg': '标记数据失败'}

        return {'code': 0, 'msg': '标记成功'}


class HeraProtectPhoneHuaweiyunCallRecordsDB(DataBuilder):
    def getval_username(self, obj):
        from api.models import User
        if obj and obj.operator_id:
            user = User.objects.filter(id=obj.operator_id).first()
            if user and user.id and user.username:
                return user.id, user.username

        return '', ''

    def getval_active_status(self, obj):
        if obj.active_status_time:
            befor_time = obj.active_status_time.date()
            now_time = datetime.now().date()
            if befor_time > now_time:
                delay = befor_time - now_time
                days = delay.days
                return obj.active_status, days
            else:
                obj.active_status_time = None
                obj.save()
        return obj.active_status, 0


@DB
class HeraProtectPhoneHuaweiyunCallRecordsDQ(DataSQLQuery):
    model = HeraProtectPhoneHuaweiyunCallRecords
    data_model = HeraProtectPhoneHuaweiyunCallRecordsDB

    def update(self, updates, **kwargs):
        action = kwargs.pop('action', '')
        id = updates.pop('call_recode_id', '')
        active_status = updates.pop('active_status', None)
        active_status_time = updates.pop('active_status_time', 0)
        remark = updates.pop('remark', '')

        try:
            if action == 'mark':
                pro = HeraProtectPhoneHuaweiyunCallRecords.objects.filter(id=id).last()
                if pro:
                    if int(active_status_time) > 0:
                        pro.active_status_time = datetime.now() + timedelta(days=(int(active_status_time.encode())))
                    else:
                        pro.active_status_time = None
                    pro.active_status = active_status
                    pro.remark = remark
                    pro.save()
                else:
                    return {'code': -1, 'msg': '标记数据失败'}

        except Exception as e:
            exception_logger.info(e)
            return {'code': -1, 'msg': '标记数据失败'}

        return {'code': 0, 'msg': '标记成功'}

    def create(self, updates, **kwargs):
        action = kwargs.pop('action', '')
        info_logger.info('CallRecords', action, str(updates))

        call_status = updates.pop('call_status', None)
        session_id = updates.pop('session_id', None)
        subscription_id = updates.pop('subscription_id', None)

        call_in_time = updates.pop('call_in_time', None)
        if call_in_time:
            call_in_time = datetime.fromtimestamp(call_in_time)
        call_end_time = updates.pop('call_end_time', None)
        if call_end_time:
            call_end_time = datetime.fromtimestamp(call_end_time)
        duration = updates.pop('duration', None)
        audio_url = updates.pop('audio_url', None)

        if action == 'call_event' or action == 'fee_event':
            pro = HeraProtectPhoneHuaweiyunCallRecords.objects.filter(session_id=session_id).last()
            if not pro:
                pro = HeraProtectPhoneHuaweiyunCallRecords()
            obj = HeraProtectPhoneHuaweiyunBindingRelationship.objects.filter(subscription_id=subscription_id).last()
            call_list = HeraProtectPhoneUserCallbackList.objects.filter(subscription_id=subscription_id).last()
            if call_list and obj and pro:
                if call_status:
                    call_list.call_status = call_status
                call_list.session_id = session_id
                call_list.subscription_id = subscription_id
                call_list.operator_id = obj.operator_id
                call_list.save()

                pro.session_id = session_id
                pro.subscription_id = subscription_id
                pro.user_id = obj.user_id
                pro.operator_id = obj.operator_id
                if call_status:
                    pro.call_status = call_status
                if call_in_time:
                    pro.call_in_time = call_in_time
                if call_end_time:
                    pro.call_end_time = call_end_time
                if duration:
                    pro.duration = duration
                if audio_url:
                    pro.audio_url = audio_url
                pro.save()
            else:
                return {'code': -1, 'msg': '话单数据保存失败'}
        return {'code': 0, 'msg': '话单数据保存成功'}


@DB
class HeraProtectPhoneHuaweiyunBindingRelationshipDQ(DataSQLQuery):
    model = HeraProtectPhoneHuaweiyunBindingRelationship

    def update(self, updates, **kwargs):
        action = kwargs.pop('action', '')
        protectPhone_id = updates.pop('protectPhone_id', '')
        id = updates.pop('bind_list_id', '')
        info_logger.info('HeraProtectPhoneHuaweiyunBindingRelationshipDQ', action, id, protectPhone_id)

        try:
            if action == 'unbind':
                now_time = datetime.now()
                pro = HeraProtectPhoneHuaweiyunBindingRelationship.objects.filter(id=id).last()
                obj = HeraProtectPhoneUserCallbackList.objects.filter(id=protectPhone_id).last()
                if pro and obj:
                    pro.unbind_time = now_time
                    pro.is_bind = False

                    obj.unbind_time = now_time

                    pro.save()
                    obj.save()
                else:
                    {'code': -1, 'msg': '解绑失败'}
        except Exception as e:
            exception_logger.info(e)
            return {'code': -1, 'msg': '解绑失败'}

        return {'code': 0, 'msg': '解绑成功'}

    def create(self, data, **kwargs):
        action = kwargs.pop('action', '')
        info_logger.info('HeraProtectPhoneHuaweiyunBindingRelationshipDQ', action, str(data))
        subscription_id = data.pop('subscription_id', '')
        relationNum = data.pop('relationNum', None)
        operator_id = data.pop('operator_id', '')
        user_id = data.pop('user_id', '')
        protectPhone_id = data.pop('protectPhone_id', '')

        try:
            if action == 'bind':
                obj = HeraProtectPhoneHuaweiyunBindingRelationship()
                pro = HeraProtectPhoneUserCallbackList.objects.filter(id=protectPhone_id).last()
                if obj and pro:
                    now_time = datetime.now()
                    obj.subscription_id = subscription_id
                    obj.relationNum = relationNum
                    obj.operator_id = operator_id
                    obj.user_id = user_id
                    obj.bind_time = now_time
                    obj.unbind_time = None
                    obj.is_bind = True
                    obj.save()

                    pro.bind_time = now_time
                    pro.unbind_time = None
                    pro.subscription_id = subscription_id
                    pro.save()
                else:
                    return {'code': -1, 'msg': '绑定失败'}
        except Exception as e:
            exception_logger.info(e.message)
            return {'code': -1, 'msg': '绑定失败'}

        return {'code': 0, 'msg': '绑定成功'}