# -*- coding: utf8 -*-

from api.tool.user_tool import filter_user_nick_name

from doctor.models import Notification, Patient
from message.views.push import doctor_noti_doctor_ids

from rpc.tool.protocol import gmdoctor_protocol
from rpc.tool.log_tool import logging_exception

from gm_types.gaia import TYPES
from gm_types.doctor import NOTIFICATION_TYPE
from gm_types.push import PUSH_INFO_TYPE


class DoctorNotifyService(object):
    """send notification to doctor."""

    def __init__(self, doctor_id):
        self.doctor_id = doctor_id

    @classmethod
    def get_service(cls, doctor_id):
        return cls(doctor_id)

    def notify_new_reservation(self, reservation):
        """send notification when user create a new reservation."""
        self._noti_for_reservation(reservation, u'新的预约！{}用户申请了您的{}美购预约')

    def notify_user_cancel_reservation(self, reservation):
        """send notification when user cancel a reservation."""
        self._noti_for_reservation(reservation, u'预约取消：{}用户取消了您的{}美购预约')

    def notify_cancel_reservation(self, reservation):
        """send notification when doctor cancel a reservation."""
        self._noti_for_reservation(reservation, u'预约取消：您取消了{}用户的{}美购预约')

    def notify_confirm_reservation(self, reservation):
        """send notification when doctor confirm a reservation."""
        self._noti_for_reservation(reservation, u'预约确认！您确认了{}用户的{}美购预约')

    def _noti_for_reservation(self, reservation, expression):
        if not self.doctor_id or not reservation:
            return
        summary = expression.format(
            filter_user_nick_name(reservation.user),
            reservation.order.service.name,
        )
        ntype = NOTIFICATION_TYPE.RESERVATION
        try:
            Notification.objects.create(
                doctor_id=self.doctor_id,
                summary=summary,
                ntype=ntype,
                person_id=reservation.user.person.id,
                related_item_id=reservation.id,
                related_item_type=TYPES.RESERVATION,
                related_item_sub=reservation.status,
            )

            self._push_noti(ntype, summary)
        except:
            logging_exception()

    def notify_new_order(self, order):
        self._noti_for_order(order, u'新的订单！{}用户下单了您的{}美购', join=True)

    def notify_verify_order(self, order):
        self._noti_for_order(order, u'新的验证！{}用户验证了您的{}美购', join=True)

    def _noti_for_order(self, order, expression, join=False):
        """
            join: 这个操作是否加入医生的患者列表
        """
        if not self.doctor_id or not order:
            return
        summary = expression.format(
            filter_user_nick_name(order.user),
            order.service.name,
        )
        ntype = NOTIFICATION_TYPE.TRADE
        try:
            noti = Notification.objects.create(
                doctor_id=self.doctor_id,
                summary=summary,
                ntype=ntype,
                person_id=order.user.person.id,
                related_item_id=order.id,
                related_item_type=TYPES.ORDER,
                related_item_sub=order.status,
            )
            if join:
                Patient.join_patient_list(self.doctor_id, noti, order=order)

            self._push_noti(ntype, summary)
        except:
            logging_exception()

    def notify_new_refund(self, refund_order):
        self._noti_for_refund(refund_order, u'新的退款：{}用户申请了您的{}美购退款', join=True)

    def notify_reject_refund(self, refund_order):
        """send notification when doctor reject refund request."""
        self._noti_for_refund(refund_order, u'拒绝退款：您拒绝了{}用户的{}美购退款申请', join=True)

    def notify_user_cancel_refund(self, refund_order):
        """send notification when user cancel refund request."""
        self._noti_for_refund(refund_order, u'取消退款：{}用户取消了您的{}美购退款申请', join=True)

    def notify_confirm_refund(self, refund_order):
        self._noti_for_refund(refund_order, u'确认退款：您确认了{}用户的{}美购退款申请', join=True)

    def notify_finish_refund(self, refund_order):
        self._noti_for_refund(refund_order, u'退款完成：{}用户完成了您的{}美购退款', join=True)

    def _noti_for_refund(self, refund, expression, join=False):
        if not self.doctor_id or not refund:
            return
        summary = expression.format(
            filter_user_nick_name(refund.order.user),
            refund.order.service.name,
        )
        ntype = NOTIFICATION_TYPE.REFUND
        try:
            noti = Notification.objects.create(
                doctor_id=self.doctor_id,
                summary=summary,
                ntype=ntype,
                person_id=refund.order.user.person.id,
                related_item_id=refund.id,
                related_item_type=TYPES.REFUND_ORDER,
                related_item_sub=refund.status,
            )
            if join:
                Patient.join_patient_list(self.doctor_id, noti, refund=refund)

            self._push_noti(ntype, summary)
        except:
            logging_exception()

    def notify_user_create_first_topic(self, topic):
        # 外部别调用， see mothod 'doctor/notify/create_topic'
        """send notification when user create first topic for specified diary."""
        self._noti_for_topic(topic, u'新的案例！{}用户创建了您的{}案例', join=True)

    def notify_user_create_topic(self, topic):
        # 外部别调用， see mothod 'doctor/notify/create_topic'
        """send notification when user create new topic other than the first for diary."""
        self._noti_for_topic(topic, u'案例更新！{}用户更新了您的{}案例', join=True)

    def _noti_for_topic(self, topic, expression, join=False):
        if not self.doctor_id or not topic:
            return
        if not topic.get('diary_id'):
            return
        summary = expression.format(
            topic.get('nickname'),
            topic.get('nickname') if topic.get('related_service_name') else topic.get('title'),
        )
        try:
            noti = Notification.objects.create(
                doctor_id=self.doctor_id,
                summary=summary,
                ntype=NOTIFICATION_TYPE.USERCASE,
                person_id=topic.get('person_id'),
                related_item_id=topic.get('diary_id'),
                related_item_type=TYPES.DIARY,
                related_item_sub=topic.get('id'),
            )
            if join:
                Patient.join_patient_list(self.doctor_id, noti, topic=topic)
        except:
            logging_exception()

    def _push_noti(self, ntype, summary):
        doctor_noti_doctor_ids([self.doctor_id], alert=summary, extra={
            'type': PUSH_INFO_TYPE.GM_PROTOCOL,
            'pushUrl': gmdoctor_protocol.get_noti_list(
                ntype,
                title=NOTIFICATION_TYPE.getDesc(ntype)
            ),
        })
