# -*- encoding: utf-8 -*-
"""
@File    : ComboCronPushController.py
@Time    : 2022/7/8 19:52
@Author  : stephen
@Email   : zhangdongming@asj6.wecom.work
@Software: PyCharm
"""
import logging
import time
import traceback

from django.db.models import Q
from django.views import View

from Model.models import UnicomComboOrderInfo, UnicomDeviceInfo, GatewayPush, SysMsgModel, UnicomFlowPush, Device_User
from Object.AliyunSmsObject import AliyunSmsObject
from Object.ResponseObject import ResponseObject
from Service.GatewayService import GatewayPushService


class ComboCronPushView(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):
        print(request_dict)
        print(request)
        response = ResponseObject()
        if operation == 'expire-push':
            return self.combo_expire_push(response)
        elif operation == 'warning-push':
            return self.flow_warning_push(response)
        else:
            return response.json(404)

    @classmethod
    def combo_expire_push(cls, response):
        """
        套餐到期预警通知，分别7前3天前消息推送
        """
        logger = logging.getLogger('info')
        logger.info('进入流量包过期消息推送')
        try:
            now_time = int(time.time())
            combo_order_qs = UnicomComboOrderInfo.objects.filter(
                ~Q(status=2) & Q(expire_time__gt=now_time + 3600 * 144) & Q(
                    expire_time__lte=(now_time + 3600 * 168)), is_del=False).values()
            if combo_order_qs.exists():
                cls.phone_msg_push(combo_order_qs)
            combo_order_qs = UnicomComboOrderInfo.objects.filter(
                ~Q(status=2) & Q(expire_time__gt=now_time + 3600 * 48) & Q(
                    expire_time__lte=(now_time + 3600 * 72)), is_del=False).values()
            if combo_order_qs.exists():
                cls.phone_msg_push(combo_order_qs)
            return response.json(0)
        except Exception as e:
            print(e.args)
            ex = traceback.format_exc()
            print(ex)
            return response.json(177, ex)

    @classmethod
    def phone_msg_push(cls, combo_order_qs):
        """
        消息推送
        """
        now_time = int(time.time())
        for item in combo_order_qs:
            iccid = item['iccid']
            device_info = UnicomDeviceInfo.objects.filter(iccid=iccid).values()
            if not device_info.exists():
                continue
            nickname = device_info.first()['serial_no']
            user_id = device_info.first()['user_id']
            if not user_id:
                continue

            # 查询推送配置数据
            push_qs = GatewayPush.objects.filter(user_id=user_id, logout=False). \
                values('user_id', 'app_bundle_id', 'app_type', 'push_type', 'token_val', 'm_code', 'lang', 'tz')
            if not push_qs.exists():
                continue
            for push_vo in push_qs:
                kwargs = {
                    'n_time': now_time,
                    'event_type': 1,
                    'nickname': nickname,
                }

                push_type = push_vo['push_type']
                token_val = push_vo['token_val']
                lang = push_vo['lang']
                app_bundle_id = push_vo['app_bundle_id']

                # 获取推送所需数据
                msg_title = GatewayPushService.get_msg_title(app_bundle_id, nickname)
                if lang == 'cn':
                    sys_msg_text = "温馨提示：尊敬的客户，您" + nickname + "设备4G流量套餐将在" + time.strftime("%Y-%m-%d", time.localtime(
                        item['expire_time'])) + "到期"
                else:
                    sys_msg_text = 'Dear customer,the flow package for your device ' + nickname + ' will expire on ' + \
                                   time.strftime('%m-%d-%y', time.localtime(item['expire_time']))
                kwargs['app_bundle_id'] = app_bundle_id
                kwargs['token_val'] = token_val
                kwargs['msg_title'] = msg_title
                kwargs['msg_text'] = sys_msg_text
                cls.sys_msg_save(user_id, nickname, now_time, sys_msg_text)
                if not cls.msg_push(push_type, **kwargs):
                    continue
        return True

    @classmethod
    def sys_msg_save(cls, user_id, serial_no, n_time, text_msg):
        """
        系统消息存库
        """
        logger = logging.getLogger('info')
        try:
            data = {'addTime': n_time, 'updTime': n_time, 'userID_id': user_id, 'eventType': 0, 'msg': text_msg,
                    'uid': serial_no}
            SysMsgModel.objects.create(**data)
        except Exception as e:
            logger.info('---4G流量存库异常--- {}'.format(repr(e)))

    @classmethod
    def flow_warning_push(cls, response):
        """
        流量到期或者流量预警消息推送
        """
        logger = logging.getLogger('info')
        flow_push_qs = UnicomFlowPush.objects.filter(status=0)
        if not flow_push_qs.exists():
            return response.json(0)
        for item in flow_push_qs:
            try:
                user_id = item.user_id
                if not user_id:
                    continue
                user_push_qs = GatewayPush.objects.filter(user_id=user_id)
                if not user_push_qs:
                    continue
                now_time = int(time.time())
                # 查询推送配置数据
                push_qs = GatewayPush.objects.filter(user_id=user_id, logout=False). \
                    values('user_id', 'app_bundle_id', 'app_type', 'push_type', 'token_val', 'm_code', 'lang', 'tz')
                if not push_qs.exists():
                    continue
                usage = cls.flow_split(item.flow_total_usage)
                total = cls.flow_split(item.flow_total)
                usable = cls.flow_split(item.flow_total - item.flow_total_usage)
                msg = False
                if item.type != 0 and item.type != 1:
                    unicom_order_qs = UnicomComboOrderInfo.objects.filter(id=item.combo_order_id) \
                        .values('combo__combo_name')
                    combo_name = unicom_order_qs.first()['combo__combo_name'] if unicom_order_qs.exists() else ''
                    sys_msg = cls.get_sys_msg_text(item.serial_no, combo_name, item.type)
                    msg = True
                else:
                    user_qs = Device_User.objects.filter(userID=user_id).values('phone')
                    if user_qs.exists() and user_qs.first()['phone']:
                        params = u'{"devname":"' + item.serial_no + '","usage":"流量' + usage + '","usable":"流量' + \
                                 usable + '","total":"流量共' + total + '"}'
                        cls.send_aliyun_sms(user_qs.first()['phone'], params, 'SMS_246100414')
                    sys_msg = cls.get_msg_text(item.serial_no, push_qs[0]['lang'], total, usage, usable)
                for push_vo in push_qs:
                    kwargs = {
                        'n_time': now_time,
                        'event_type': 1,
                        'nickname': item.serial_no,
                    }
                    push_type = push_vo['push_type']
                    token_val = push_vo['token_val']
                    lang = push_vo['lang']
                    app_bundle_id = push_vo['app_bundle_id']

                    # 获取推送所需数据
                    msg_title = GatewayPushService.get_msg_title(app_bundle_id, item.serial_no)
                    sys_msg_text = sys_msg if msg else cls.get_msg_text(item.serial_no, lang, total, usage, usable)
                    kwargs['app_bundle_id'] = app_bundle_id
                    kwargs['token_val'] = token_val
                    kwargs['msg_title'] = msg_title
                    kwargs['msg_text'] = sys_msg_text
                    if not cls.msg_push(push_type, **kwargs):
                        continue
                cls.sys_msg_save(user_id, item.serial_no, now_time, sys_msg)
                # 修改推送状态
                UnicomFlowPush.objects.filter(id=item.id).update(status=1)
            except Exception as e:
                logger.info('出错了~4G流量推送消息异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                continue
        return response.json(0)

    @staticmethod
    def get_msg_text(serial_no, lang, total, usage, usable):
        """
        app消息推送内容
        """
        if lang == 'cn':
            sys_msg_text = "温馨提示：尊敬的客户，您" + serial_no + "设备当前套餐总流量共" + total + "，已使用" + \
                           usage + "" + "，剩余" + usable + ""
        else:
            sys_msg_text = 'Warm tip: Dear customer, the total traffic of your ' + serial_no + \
                           ' device is ' + total + 'g in the current package. ' + usage + \
                           ' has been used and ' + usable + ' is left'
        return sys_msg_text

    @staticmethod
    def msg_push(push_type, **kwargs):
        """
        app推送
        """
        logger = logging.getLogger('info')
        try:
            # ios apns
            if push_type == 0:
                GatewayPushService.ios_apns_push(**kwargs)
            # android gcm
            elif push_type == 1:
                GatewayPushService.android_fcm_push(**kwargs)
            # android 极光推送
            elif push_type == 2:
                GatewayPushService.android_jpush(**kwargs)
            return True
        except Exception as e:
            logger.info('流量预警推送异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return False

    @staticmethod
    def send_aliyun_sms(phone, params, temp_code):
        """
        推送阿里云国内短信通知
        """
        sign = '周视'
        ali_sms = AliyunSmsObject()
        ali_sms.send_code_sms_cloud(phone, params, sign, temp_code)

    @staticmethod
    def flow_split(flow):
        """
        流量保留两位小数并带单位
        """
        if flow >= 1024:
            flow = flow / 1024
            return str(round(flow, 2)) + "G"
        else:
            return str(round(flow, 2)) + "M"

    @staticmethod
    def get_sys_msg_text(serial_no, combo_name, sys_type):
        """
        获取系统消息文本
        @return:
        """
        if sys_type == 4:
            sys_msg_text = "温馨提示：尊敬的客户，您" + serial_no + "设备当前4G" + combo_name + "已到期"
        elif sys_type == 3:
            sys_msg_text = "温馨提示：尊敬的客户，您" + serial_no + "设备当前4G" + combo_name + "已激活"
        else:
            sys_msg_text = "温馨提示：尊敬的客户，您" + serial_no + "设备当前4G" + combo_name + "已用完"
        return sys_msg_text
