# -*- coding: UTF-8 -*-
import datetime

from celery import shared_task
from django.conf import settings
from django.db.models import Count

from api.models import Message, Conversation, UserTag, UserTagRelation, User, FreeMessage
from hera.utils import get_mail_instance
from hippo.models import Doctor, Advertise_conver_stats
from hippo.tool.user_tool import get_user_extra_by_user_id
from hippo.utils import get_merchant
from rpc.context import get_rpc_remote_invoker
from rpc.tool.log_tool import logging_exception, log_audit_hera
from gm_types.whisper import MESSAGE_SOURCE


def send_export_mail(subject, body, to_list, send=True):
    if not isinstance(to_list, (list, tuple)):
        to_list = [to_list]
    mail = get_mail_instance(subject, body, to_list)
    if send:
        mail.send()

    # audit log
    audit_data = {
        'audit_type': u'跑私信广告数据',
        'email_title': subject,
        'email_to': to_list,
        # 'excel_data': dt.xlsx,
        # 'excel_name': u'{}.xlsx'.format(subject),
    }
    log_audit_hera(audit_data)
    return mail


@shared_task
def async_new_conversation_everyday(asy_date=None):
    """
    每天同步医生的新私信数据
    新私信规则：仅对30天内主动发起私信的用户收费。医生主动发起的不收费
    :param asy_date:
    :return:
    """
    to_list = ['songzhenqi@igengmei.com', 'zhouyang@igengmei.com', 'yupengbo@igengmei.com']
    if not asy_date:
        asy_date = datetime.date.today() - datetime.timedelta(days=1)
    async_datetime_gt = datetime.datetime.combine(asy_date, datetime.datetime.min.time())
    async_datetime_lt = datetime.datetime.combine(asy_date + datetime.timedelta(days=1), datetime.datetime.min.time())

    exsits_datetime_gt = datetime.datetime(asy_date.year, asy_date.month, 1, 0, 0, 0)
    #获取kyc类型并且is_system=False的私信
    free_message_ids = list(FreeMessage.objects.filter(send_time__gte=async_datetime_gt, send_time__lt=async_datetime_lt, is_system=False).only('id').values_list('id', flat=True))
    #获取所有的非系统私信，排除掉kyc类型
    messages = Message.objects.filter(send_time__gte=async_datetime_gt, send_time__lt=async_datetime_lt,
                                      is_system=False, source=MESSAGE_SOURCE.UNKNOWN).exclude(id__in=free_message_ids)

    #获取所有医生的user_id, 医生主动发起不收费
    doctor_user_ids = list(Doctor.objects.all().values_list('user_id', flat=True))
    #昨天的所有会话id
    useless_c_ids = list(Message.objects.filter(
        send_time__gte=async_datetime_gt, send_time__lt=async_datetime_lt,
        user_id__in=doctor_user_ids, is_system=False, source=MESSAGE_SOURCE.UNKNOWN).exclude(id__in=free_message_ids).values_list('conversation_id', flat=True).distinct())
    #找到客户主动发起的, useless_c_ids是医生主动发起的
    for c_id in useless_c_ids:
        if messages.filter(conversation_id=c_id).order_by('send_time').first().user_id not in doctor_user_ids:
            useless_c_ids.remove(c_id)
    #所有用户发起的会话id集合
    conversations = messages.exclude(conversation_id__in=useless_c_ids).values('conversation_id').annotate(coun=Count('id'))
    count = conversations.count()
    begin = 0
    step = 1000
    # 去重数据
    old_data = Advertise_conver_stats.objects.filter(stat_date=asy_date)
    if old_data.exists():
        Advertise_conver_stats.objects.filter(stat_date=asy_date).delete()
    # 去重数据结束
    message_count = 0
    while begin < count:
        for item in conversations[begin:begin + 1000]:
            try:
                conversation_id = item.get('conversation_id')

                conversation = Conversation.objects.get(id=conversation_id)
                users = [conver_user.user_id for conver_user in conversation.user_status_set.all()]
                assert len(users) == 2
                doctors = Doctor.objects.filter(user__in=users)
                if len(doctors) == 1:
                    doctor = doctors[0]
                    user = [user_id for user_id in users if user_id != doctor.user.id]
                    assert len(user) == 1
                    user = user[0]
                    message = messages.filter(conversation=conversation, user_id=user).order_by('send_time').first()
                    exists_messages = Advertise_conver_stats.objects.filter(
                                                          time_str__gte=exsits_datetime_gt, 
                                                          time_str__lt=async_datetime_gt, 
                                                          conversation_id=conversation_id)
                    if not exists_messages:
                        user_extra = get_user_extra_by_user_id(user_id=user)
                        merchant = get_merchant(doctor.id)
                        info = {
                            'stat_date': asy_date,
                            'time_str': message.send_time,
                            'conversation_id': conversation_id,
                            'city_id': user_extra.city_id,
                            'city_name': user_extra.city.name if user_extra.city else '',
                            'province_id': user_extra.city.province.id if user_extra.city else '',
                            'province_name': user_extra.city.province.name if user_extra.city else '',
                            'doctor_id': doctor.id,
                            'merchant_id': merchant.id if merchant else 0,  # 没有商户ID的存零
                            'doctor_user_id': doctor.user.id,
                            'user_id': user,
                            'user_name': User.objects.get(id=user).username,
                            'birthday': user_extra.birthday,
                            'user_rights_level': user_extra.user_rights_level,
                            'membership_level': user_extra.membership_level,
                            'tag': u','.join([usertag.related_tag.name for usertag in
                                              UserTagRelation.objects.filter(user_id=user)]
                                             ),
                            'message_id': message.id
                        }
                        Advertise_conver_stats.objects.create(**info)
                        message_count += 1
            except Exception as e:
                logging_exception()
                continue
        begin += step
    body = u'{}私信广告跑数据成功, 共{}条'.format(asy_date.strftime("%Y-%m-%d"), message_count)
    send_export_mail(u'私信广告跑数据成功！', body, to_list)
    # rpc_invoker = get_rpc_remote_invoker()
    # stats_date = asy_date.strftime("%Y-%m-%d")
    # rpc_invoker['artemis/account/message/expense'](stats_date=stats_date).unwrap()


@shared_task()
def async_lsat_month_pv_total_stats():
    """
    统计上个月PV的浏览量
    :return:
    """
    to_list = ['yupengbo@igengmei.com', 'zhouyang@igengmei.com', 'songzhenqi@igengmei.com']
    date_now = datetime.date.today()
    date_this_month = datetime.date(date_now.year, date_now.month, 1)
    date_last_month = (date_this_month - datetime.timedelta(1)).replace(day=1)
    # datetime_this_month = datetime.datetime.strptime(str(date_this_month), '%Y-%m-%d')
    # datetime_last_month = datetime.datetime.strptime(str(date_last_month), '%Y-%m-%d')
    date_today_int = date_now.strftime('%Y%m')

    from hippo.models import Advertise_pv_stats
    res_date = Advertise_pv_stats.objects.filter(time_str__gte=date_last_month,
                                                 time_str__lt=date_this_month). \
        values('merchant_id').annotate(total=Count('id'))
    message_count = 0
    for item in res_date:
        try:
            if item['total'] >= settings.PV_LIMIT:
                print 1, item['merchant_id']
                from hippo.models import Merchant
                from hippo.models import PvOverNorm
                old_date = PvOverNorm.objects.filter(doctor_id=Merchant.objects.get(id=item['merchant_id'],
                                                                                    is_online=True).doctor_id,
                                                     cal_month=date_today_int)
                if old_date.exists():
                    continue
                PvOverNorm.objects.create(
                    doctor_id=Merchant.objects.get(id=item['merchant_id'],
                                                   is_online=True).doctor_id,
                    pv_total=item['total'],
                    cal_month=date_today_int
                )
                message_count += 1
        except:
            logging_exception()
            continue

    total = PvOverNorm.objects.filter(cal_month=date_today_int).count()
    body = u'{}广告PV统计跑数据成功, 上月PV超过3000的商户共{}条'.format(date_now.strftime("%Y-%m"), total)
    send_export_mail(u'广告PV统计跑数据成功！', body, to_list)


@shared_task()
def async_conversation_unread_num():
    """
    每日更新前1日的未读数不同步的情况
    :return:
    """
    now = datetime.datetime.now()
    time = now - datetime.timedelta(days=1)
    from services.unread.stat import UserUnread
    from api.models import ConversationUserStatus
    from api.models.user import User
    import message.signals as message_signals
    cus = ConversationUserStatus.objects.filter(read_status=False, last_reply_time__gte=time, last_reply_time__lte=now)
    for cu in cus:
        # 判断这些已读的cus在redis中是否还有未读数留存
        if UserUnread(cu.user_id).get_conversation_unread(cu.conversation_id) > 0:
            view_user = User.objects.get(id=cu.user_id)
            from services.notify import notify
            uids_1, uids_2 = cu.conversation.user_ids()
            # 清除redis未读数
            notify("conversation/clear", user_id=view_user.id, data={
                'conversation_id': cu.conversation_id,
                'send_uid': view_user.id,
                'send_nickname': view_user.last_name,
                'target_uid': uids_2 if uids_1 == view_user.id else uids_1,
            })
            # 通知es更改已读状态
            message_signals.post_touch_conversation(view_user, cu.conversation)
            print('{}:{}'.format(cu.user_id, cu.conversation_id))
