# coding=utf-8
import datetime
from django.db import transaction

from gm_types.pay import CHANNEL
from gm_types.gaia import PAYMENT_CHANNEL, SETTLEMENT_TYPE

from rpc.tool.protocol import PushUrlProtocol
from rpc.tool.error_code import gen
from rpc.tool.error_code import CODES
from rpc.all import get_rpc_remote_invoker
from api.tool.notification_tool import send_notification
from api.tool.log_tool import logging_exception
from api.tool.order_tool import push_cash_back_message
from pay.models import WechatRefund
from pay.models import AlipayRefund
from services.doctor_notify_service import DoctorNotifyService

_CHANNEL_TO_PAYMENT_CHANNEL = {
    CHANNEL.LIANLIAN: PAYMENT_CHANNEL.APPLEPAY,
    CHANNEL.WECHAT: PAYMENT_CHANNEL.WECHAT,
    CHANNEL.ALIPAY: PAYMENT_CHANNEL.ALIPAY,
}


def get_channel_to_payment_channel(channel):
    return _CHANNEL_TO_PAYMENT_CHANNEL[channel]


def get_actual_refund_amount(order):
    refund_amount = order.payment
    the_settleitem = None
    settlement_type = SETTLEMENT_TYPE.NORMAL_ORDER
    try:
        the_settleitem = order.settlementitem
        settlement_type = the_settleitem.settlement.settlement_type
    except:
        pass
    if the_settleitem:
        if order.real_payment <=0 :
            # 老订单, 没有按照比例分配
            refund_amount = the_settleitem.get_actual_refund()
            if settlement_type == SETTLEMENT_TYPE.ZERO_ORDER:  # 零元单
                return 0
            else:
                if refund_amount <= 0:
                    return gen(CODES.CAN_NOT_APPLY_REFUND_SINCE_COUPON_GT_PAYMENT)
        else:
            # 新订单,已算好退款额度
            refund_amount = order.real_payment
    return refund_amount


def refund_send_notification_and_sms(order):
    try:
        get_rpc_remote_invoker()['plutus/insurance/lose_efficacy'](order_id=order.id).unwrap()
    except:
        logging_exception()
    service_name = order.service.name + order.order_multiattribute
    order_id = order.id
    refund_date = datetime.datetime.now().strftime('%Y/%m/%d %H:%M')
    refund_amount = int(order.refund.fee)
    buyer_user_id = order.user.id
    _notification(service_name, order_id, refund_date, buyer_user_id, refund_amount, opera_type=u'退款')
    from api.tool.order_tool import push_refund_message
    push_refund_message(order)

    try:
        # 处理掉自动创建的空日记本
        diary = order.diary
        if diary and not diary.rate_count and not diary.topics.all():
            diary.is_online = False
            diary.save()
    except:
        logging_exception()
    from services.notify import notify
    notify('order/delete', doctor_id=order.service.doctor_id)
    ss = DoctorNotifyService.get_service(order.service.doctor_id)
    ss.notify_finish_refund(order.refund)


def cashback_send_notification_and_sms(order):
    service_name = order.service.name + order.order_multiattribute
    order_id = order.id
    refund_date = datetime.datetime.now().strftime('%Y/%m/%d %H:%M')
    if order.cash_back_fee:
        refund_amount = order.cash_back_fee
    else:
        refund_amount = order.service_price * 0.05
    buyer_user_id = order.user.id
    refund_amount = int(refund_amount)
    _notification(service_name, order_id, refund_date, buyer_user_id, refund_amount, opera_type=u'返现')
    push_cash_back_message(order, refund_amount)


def _notification(service_name, order_id, refund_date, buyer_user_id, refund_amount, opera_type):
    notification_content = u'''亲爱的美人，您的美购订单 {order_id} {opera_type}受理成功，{refund_amount}元金额已原路返还，请注意查收下付款账户及付款银行卡。\n【如何查看？】\n（1）支付宝钱包：财富-余额-账户余额-根据所长私信日期查询 \n（2）支付宝电脑端：登录-点击账户余额最右侧“查看”-根据所长私信日期查询，支付宝为即时到账哦 \n（3）微信支付：我-钱包-右上角「...」-点击「交易记录」查看-根据所长私信日期查询
                     '''.format(
        service_name=service_name,
        order_id=order_id,
        refund_date=refund_date,
        opera_type=opera_type,
        refund_amount=refund_amount,
    )
    send_notification(
        buyer_user_id,
        u'%s成功' % opera_type,
        notification_content,
        PushUrlProtocol.ORDER_DETAIL.format(id=order_id)
    )


def change_wechat_order_status(wechat_order, wechat_data):
    wechat_order.out_refund_no = wechat_data.get("out_refund_no")
    wechat_order.save()


def change_wechat_refund(order, wechat_data):
    refund_id = wechat_data.get("refund_id")
    if refund_id:
        refund, created = WechatRefund.objects.get_or_create(refund_id=refund_id)
        refund.order_no = order.id
        refund.nonce_str = wechat_data.get("nonce_str")
        refund.refund_fee = int(wechat_data.get("refund_fee"))
        refund.cash_refund_fee = int(wechat_data.get("cash_refund_fee"))
        refund.out_trade_no = wechat_data.get("out_trade_no")
        refund.out_refund_no = wechat_data.get("out_refund_no")
        refund.save()
    else:
        WechatRefund.objects.get_or_create(
            order_no=order.id,
            err_code=wechat_data.get("err_code")
        )


def change_alipay_refund(order, alipay_data):
    order_no = order.id
    trade_no, fee, trade_status = alipay_data['result_details'].split('^')
    refund_fee = int(float(fee))  # fee must be an integer!
    batch_no = alipay_data['batch_no']
    notify_id = alipay_data['notify_id']

    refund = AlipayRefund.objects.create(
        order_no=order_no,
        refund_fee=refund_fee,
        trade_no=trade_no,
        batch_no=batch_no,
        trade_status=trade_status,
        notify_id=notify_id
    )
