# coding=utf-8
# create by esse at 2017/11/14

from __future__ import unicode_literals
import datetime
import json
import redis

from django.db.models import Q
from django.db.models import Count
from gm_types.doctor import PV_TYPE
from gm_types.gaia import HOSPITAL_TYPE, USER_RIGHTS_LEVEL

from hera.queries.tickets import create_by_advertise, cancel_by_advertise
from rpc.tool.log_tool import logging_exception
from ..models.advertise import Advertise_pv_stats, Advertise_conver_stats, AdWhiteList, PvOverNorm
from rpc.decorators import bind_context, bind
from ..models.merchant import Merchant
from ..models.doctor import Doctor
from ..models.advertise import IpBlackClient, DeviceBlackClient
from api.tool.datetime_tool import get_timestamp
from api.models import User, Message
from rpc.tool.error_code import gen, CODES
from api.tasks.stats_everyday_doctorconversation import async_lsat_month_pv_total_stats, async_new_conversation_everyday


def is_deal(ac_id):
    """
    判断当前会话是否已处理
    :param ac_id:
    :return:
    """
    try:
        ac = Advertise_conver_stats.objects.get(id=ac_id)
        doctor_user = User.objects.get(id=ac.doctor_user_id)
        messages = Message.objects.filter(send_time__gt=ac.time_str,
                                          conversation_id=ac.conversation_id,
                                          user_id=doctor_user.id
                                          )
        if messages.exists():
            return True
        else:
            return False

    except Exception as e:
        logging_exception()
        return False


@bind('doctor/advertise/pv_data')
def get_pv_data(doctor_id, time, pv_type, start, end):
    doctors = Doctor.objects.filter(hospital__hospital_type=HOSPITAL_TYPE.PRIVATE)\
        .values_list('id', flat=True)
    try:
        merchant = Merchant.objects.get(doctor_id=doctor_id)
    except Merchant.DoesNotExist:
        return {'total': 0, 'pv_list': []}
    if pv_type:
        aps = Advertise_pv_stats.objects.filter(
            merchant_id=merchant.id, pv_type=pv_type, stat_date=time, doctor_id__in=list(doctors)
        ).order_by('-time_str')
    else:
        aps = Advertise_pv_stats.objects.filter(
            merchant_id=merchant.id, stat_date=time, doctor_id__in=list(doctors)
        ).order_by('-time_str')
    data = {}
    data['total'] = aps.count()
    pv_list = [
        {
            'time': get_timestamp(ap.time_str),
            'pv_type': ap.pv_type,
            'pv_type_desc': PV_TYPE.getDesc(ap.pv_type),
            'page_name': ap.page_name,
            'city_name': ap.city_name,
            'user_name': ap.user_name,
            'age': datetime.datetime.now().year - ap.birthday.year if ap.birthday else '-',
            'tag': ','.join(json.loads(ap.tag)[0:3]) if ap.tag else '',
        } for ap in aps[start: end]
        ]
    data['pv_list'] = pv_list
    return data


@bind('doctor/advertise/message_data')
def get_message_data(doctor_id, time, start, end):
    doctors = Doctor.objects.filter(hospital__hospital_type=HOSPITAL_TYPE.PRIVATE)\
        .values_list('id', flat=True)
    try:
        merchant = Merchant.objects.get(doctor_id=doctor_id)
    except Merchant.DoesNotExist:
        return {'total': 0, 'message_list': []}
    acs = Advertise_conver_stats.objects.filter(
        merchant_id=merchant.id,
        stat_date=time,
        doctor_id__in=list(doctors)
    ).order_by('-time_str')
    data = {}
    data['total'] = acs.count()
    message_list = [
        {
            'time': get_timestamp(ac.time_str),
            'user_name': ac.user_name,
            'city_name': ac.city_name,
            'user_rights_level':
                USER_RIGHTS_LEVEL.getDesc(ac.user_rights_level) if ac.user_rights_level else '',
            'user_id': ac.user_id,
            'age': datetime.datetime.now().year - ac.birthday.year if ac.birthday else '-',
            'tag': ','.join(ac.tag.split(',')[0:3]) if ac.tag else '',
            'doctor_id': ac.doctor_id,
            'conversation_id': ac.conversation_id,
            'doctor_name': Doctor.objects.get(id=ac.doctor_id).name,
            'doctor_user_id': ac.doctor_user_id,
            'is_deal': is_deal(ac.id)
        } for ac in acs[start: end]
        ]
    data['message_list'] = message_list
    return data


@bind('doctor/advertise/down_by_advertise')
def down_by_advertise(doctor_id):
    """
    给商户降流
    :param doctor_id:商户的医生ID
    :return:
    """
    create_by_advertise(doctor_id=doctor_id)


@bind('doctor/advertise/cancel_by_advertise')
def punish_cancel_by_advertise(doctor_id):
    """
    给商户降流取消
    :param doctor_id:商户的医生ID
    :return:
    """
    cancel_by_advertise(doctor_id=doctor_id)


@bind('doctor/advertise/pv_expense')
def get_pv_expense(doctor_ids=None, stats_date=None):
    doctors = Doctor.objects.filter(hospital__hospital_type=HOSPITAL_TYPE.PRIVATE)\
        .values_list('id', flat=True)
    if not stats_date:
        stats_date = datetime.date.today() - datetime.timedelta(days=1)
    if doctor_ids:
        merchant_ids = [item.id for item in Merchant.objects.filter(doctor_id__in=doctor_ids,
                                                                    is_online=True)]
        query = Advertise_pv_stats.objects.filter(merchant_id__in=merchant_ids)
    else:
        query = Advertise_pv_stats.objects.filter(doctor_id__in=list(doctors))
    # 没有商户的在数据库存merchant_id = 0
    pv_data = query.filter(stat_date=stats_date) \
        .exclude(merchant_id=0).values('merchant_id').annotate(
        count=Count('id')
    ).values('merchant_id', 'count')
    if isinstance(stats_date, datetime.date):
        data = {'date': stats_date.strftime("%Y-%m-%d")}
    else:
        data = {'date': stats_date}
    pv_list = []
    for merchant in pv_data:
        try:
            doctor = Merchant.objects.get(id=merchant['merchant_id'], is_online=True).doctor
            sub_data = {
                'pv_num': merchant['count'],
                'doctor_id': doctor.id
            }
            # sub_data.update(doctor.get_doctor_base_info())
            pv_list.append(sub_data)
        except:
            continue
    data['pv_list'] = pv_list
    return data


@bind('doctor/advertise/message_expense')
def get_message_expense(doctor_ids=None, stats_date=None):
    # 获取私信具体信息之前先进行私信统计, 可能会导致超时
    # async_new_conversation_everyday()
    # ---
    doctors = Doctor.objects.filter(hospital__hospital_type=HOSPITAL_TYPE.PRIVATE)\
        .values_list('id', flat=True)
    if not stats_date:
        stats_date = datetime.date.today() - datetime.timedelta(days=1)
    else:
        stats_date = datetime.datetime.strptime(stats_date, "%Y-%m-%d")
    if doctor_ids:
        merchant_ids = [item.id for item in Merchant.objects.filter(doctor_id__in=doctor_ids,
                                                                    is_online=True)]
        query = Advertise_conver_stats.objects.filter(merchant_id__in=merchant_ids)
    else:
        query = Advertise_conver_stats.objects.filter(doctor_id__in=list(doctors))
    # 没有商户的在数据库存merchant_id = 0
    message_data = query.filter(stat_date=stats_date).exclude(merchant_id=0).values('merchant_id').annotate(
        count=Count('id')
    ).values('merchant_id', 'count')
    data = {'date': stats_date.strftime("%Y-%m-%d")}
    message_list = []
    for merchant in message_data:
        try:
            doctor = Merchant.objects.get(id=merchant['merchant_id'], is_online=True).doctor
            sub_data = {
                'message_num': merchant['count'],
                'doctor_id': doctor.id
            }
            # sub_data.update(doctor.get_doctor_base_info())

            message_list.append(sub_data)
        except:
            continue
    data['message_list'] = message_list
    return data


@bind('doctor/advertise/can_deduct')
def can_deduct(deduct_year, deduct_month):
    w_list = list(AdWhiteList.objects.all().values_list('doctor_id', flat=True))
    # 注册时间已超过90天的才会扣费
    time = datetime.datetime.now() - datetime.timedelta(days=90)
    m_list = list(Merchant.objects.filter(
        doctor__online_time__lte=time
    ).values_list('doctor_id', flat=True))
    cal_month = deduct_year * 100 + deduct_month
    p_list = list(
        PvOverNorm.objects.filter(cal_month=cal_month).values_list('doctor_id', flat=True)
    )
    doctor_ids = list(set(w_list) & set(p_list) & set(m_list))
    return doctor_ids


@bind('doctor/advertise/stat_pv_month')
def stat_pv():
    async_lsat_month_pv_total_stats.delay()
    return {'success': True}
