# coding=utf-8
from __future__ import unicode_literals, absolute_import
import json
from pay.models import ApplePay, PaymentOrder
from django.conf import settings

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

from api.models import Order
from api.models import RefundOrder
from api.models import CashBackOrder
from api.models import NEW_CASH_BACK_STATUS
from api.models import Person
from api.models import ORDER_OPERATION_TYPE
from api.models import ORDER_OPERATION_ROLE
from api.manager import order_manager
from api.tool.user_tool import get_user_from_context
from api.tool.log_tool import apple_refund_logger

from pay.tool import own_tool
from pay.tool.new_order_tool import refund_send_notification_and_sms
from pay.tool.new_order_tool import cashback_send_notification_and_sms
from pay.tool.types import REFUND_TYPE
from pay.tool.order_lock_tool import lock
from pay.tool.order_lock_tool import is_locked
from pay.tool import apple_tool
from pay.models import ApplePayRefund


def pre_refund_operate(no_refund, dt_refund, no_order, dt_order, oid_paybill, money_refund, refund_notify_url):
    apple = ApplePay()
    result = apple.refund(
            no_refund=no_refund,
            dt_refund=dt_refund,
            no_order=no_order,
            dt_order=dt_order,
            oid_paybill=oid_paybill,
            money_refund=money_refund,
            refund_notify_url=refund_notify_url,
    )
    return result['ret_code']


@bind_context('pay/apple/prepay', login_required=True)
def apple_prepay(ctx, settlement_id):
    user = get_user_from_context(ctx)
    settlement = own_tool.is_my_settlement(user, settlement_id)
    dt_order = settlement.created_at.strftime('%Y%m%d%H%M%S')
    name_goods = settlement.name[:40]
    info_order = settlement.name[:255]
    money_order = settlement.real_payment

    apple = ApplePay()
    params = apple.pay_params(
            user_id=settlement.person_id,
            no_order=settlement.id,
            dt_order=dt_order,
            name_goods=name_goods,
            info_order=info_order,
            money_order=money_order,
    )
    return params


@bind_context('pay/apple/refund')
def apple_refund(ctx, order_id):
    try:
        refund_order = RefundOrder.objects.get(order_id=order_id)
    except RefundOrder.DoesNotExist:
        return gen(CODES.ORDER_NOT_FOUND)
    payment_order = PaymentOrder.objects.get(orders=refund_order.order_id)
    # applepay_settlement = ApplePaySettlement.objects.get(
    #         settlement=refund_order.order.settlementitem.settlement
    # )
    is_locked(order_id=order_id, refund_type=REFUND_TYPE.REFUND)
    refund_order.fee = refund_order.order.real_payment
    refund_order.save()

    no_refund = refund_order.id
    dt_refund = refund_order.created_at.strftime('%Y%m%d%H%M%S')
    # no_order = applepay_settlement.no_order_id
    # dt_order = applepay_settlement.dt_order.strftime('%Y%m%d%H%M%S')
    # oid_paybill = applepay_settlement.oid_paybill
    no_order = payment_order.out_trade_no
    dt_order = payment_order.pay_start_time.strftime('%Y%m%d%H%M%S')
    oid_paybill = payment_order.transaction_id
    money_refund = refund_order.fee
    refund_notify_url = settings.APPLEPAY_REFUND_NOTIFY_URL + '/{order_id}'.format(order_id=order_id)
    if '0000' == pre_refund_operate(no_refund, dt_refund, no_order, dt_order, oid_paybill, money_refund,
                                    refund_notify_url):
        lock(order_id=order_id, refund_type=REFUND_TYPE.REFUND)
        apple_refund_logger.info("order {order_id} pre-refund success!".format(order_id=order_id))
        return gen(CODES.SUCCESS)
    elif '5006' == pre_refund_operate(no_refund, dt_refund, no_order, dt_order, oid_paybill, money_refund,
                                      refund_notify_url):
        refund_order.low_balance = True
        refund_order.save()
        return gen(CODES.SUCCESS)
    return gen(CODES.REFUND_ERROR)


@bind_context('pay/apple/cashback', login_required=True)
def apple_cashback(ctx, order_id):
    try:
        cashback_order = CashBackOrder.objects.get(order_id=order_id)
    except CashBackOrder.DoesNotExist:
        return gen(CODES.ORDER_NOT_FOUND)

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

    payment_order = PaymentOrder.objects.get(orders=order_id)
    # applepay_settlement = ApplePaySettlement.objects.get(
    #         settlement=cashback_order.order.settlementitem.settlement
    # )

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

    no_refund = cashback_order.id
    dt_refund = cashback_order.created_at.strftime('%Y%m%d%H%M%S')
    # no_order = applepay_settlement.no_order_id
    # dt_order = applepay_settlement.dt_order
    # oid_paybill = applepay_settlement.oid_paybill
    no_order = payment_order.out_trade_no
    dt_order = payment_order.pay_start_time.strftime('%Y%m%d%H%M%S')
    oid_paybill = payment_order.transaction_id

    money_refund = cashback_order.fee
    refund_notify_url = settings.APPLEPAY_REFUND_NOTIFY_URL + '/{order_id}'.format(order_id=order_id)
    if '0000' == pre_refund_operate(no_refund, dt_refund, no_order, dt_order, oid_paybill, money_refund,
                                    refund_notify_url):
        lock(order_id=order_id, refund_type=REFUND_TYPE.CASHBACK)
        apple_refund_logger.info("order {order_id} pre-refund success!".format(order_id=order_id))
        return gen(CODES.SUCCESS)
    elif '5006' == pre_refund_operate(no_refund, dt_refund, no_order, dt_order, oid_paybill, money_refund,
                                      refund_notify_url):
        cashback_order.low_balance = True
        cashback_order.save()
        return gen(CODES.SUCCESS)
    return gen(CODES.REFUND_ERROR)


@bind('pay/apple/callback/refund')
def pay_alipay_callback_refund(order_id, trade_data):
    if _succeed_refund_operate(order_id, trade_data, REFUND_TYPE.REFUND):
        return
    else:
        return gen(CODES.REFUND_ERROR)


@bind('pay/apple/callback/cashback')
def pay_apple_callback_refund(order_id, trade_data):
    if _succeed_refund_operate(order_id, trade_data, REFUND_TYPE.CASHBACK):
        return
    else:
        return gen(CODES.REFUND_ERROR)


def _succeed_refund_operate(order_id, trade_data, refund_type):
    alipay_refund_logger.info(json.dumps(trade_data))
    apple_tool.check_is_from_apple(trade_data)
    sta_refund = trade_data['sta_refund']

    try:
        order = Order.objects.get(id=order_id)
    except Order.DoesNotExist:
        apple_refund_logger.error("Order whose trade_no {trade_no} not found!".format(order_id=order_id))
        return False

    operator = Person.objects.get(user_id=settings.BOSS)
    if sta_refund == '2':
        if refund_type == REFUND_TYPE.REFUND:
            try:
                refund_order = RefundOrder.objects.get(order=order)
            except RefundOrder.DoesNotExist:
                return gen(CODES.ORDER_NOT_FOUND)
            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(order)

            order_manager.send_order_refunded_event(refund_order.order)
            refund_send_notification_and_sms(order)

        if refund_type == REFUND_TYPE.CASHBACK:
            try:
                cashback_order = CashBackOrder.objects.get(order=order)
            except CashBackOrder.DoesNotExist:
                return gen(CODES.ORDER_NOT_FOUND)
            cashback_order.order.operate(operator, ORDER_OPERATION_TYPE.CASHBACKED, ORDER_OPERATION_ROLE.SYSTEM)
            cashback_send_notification_and_sms(order)

    # Recode the applepay response whether it's succeed or failed
    ApplePayRefund.objects.create_record(no_order=order_id, trade_data=trade_data)
    return True
