# coding=utf-8
from __future__ import absolute_import, unicode_literals

import json

from django.conf import settings

from rpc.decorators import bind
from rpc.decorators import bind_context
from rpc.tool.error_code import CODES, gen

from api.models import CashBackOrder
from api.models import RefundOrder
from api.models import Person
from api.models import NEW_CASH_BACK_STATUS
from api.models import REFUND_STATUS
from api.models import ORDER_OPERATION_TYPE
from api.models import ORDER_OPERATION_ROLE
from api.models import Settlement, SETTLEMENT_STATUS
from api.manager import order_manager

from pay.models import Wechat, PaymentOrder
from pay.tool import wechat_pay_tool
from pay.tool.new_order_tool import refund_send_notification_and_sms
from pay.tool.new_order_tool import change_wechat_refund
from pay.tool.new_order_tool import cashback_send_notification_and_sms
from pay.tool.order_lock_tool import lock
from pay.tool.order_lock_tool import is_locked
from pay.tool.types import REFUND_TYPE
from pay.tool.new_order_tool import get_actual_refund_amount


@bind_context('pay/wechat/prepay', login_required=True)
def pay_wechat_prepay(ctx, settlement_id, ip, openid, is_mweb=True, is_wechat_app=False):
    # 默认这个接口都是M站PC站调用, 目前客户端微信支付在backend上
    try:
         settlement = Settlement.objects.get(pk=settlement_id)
    except Settlement.DoesNotExist:
        return gen(CODES.ORDER_NOT_FOUND)

    if settlement.status == SETTLEMENT_STATUS.PAID:
        return gen(CODES.SETTLEMENT_PAID)

    if settlement.status == SETTLEMENT_STATUS.CANCEL:
        return gen(CODES.SETTLEMENT_CANCELED)

    if is_wechat_app:
        wechat = wechat_pay_tool.get_wechat_obj_by_name(wechat_pay_tool.WECHAT_OBJ_NAME_FOR_WECHAT_APP)
        result = wechat.unifiedorder(
            settlement_id=settlement_id,
            ip=ip,
            fee=100 * settlement.real_payment,
            body=u'更美',
            detail=settlement.name,
            openid=openid,
            notify_url=settings.M_WECHAT_NOTIFY_URL
        )
    elif is_mweb:
        wechat = wechat_pay_tool.get_wechat_obj_by_name(wechat_pay_tool.WECHAT_OBJ_NAME_FOR_MWEB)
        result = wechat.unifiedorder(
            settlement_id=settlement_id,
            ip=ip,
            fee=100 * settlement.real_payment,
            body=u'更美',
            detail=settlement.name,
            openid=openid,
            notify_url=settings.M_WECHAT_NOTIFY_URL
        )
    else:
        wechat = wechat_pay_tool.get_wechat_obj_by_name(wechat_pay_tool.WECHAT_OBJ_NAME_FOR_APP)
        result = wechat.unifiedorder_for_app(
            out_trade_no=settlement_id,
            ip=ip,
            fee=100 * settlement.real_payment,
            body=u'更美',
            detail=settlement.name,
            notify_url=settings.M_WECHAT_NOTIFY_URL
        )

    return result


@bind("pay/wechat/refund/new")
def pay_wechat_refund(order_id):
    try:
        refund_order = RefundOrder.objects.get(order_id=order_id)
    except RefundOrder.DoesNotExist:
        return gen(CODES.ORDER_NOT_FOUND)

    is_locked(order_id=order_id, refund_type=REFUND_TYPE.REFUND)

    # 退款时现算退款金额, 我是非常不赞成的
    # 最重要改成申请退款时, 就算出退款金额
    refund_order.fee = get_actual_refund_amount(refund_order.order)
    refund_order.save()

    try:
        payment_order = PaymentOrder.objects.get(orders=order_id)
    except PaymentOrder.DoesNotExist:
        raise gen(CODES.ORDER_CAN_NOT_REFUND)

    wechat_notify_data = json.loads(payment_order.notify_data)
    wechat_app_id = wechat_notify_data['appid']
    wechat_obj_name = wechat_pay_tool.get_wechat_obj_name_by_appid(wechat_app_id)
    wechat = wechat_pay_tool.get_wechat_obj_by_name(wechat_obj_name)

    # 商户同意退款
    # 商户超时操作, 自动默认退款
    # 仲裁同意退款
    if refund_order.status not in (
            REFUND_STATUS.DOCTOR_APPROVE,
            REFUND_STATUS.REFUND_APPLY_SELLER_TIMEOUT,
            REFUND_STATUS.ARBIT_APPROVE):
        raise gen(CODES.ORDER_REFUDN_STATUS_ERROR)

    operator = Person.objects.get(user_id=settings.BOSS)
    wechat_data = wechat.refund(payment_order.transaction_id, refund_order.id, payment_order.total_fee,
                                refund_order.fee * 100)
    if not wechat_data.get('err_code'):
        lock(order_id=order_id, refund_type=REFUND_TYPE.REFUND)
        # TODO: 移到一起
        refund_order.order.operate(operator, ORDER_OPERATION_TYPE.REFUNDED, ORDER_OPERATION_ROLE.SYSTEM)

        from api.tool.order_tool import send_momo_stat_log_info_when_order_refunded
        send_momo_stat_log_info_when_order_refunded(refund_order.order)

        order_manager.send_order_refunded_event(refund_order.order)

        # TODO END
        refund_send_notification_and_sms(refund_order.order)
        # change_wechat_order_status(wechat_order, wechat_data)
    else:
        optype = ORDER_OPERATION_TYPE.REFUND_ERROR
        if wechat_data.get('err_code_des') == u"超期订单不允许退款":
            optype = ORDER_OPERATION_TYPE.TAG_STALE_REFUND
        refund_order.order.operate(operator, optype, ORDER_OPERATION_ROLE.SYSTEM)
    change_wechat_refund(refund_order.order, wechat_data)


@bind("pay/wechat/cashback/new")
def pay_wechat_refund(order_id):
    try:
        cashback_order = CashBackOrder.objects.get(order_id=order_id)
    except CashBackOrder.DoesNotExist:
        raise gen(CODES.ORDER_NOT_FOUND)
    is_locked(order_id=order_id, refund_type=REFUND_TYPE.CASHBACK)

    try:
        payment_order = PaymentOrder.objects.get(orders=order_id)
    except PaymentOrder.DoesNotExist:
        raise gen(CODES.ORDER_CAN_NOT_REFUND)

    wechat_notify_data = json.loads(payment_order.notify_data)
    wechat_app_id = wechat_notify_data['appid']
    wechat_obj_name = wechat_pay_tool.get_wechat_obj_name_by_appid(wechat_app_id)
    wechat = wechat_pay_tool.get_wechat_obj_by_name(wechat_obj_name)

    if cashback_order.status != NEW_CASH_BACK_STATUS.WAIT:
        raise gen(CODES.ORDER_CAN_NOT_REFUND)

    wechat_data = wechat.refund(payment_order.transaction_id, cashback_order.id, payment_order.total_fee,
                                cashback_order.fee * 100)
    operator = Person.objects.get(user_id=settings.BOSS)

    if not wechat_data.get('err_code'):
        lock(order_id, refund_type=REFUND_TYPE.CASHBACK)
        cashback_order.order.operate(operator, ORDER_OPERATION_TYPE.CASHBACKED, ORDER_OPERATION_ROLE.SYSTEM)
        cashback_send_notification_and_sms(cashback_order.order)
        # change_wechat_order_status(wechat_order, wechat_data)
    else:
        optype = ORDER_OPERATION_TYPE.CASHBACK_ERROR
        if wechat_data.get('err_code_des') == u"超期订单不允许退款":
            optype = ORDER_OPERATION_TYPE.TAG_STALE_CASHBACK
        cashback_order.order.operate(operator, optype, ORDER_OPERATION_ROLE.SYSTEM)

    change_wechat_refund(cashback_order.order, wechat_data)
