# -*- coding: utf-8 -*-

import datetime

from django.dispatch import receiver
from django.db.models.signals import post_save, pre_save
from django.conf import settings
from gm_types.gaia import BDTRANSFER_OBJECT_STATE, SINGLE_TYPE

from api.models import Service, BDTransferSingleRecord, BDTransfer, BDTransferSingleRecordLog
from api.models import RefundOrder
from api.models import Person, UserAuthentication
from api.models.types import REFUND_STATUS
from api.tool.log_tool import logging_exception

from pay.tasks.alter_task import stock_alert
from pay.tasks.alter_task import refund_alert


@receiver(post_save, sender=Person)
def post_save_person_add_user_authentication(sender, instance, **kwargs):
    # we dont know phone info, return
    if not instance.phone:
        return

    # if already authenticated
    if UserAuthentication.objects.filter(user_id=instance.user_id).exists():
        return

    u = UserAuthentication.objects.create(user_id=instance.user_id, phone=instance.phone)
    u.save()


@receiver(pre_save, sender=Service)
def stock_monitor(sender, instance, **kwargs):
    if instance.pk is None:
        # exclude when the object is first created
        return
    try:
        old_service = Service.objects.get(pk=instance.pk)
        if instance.sell_num_limit == settings.STOCK_ALERT_THRESHOLD and old_service.sell_num_limit == settings.STOCK_ALERT_THRESHOLD + 1:
            if instance.is_online is True:
                now = datetime.datetime.now()
                if now > instance.start_time:
                    if instance.doctor.business_partener:
                        business_partener_email = instance.doctor.business_partener.email
                        stock_alert.delay(
                            service_id=instance.id,
                            service_name=instance.name,
                            current_stock=instance.sell_num_limit,
                            email=business_partener_email,
                        )
    except:
        logging_exception()


@receiver(post_save, sender=RefundOrder)
def refund_order_monitor(sender, **kwargs):
    refund_order = kwargs['instance']
    if refund_order.status in [REFUND_STATUS.ARBIT_APPROVE, REFUND_STATUS.DOCTOR_APPROVE]:
        refund_order_id = refund_order.id
        refund_alert.apply_async(
            args=(
                refund_order_id,
            ),
            countdown=settings.PAY_GATEWAY_TIMEOUT
        )


@receiver(post_save, sender=BDTransferSingleRecord)
def update_bdtransfer_object_state(sender, instance, **kwargs):
    # TODO: 如果是已撤销， 对应是什么
    # TODO: 此处应该有事务
    # http://wiki.wanmeizhensuo.com/pages/viewpage.action?pageId=11615549
    BDTransferSingleRecordLog.objects.create(singlerecord=instance, status=instance.status)
    single_status_to_bdtransfer_object_state = {
        SINGLE_TYPE.NO_ORDER_FORM: BDTRANSFER_OBJECT_STATE.HAS_SENT_SINGLE,
        SINGLE_TYPE.HAS_APPOINTMENT: BDTRANSFER_OBJECT_STATE.HAS_MADE_APPOINTMENT,
        SINGLE_TYPE.HAS_CONSULTATION: BDTRANSFER_OBJECT_STATE.HAS_CONSULTATION,
        SINGLE_TYPE.HAS_ORDER_FORM: BDTRANSFER_OBJECT_STATE.SINGLE_FINISHED,
        SINGLE_TYPE.HAS_TERMINATE: BDTRANSFER_OBJECT_STATE.HAS_TERMINATE,
    }
    bdtransfer = BDTransfer.objects.filter(id=instance.dbtransfer_id).first()
    if bdtransfer is None:
        return
    # if bdtransfer.object_state == BDTRANSFER_OBJECT_STATE.NOT_THROUGH_INFOMATION:
    #     return

    object_state = bdtransfer.object_state
    if instance.status == SINGLE_TYPE.HAS_CANCEL:
        return

    if instance.status == SINGLE_TYPE.HAS_TERMINATE:
        bd = BDTransferSingleRecord.objects.filter(dbtransfer_id=instance.dbtransfer_id)
        if not BDTransferSingleRecord.objects.filter(
                dbtransfer_id=instance.dbtransfer_id).exclude(status__in=[SINGLE_TYPE.HAS_CANCEL, SINGLE_TYPE.HAS_TERMINATE]).exists():
            bdtransfer.object_state = BDTRANSFER_OBJECT_STATE.HAS_PASSED_INFOMATION

        if not bd.exclude(status__in=[SINGLE_TYPE.HAS_CANCEL, SINGLE_TYPE.HAS_TERMINATE]).exists():
            bdtransfer.object_state = BDTRANSFER_OBJECT_STATE.HAS_PASSED_INFOMATION
        elif bd.filter(status=SINGLE_TYPE.HAS_CONSULTATION).exists():
            bdtransfer.object_state = BDTRANSFER_OBJECT_STATE.HAS_CONSULTATION
        elif bd.filter(status=SINGLE_TYPE.HAS_APPOINTMENT).exists():
            bdtransfer.object_state = BDTRANSFER_OBJECT_STATE.HAS_MADE_APPOINTMENT
        elif bd.filter(status=SINGLE_TYPE.NO_ORDER_FORM).exists():
            bdtransfer.object_state = BDTRANSFER_OBJECT_STATE.HAS_SENT_SINGLE
        bdtransfer.save(update_fields=['object_state'])
        return

    get_object_state = single_status_to_bdtransfer_object_state.get(instance.status)
    if get_object_state and get_object_state > bdtransfer.object_state:
        bdtransfer.object_state = get_object_state
        bdtransfer.save(update_fields=['object_state'])
