# coding=utf-8
from hera.queries.shortmessagesend import ShortMessageSendDQ
from rpc.decorators import bind_context
from api.models import *
from django.db import IntegrityError, transaction
from rpc.exceptions import RPCIntegrityError, RPCNotFoundException
from rpc.tool.log_tool import info_logger
from rpc.tool.dict_mixin import to_dict
from sms.utils.smsfactory import send_sms
from django.db.models import Q
from django.utils import timezone
from django.conf import settings
from datetime import datetime


uri_pre = 'hera/shortmessagesend'


@bind_context(uri_pre + '/doctor/choices')
def doctor_choices(ctx, q='', page=1, num=30, initial=None, business=None, doctor_id=None):
    page = int(page)
    num = int(num)

    if initial is not None:
        if isinstance(initial, (list, tuple)):
            qry = Q(id__in=initial)
        else:
            qry = Q(id=initial)
    else:
        qry = Q(id__contains=q) | Q(name__contains=q)
        qry &= Q(user__isnull=False)
    # 关联医生
    if doctor_id:
        try:
            doctor = Doctor.objects.get(id=doctor_id)
            qry &= Q(hospital=doctor.hospital) & ~Q(id=doctor_id)
        except:
            pass

    if business is not None:
        if isinstance(business, (list, tuple)):
            qry &= Q(business_partener_id__in=business)
        else:
            qry &= Q(business_partener_id=business)
    query = Doctor.objects.using(settings.SLAVE_DB_NAME).filter(qry)
    total_count = query.count()
    start_pos = (page - 1) * num
    start_pos = start_pos if start_pos >= 0 else 0
    results = [
        {
            'id': obj.id,
            'text': u'{}:{}({})({})({})'.format(
                obj.id,
                obj.name,
                obj.hospital.name if hasattr(obj, 'hospital') and obj.hospital else None,
                obj.title if obj.doctor_type == DOCTOR_TYPE.DOCTOR else
                HOSPITAL_TYPE.getDesc(obj.hospital.hospital_type
                                      if hasattr(obj, 'hospital') and obj.hospital else None),
                u'在线' if obj.is_online else u'离线'
            ),

        } for obj in query[start_pos: start_pos + num]
        ]
    return {'total_count': total_count, 'results': results, 'page': page, 'num': num}


def many_save(modal, modal_instance, relation_modal, b_modal, datas=[]):
    b_modal_name = str(b_modal.__name__).lower()
    modal_id = '%s_id' % str(modal.__name__).lower()
    new_datas = set(b_modal.objects.filter(id__in=datas))
    old_datas = set(getattr(modal_instance, b_modal_name).all())
    for data_obj in (new_datas - old_datas):
        params = {modal_id: modal_instance.id, b_modal_name: data_obj}
        relation_modal.objects.get_or_create(**params)
    params_r = {modal_id: modal_instance.id, '%s__in' % str(b_modal.__name__).lower(): (old_datas - new_datas)}
    relation_modal.objects.filter(
        **params_r
    ).delete()


def send_message(message_obj):
    phone_list1 = message_obj.phone_list.split('\n')
    doctors = message_obj.doctor.all()
    services = message_obj.service.all()
    hospitals = message_obj.hospital.all()
    status = message_obj.order_status.split(',')
    filter_q = Q()
    for f in status:
        if f:
            filter_q = filter_q | Q(status=f)
    if doctors:
        phone_list1.extend(list(Order.objects.filter(
            service__doctor__in=doctors).filter(filter_q).values_list('phone', flat=True)))
    if services:
        phone_list1.extend(list(Order.objects.filter(
            service__in=services).filter(filter_q).values_list('phone', flat=True)))
    if hospitals:
        phone_list1.extend(list(Order.objects.filter(
            service__doctor__hospital__in=hospitals).filter(filter_q).values_list('phone', flat=True)))
    phone_list1 = map(lambda x: x.strip(), phone_list1)
    phone_list1 = list(set(phone_list1))
    if phone_list1 and (not phone_list1[0]):
        del phone_list1[0]
    # phone_list1 = ['18810408797', '18010473527']
    send_sms(
        phone=phone_list1,
        template_id=37,
        params=[{'msg': message_obj.content}],
        msg='',
        platform='md',
    )


@bind_context(uri_pre + '/query')
def shortmessagesend_query(ctx, options):
    dqobj = ShortMessageSendDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + '/edit')
@transaction.atomic
def shortmessagesend_edit(ctx, shortmessagesend_id=None, shortmessagesend_info=None, urls=None):
    if shortmessagesend_info is None:
        return None
    data_doctors = shortmessagesend_info.pop('doctor', [])
    data_services = shortmessagesend_info.pop('service', [])
    data_hospitals = shortmessagesend_info.pop('hospital', [])
    is_send = shortmessagesend_info.pop('is_send')
    if shortmessagesend_id is None:
        try:
            shortmessagesend = ShortMessageSend.objects.create(**shortmessagesend_info)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            shortmessagesend = ShortMessageSend.objects.get(id=shortmessagesend_id)
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
        for k, v in shortmessagesend_info.iteritems():
            setattr(shortmessagesend, k, v)
        shortmessagesend.save()
    # next save manytomany
    many_save(ShortMessageSend, shortmessagesend, ShortMessageSendDoctor, Doctor, data_doctors)
    many_save(ShortMessageSend, shortmessagesend, ShortMessageSendHospital, Hospital, data_hospitals)
    many_save(ShortMessageSend, shortmessagesend, ShortMessageSendService, Service, data_services)
    # next sendmessage
    if is_send:
        # send message
        send_message(shortmessagesend)
        shortmessagesend.send_status = True
        shortmessagesend.send_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        shortmessagesend.save()

    return shortmessagesend.id


@bind_context(uri_pre + '/get')
def shortmessagesend_get(ctx, shortmessagesend_id):
    """
    获取短信根据id
    """
    if shortmessagesend_id is None:
        return None
    try:
        shortmessagesend = ShortMessageSend.objects.get(id=shortmessagesend_id)
    except IntegrityError:
        raise RPCIntegrityError
    shortmessagesend_data = to_dict(shortmessagesend)
    return shortmessagesend_data
