#!coding=utf-8

from __future__ import unicode_literals, absolute_import, print_function
import json

from django.db import transaction

from api.tasks import order_task
from rpc.decorators import bind, bind_context
from rpc.tool.error_code import CODES, gen
from gm_types.pay import SUFPAY_STATUS
from gm_types.gaia import ORDER_STATUS
from gm_types.gaia import ORDER_OPERATION_TYPE
from gm_types.gaia import ORDER_OPERATION_ROLE
from api.tool.user_tool import get_user_from_context

from api.models import Doctor, Person
from api.models import Order
from weikuan.models import HospitalPay
from weikuan.manager.hospital_pay_manager import get_or_create_hospital_pay
from weikuan.views.pay import _refund_hospital_pay


@bind_context('api/hospital_pay/detail', login_required=True)
def hospital_pay_detail(ctx, hospital_pay_id):
    hospital_pay = HospitalPay.objects.get(id=hospital_pay_id)
    return hospital_pay.order_data()


@bind_context('api/hospital_pay/create', login_required=True)
def hospital_pay_create(ctx, order_id, device_id=None, ip=None):
    """创建尾款支付单"""
    try:
        order = Order.objects.get(pk=order_id, status=ORDER_STATUS.PAID)
    except:
        return gen(CODES.ORDER_NOT_FOUND)
    hospital_pay_id = get_or_create_hospital_pay(order)

    # 记录用户的设备标识,ip
    order_task.record_user_information.delay([order], hospital_pay_id, device_id, ip, ORDER_STATUS.NOT_PAID)
    result = {
        'hospital_pay_id': hospital_pay_id
    }
    return result


@bind_context('api/hospital_pay/cancel', login_required=True)
def hospital_pay_cancel(ctx, order_id, device_id, ip):
    with transaction.atomic():
        user = get_user_from_context(ctx)
        person = Person.objects.get(user=user)
        try:
            hospital_pay = HospitalPay.objects.select_for_update().get(order_id=order_id)
            if user != hospital_pay.order.user:
                raise HospitalPay.DoesNotExist()
        except:
            return gen(CODES.ORDER_NOT_FOUND)
        hospital_pay.operate(person, ORDER_OPERATION_TYPE.APPLY_REFUND, ORDER_OPERATION_ROLE.USER)

        # 记录用户的设备标识,ip
        order = Order.objects.get(pk=order_id)
        order_task.record_user_information.delay([order], hospital_pay.id, device_id, ip, ORDER_STATUS.WAIT_REFUNDED)
        if _refund_hospital_pay(ctx, hospital_pay):
            return gen(CODES.SUCCESS)
        else:
            return gen(CODES.REFUND_ERROR)


@bind_context('api/hospital_pay/pay_jump', login_required=True)
def hospital_pay_jump(ctx, hospital_pay_id):
    with transaction.atomic():
        user = get_user_from_context(ctx)
        person = Person.objects.get(user=user)
        try:
            hospital_pay = HospitalPay.objects.select_for_update().get(id=hospital_pay_id)
            if hospital_pay.order.user != user:
                return HospitalPay.DoesNotExist()
        except HospitalPay.DoesNotExist:
            return gen(CODES.ORDER_NOT_FOUND)
        if hospital_pay.status in (SUFPAY_STATUS.PAYING):
            hospital_pay.operate(person, ORDER_OPERATION_TYPE.PAYING, ORDER_OPERATION_ROLE.USER)
            return gen(CODES.SUCCESS)
        return gen(CODES.ORDER_PAID)

