#!coding=utf-8

from __future__ import unicode_literals, absolute_import, print_function
import json

from django.db import transaction
from gm_types.gaia import ORDER_STATUS
from gm_types.gaia import ORDER_OPERATION_TYPE
from gm_types.gaia import ORDER_OPERATION_ROLE
from rpc.decorators import bind, bind_context
from rpc.tool.error_code import CODES, gen
from api.tool.user_tool import get_user_from_context
from api.models import Doctor
from api.models import Person
from maidan.models.order import MaidanOrder
from maidan.models.setting import MaidanSetting
from maidan.manager.order_manager import create_order
from maidan.tasks.order_task import maidan_order_create_event


@bind('api/maidan/is_open')
def support_maidan(doctor_id):
    try:
        s = MaidanSetting.objects.get(doctor=doctor_id)
        return s.is_open
    except MaidanSetting.DoesNotExist:
        return False


@bind('api/maidan/discount')
def doctor_discount(doctor_id):
    try:
        s = MaidanSetting.objects.get(doctor=doctor_id)
        discount = s.doctor_discount_rate - s.gengmei_offers_rate
    except MaidanSetting.DoesNotExist:
        return gen(CODES.DOCTOR_NOT_FOUND)
    return discount


@bind_context('api/maidan/status', login_required=True)
def maidan_status(ctx):
    user = get_user_from_context(ctx)
    orders = MaidanOrder.objects.filter(user=user)
    status = [order.status for order in orders]
    return status


@bind_context('api/maidan/list', login_required=True)
def maidan_list(ctx, start_num=0, count=10, type=None):
    start_num, count = int(start_num), int(count)
    user = get_user_from_context(ctx)
    unpaid_status = [ORDER_STATUS.NOT_PAID, ORDER_STATUS.PAYING]
    paid_status = [ORDER_STATUS.PAID]
    unpaid_query_set = MaidanOrder.objects.filter(user=user, status__in=unpaid_status).order_by('-created_time')
    paid_query_set = MaidanOrder.objects.filter(user=user, status__in=paid_status).order_by('-payment_time')

    wanted_fields = ['maidan_name', 'status', 'id', 'payment_cent', 'doctor__portrait']
    unpaid_orders = list(unpaid_query_set.values(*wanted_fields))
    paid_orders = list(paid_query_set.values(*wanted_fields))
    if type == ORDER_STATUS.NOT_PAID:
        result = unpaid_orders
    elif type == ORDER_STATUS.PAID:
        result = paid_orders
    else:   # 给前端展示的全部订单
        result = unpaid_orders + paid_orders

    for i in result:
        i['doctor_portrait'] = i.pop('doctor__portrait')
        if i['status'] == ORDER_STATUS.PAYING:
            i['status'] = ORDER_STATUS.NOT_PAID
    return result[start_num: start_num+count]


@bind_context('api/maidan/detail', login_required=True)
def maidan_detail(ctx, id):
    user = get_user_from_context(ctx)
    order = MaidanOrder.objects.get(id=id, user=user)
    return order.order_data()


@bind_context('api/maidan/create', login_required=True)
def order_create(ctx, doctor_id, tags, maidan_price, source):
    # 创建买单订单 maidan_price单位为元
    try:
        doctor = Doctor.objects.get(id=doctor_id)
    except Doctor.DoesNotExist:
        return gen(CODES.DOCTOR_NOT_FOUND)

    user = get_user_from_context(ctx)
    d = {
        'doctor': doctor,
        'user': user,
        'tags': json.loads(tags),
        'maidan_price': maidan_price,
        'source': source,
    }
    order_id = create_order(**d)
    maidan_order_create_event.delay(order_id)
    result = {
        'id': order_id,
    }
    return result


@bind_context('api/maidan/cancel', login_required=True)
def order_cancel(ctx, id):
    with transaction.atomic():
        user = get_user_from_context(ctx)
        person = Person.objects.get(user=user)
        try:
            order = MaidanOrder.objects.select_for_update().get(id=id)
            if order.user != user:
                raise MaidanOrder.DoesNotExist()
        except MaidanOrder.DoesNotExist:
            return gen(CODES.ORDER_NOT_FOUND)
        if order.status == ORDER_STATUS.PAID:
            return gen(CODES.ORDER_CAN_NOT_CANCEL)
        order.operate(person, ORDER_OPERATION_TYPE.CANCEL, ORDER_OPERATION_ROLE.USER)
        return gen(CODES.SUCCESS)


@bind_context('api/maidan/pay_jump', login_required=True)
def pay_jump(ctx, order_id):
    with transaction.atomic():
        user = get_user_from_context(ctx)
        person = Person.objects.get(user=user)
        try:
            order = MaidanOrder.objects.select_for_update().get(id=order_id)
            if order.user != user:
                raise MaidanOrder.DoesNotExist()
        except MaidanOrder.DoesNotExist:
            return gen(CODES.ORDER_NOT_FOUND)
        if order.status == ORDER_STATUS.PAID:
            return gen(CODES.ORDER_PAID)
        elif order.status == ORDER_STATUS.CANCEL:
            return gen(CODES.ORDER_CANCELED)
        else:
            order.operate(person, ORDER_OPERATION_TYPE.PAYING, ORDER_OPERATION_ROLE.USER)
            return gen(CODES.SUCCESS)
