# coding=utf-8

import datetime

from django.db import IntegrityError
import pytz
from django.conf import settings

from api.models.message import PrivateMessagePush
from ..datatables import PrivateMessagePushDT
from rpc.decorators import bind_context, bind
from rpc.exceptions import RPCNotFoundException, RPCIntegrityError
from rpc.tool.dict_mixin import to_dict
from api.models.types import PRIVATE_MESSAGE_PUSH_STATUS
from rpc.tool.log_tool import info_logger
from api.tasks.private_message_push_task import send_private_message_ontime
from ..queries.privatemessagepush import PrivateMessagepushDQ

privatemessagepush_pre = 'hera/privatemessagepush'


@bind_context(privatemessagepush_pre + '/query')
def privatemessage_query(ctx, options):
    dqobj = PrivateMessagepushDQ()
    return dqobj.process(**options)


@bind_context(privatemessagepush_pre + '/list')
def privatemessagepush_datatable(request, req_data):
    dtobj = PrivateMessagePushDT(PrivateMessagePush)
    return dtobj.process(req_data)


@bind_context(privatemessagepush_pre + '/get')
def privatemessagepush_detail(ctx, id, options=None):
    try:
        message = PrivateMessagePush.objects.get(id=id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    data = to_dict(message, **options)
    return data


@bind_context(privatemessagepush_pre + '/edit')
def privatemessagepush_edit(ctx, id=None, data_info=None):
    if data_info is None:
        return None

    data_info['service_id'] = data_info.pop('service')
    data_info['doctor_id'] = data_info.pop('doctor')
    data_info['hospital_id'] = data_info.pop('hospital')
    if data_info['user_list']:
        data_info['order_status'] = None
    if id is None:
        try:
            message = PrivateMessagePush.objects.create(**data_info)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            message = PrivateMessagePush.objects.get(id=id)
            message.status = PRIVATE_MESSAGE_PUSH_STATUS.NOT_REVIEW
            for k, v in data_info.iteritems():
                setattr(message, k, v)
            message.save()
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException

    return message.id


def get_duration(eta):
    """
    返回距离发送时间的秒数
    """
    local_timezone = pytz.timezone(settings.TIME_ZONE)
    local_eta = local_timezone.localize(eta)
    now = datetime.datetime.now(local_timezone)
    duration = (local_eta - now).total_seconds()
    return duration


@bind(privatemessagepush_pre + '/audit')
def audit_push_message(message_id):
    """
    审核私信推送
    """
    try:
        message = PrivateMessagePush.objects.get(id=message_id)
    except PrivateMessagePush.DoesNotExists:
        return {'error': 1, 'message': u'私信推送不存在'}

    if message.status == PRIVATE_MESSAGE_PUSH_STATUS.OK:
        return {'error': 1, 'message': u'已经审核过了'}

    message.status = PRIVATE_MESSAGE_PUSH_STATUS.OK
    message.save()

    # 定时发送
    duration = get_duration(message.send_time)
    send_private_message_ontime.apply_async((message.id,), countdown=duration)

    return {'error': 0, 'message': 'success'}


@bind(privatemessagepush_pre + '/cancel_send')
def cancel_send(message_id):
    """
    私信推送撤回
    只有已经审核通过且未到发送时间的私信才可以撤回
    """
    try:
        message = PrivateMessagePush.objects.get(id=message_id)
    except PrivateMessagePush.DoesNotExists:
        return {'error': 1, 'message': u'私信推送不存在'}

    if message.status != PRIVATE_MESSAGE_PUSH_STATUS.OK:
        return {'error': 1, 'message': u'只有审核通过的私信才可以撤回'}

    now = datetime.datetime.now()
    send_time = message.send_time
    if now >= send_time:
        return {'error': 1, 'message': u'私信已发送不可以撤回'}

    message.status = PRIVATE_MESSAGE_PUSH_STATUS.NOT_REVIEW
    message.save()

    return {'error': 0, 'message': 'success'}
