# coding=utf-8
from __future__ import absolute_import

import datetime
from django.db.models import Q
from api.tool.user_tool import get_doctor_from_context

from rpc.decorators import bind_context
from rpc.tool.time_tool import get_timestamp_epoch
from rpc.tool.dict_mixin import to_dict
from rpc.tool.error_code import gen, CODES
from rpc.exceptions import RPCNotFoundException

from gm_types.gaia import MAIDAN_REVIEW_STATUS

from api.models import DoctorAccount, Doctor
from hippo.models.merchant import MerchantRelevance
from maidan.models import MaidanOrder, MaidanStatement, MaidanSettingApply, MaidanSetting


def maidan_order_data(obj):
    return {
        'id': obj.id,
        'pay_time': get_timestamp_epoch(obj.payment_time),
        'name': obj.maidan_name,
        'price': obj.maidan_price_cent,  # 金额
        'payment': obj.payment_cent,  # 实际支付金额
        'user_id': obj.user.id,
        'username': obj.user.last_name,
        'rebate': obj.rebate,  # 折扣
        'settle_price': obj.settle_price_cent,
        'doctor_name': obj.doctor.name,
    }


@bind_context('doctor/maidan/query')
def maidan_order_list(ctx, start_num=0, count=10, query={}, global_field=[], global_key='', order_by=[]):
    q = Q(**query)
    doctor = get_doctor_from_context(ctx)
    if doctor.is_merchant and doctor.merchant:
        doctor_ids = MerchantRelevance.objects.filter(merchant_id=doctor.merchant.id).values_list(
            'doctor_id', flat=True)
        q = q & Q(doctor_id__in=doctor_ids)
    else:
        q = q & Q(doctor=doctor)
    if global_key:
        global_q = Q()
        for field in global_field:
            global_q |= Q(**{field: global_key})
        q &= global_q
    orders = MaidanOrder.objects.filter(q)
    orders = orders.order_by(*order_by)
    total = orders.count()

    orders = orders[start_num: start_num + count]

    return {
        'total': total,
        'orders': [maidan_order_data(order) for order in orders],
    }


@bind_context('doctor/maidan/detail')
def maidan_order(ctx, maidan_id):
    doctor = get_doctor_from_context(ctx)
    if doctor.is_merchant:
        doctors = doctor.merchant_doctors()
    else:
        doctors = [doctor]
    try:
        order = MaidanOrder.objects.filter(id=maidan_id, doctor__in=doctors).first()
    except MaidanOrder.DoesNotExist:
        raise RPCNotFoundException

    return maidan_order_data(order)


def statement_data(obj):
    return {
        'id': obj.id,
        'status': obj.status,  # 结算状态
        'statement_date': obj.statement_date,  # 结算周期
        'settle_amount': obj.settle_amount_cent,  # 结算金额
        'original_amount': obj.original_amount_cent,  # 实际支付金额
        'doctor_fee_cent': obj.doctor_fee_cent,  # 医生折扣金额
        'price_sum_cent': obj.price_sum_cent,  # 买单总金额
    }


@bind_context('doctor/maidan/statement_query')
def maidan_statement_list(ctx, start_num=0, count=10, query={}, global_field=[], global_key='', order_by=[]):
    q = Q(**query)
    doctor = get_doctor_from_context(ctx)
    q = q & Q(doctor=doctor)
    if global_key:
        global_q = Q()
        for field in global_field:
            global_q |= Q(**{field: global_key})
        q &= global_q
    statements = MaidanStatement.history_objects.filter(q)
    statements = statements.order_by(*order_by)
    total = statements.count()

    statements = statements[start_num: start_num + count]

    return {
        'total': total,
        'statements': [statement_data(statement) for statement in statements],
    }


@bind_context('doctor/maidan/statement_detail')
def statement_detail(ctx, statement_id):
    doctor = get_doctor_from_context(ctx)
    try:
        statement = MaidanStatement.objects.get(id=statement_id, doctor=doctor)
    except:
        raise RPCNotFoundException

    data = statement_data(statement)

    # 医生账户信息
    account, _ = DoctorAccount.objects.get_or_create(doctor=get_doctor_from_context(ctx))
    data.update(to_dict(account, excludes=['id']))

    return data


@bind_context('doctor/maidan/statement_order_query')
def order_list(ctx, start_num=0, count=10, query={}, global_field=[], global_key='', order_by=[], doctor_id=None):
    q = Q(**query)
    if doctor_id is None:
        doctor = get_doctor_from_context(ctx)
        if not doctor:
            return gen(CODES.NO_PERMISSIO)
    else:
        try:
            doctor = Doctor.objects.get(id=doctor_id)
        except Doctor.DoesNotExist:
            return gen(CODES.DOCTOR_NOT_FOUND)
    q = q & Q(doctor=doctor)
    if global_key:
        global_q = Q()
        for field in global_field:
            global_q |= Q(**{field: global_key})
        q &= global_q
    orders = MaidanOrder.objects.filter(q)

    orders = orders.order_by(*order_by)
    total = orders.count()

    orders = orders[start_num: start_num + count]

    return {
        'total': total,
        'orders': [maidan_order_data(order) for order in orders],
    }


@bind_context('doctor/maidan/settings')
def maidan_settings(ctx, merchant_id, start_num=0, count=10):
    from hippo.models.merchant import MerchantRelevance
    mrs = MerchantRelevance.objects.filter(merchant_id=merchant_id)
    total = mrs.count()
    maidan_list = []
    for mr in mrs[start_num: start_num+count]:
        try:
            setting, _ = MaidanSetting.objects.get_or_create(doctor=mr.doctor)
            setting_apply, _ = MaidanSettingApply.objects.get_or_create(doctor=mr.doctor)
        except (MaidanSetting.DoesNotExist, MaidanSettingApply.DoesNotExist):
            raise RPCNotFoundException
        sub = {
            'is_open': setting.is_open,
            'status': setting_apply.status,
            'settings_discount': setting.doctor_discount_rate,
            'apply_discount': setting_apply.doctor_discount_rate,
            'doctor_id': mr.doctor.id,
            'doctor_name': mr.doctor.name,
        }
        maidan_list.append(sub)

    return {
        'total': total,
        'maidan_list': maidan_list
    }


@bind_context('doctor/maidan/settings/edit')
def maidan_settings_edit(ctx, doctor_id, doctor_discount, is_open):
    doctor = Doctor.objects.get(id=doctor_id)
    try:
        setting, _ = MaidanSetting.objects.get_or_create(doctor=doctor)
        setting_apply, _ = MaidanSettingApply.objects.get_or_create(doctor=doctor)
    except (MaidanSetting.DoesNotExist, MaidanSettingApply.DoesNotExist):
        raise RPCNotFoundException

    if setting_apply.status == MAIDAN_REVIEW_STATUS.UNDER_REVIEW:
        gen(CODES.MAIDAN_STATUS_ERROR)

    if setting.doctor_discount_rate != doctor_discount:
        setting_apply.doctor_discount_rate = doctor_discount
        setting_apply.is_open = is_open
        setting_apply.last_modify_time = datetime.datetime.now()
        setting_apply.status = MAIDAN_REVIEW_STATUS.UNDER_REVIEW
        setting_apply.save()
    else:
        setting_apply.status = MAIDAN_REVIEW_STATUS.PASS
        setting_apply.last_modify_time = datetime.datetime.now()
        setting_apply.save()
        setting.is_open = is_open
        setting.save()
