# coding=utf-8
from __future__ import absolute_import

import datetime
from django.db import transaction
from django.db.models import Q
from raven.utils import json
from gm_types.gaia import MAIDAN_REVIEW_STATUS, MAIDAN_STATEMENT_STATUS, ORDER_SOURCE, PAYMENT_CHANNEL

from hera.actions.maidanorder import MaidanOrderAction
from hera.models import UserPerm
from hera.queries.maidan import MaiDanSettingApplyDQ, MaiDanSettingDQ, MaiDanOrderDQ, MaidanStatementDQ
from hera.utils import check_business, check_operate, operate_business
from rpc.cache import req_data_cache
from maidan.models import MaidanSettingApply, MaidanSetting, MaidanStatement, MaidanOrder
from rpc.decorators import bind_context
from rpc.tool.dict_mixin import to_dict
from rpc.tool.error_code import gen, CODES

uri_pre = 'hera/maidan'


@bind_context(uri_pre + '/setting_apply/query')
def setting_apply_list(ctx, options):
    """
    获取医生买单申请列表
    """
    dqobj = MaiDanSettingApplyDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + '/setting_apply/detail')
def get_setting_alpply_detail(ctx, setting_apply_id):
    """
    根据ID获取医生买单申请详情
    """
    if not setting_apply_id:
        return None
    else:
        try:
            setting_apply = MaidanSettingApply.objects.get(pk=setting_apply_id)
            settingapply = to_dict(setting_apply)
            settingapply['doctor_name'] = setting_apply.doctor.name
            settingapply['hospital_name'] = setting_apply.doctor.hospital.name if \
                setting_apply.doctor and setting_apply.doctor.hospital else u''
            settingapply['business'] = setting_apply.doctor.business_partener.username if \
                setting_apply.doctor.business_partener else ''
            settingapply['old_count'] = '{}%'.format(
                setting_apply.doctor.maidansetting.doctor_discount_rate) if setting_apply.doctor.maidansetting else '100%'
            settingapply['new_count'] = '{}%'.format(setting_apply.doctor_discount_rate)
            return settingapply
        except Exception:
            raise


@bind_context(uri_pre + '/setting_apply/audit')
@transaction.atomic
def setting_apply_audit(ctx, apply_id, is_pass):
    """
    审核医生买单申请
    """
    setting_apply = MaidanSettingApply.objects.get(pk=apply_id)
    if setting_apply.status != MAIDAN_REVIEW_STATUS.UNDER_REVIEW:
        raise gen(CODES.OPERATION_NOT_SUPPORTED)
    setting_apply.review_time = datetime.datetime.now()
    if is_pass:
        if setting_apply.doctor.maidansetting:
            setting_apply.doctor.maidansetting.status = MAIDAN_REVIEW_STATUS.PASS
            setting_apply.doctor.maidansetting.doctor_discount_rate = setting_apply.doctor_discount_rate
            setting_apply.doctor.maidansetting.is_open = setting_apply.is_open
            setting_apply.doctor.maidansetting.save()
        else:
            setting_apply.doctor.maidansetting = MaidanSetting.objects.create(
                doctor_id=setting_apply.doctor.id,
                is_open=setting_apply.is_open,
                doctor_discount_rate=setting_apply.doctor_discount_rate,
            )
        setting_apply.status = MAIDAN_REVIEW_STATUS.PASS
        setting_apply.save()
    else:
        if setting_apply.doctor.maidansetting:
            setting_apply.doctor.maidansetting.status = MAIDAN_REVIEW_STATUS.TURN_DOWN
            setting_apply.doctor.maidansetting.save()
            setting_apply.status = MAIDAN_REVIEW_STATUS.TURN_DOWN
            setting_apply.save()


@bind_context(uri_pre + '/setting/query')
def setting_list(ctx, options):
    """
    获取医生买单设置列表
    """
    dqobj = MaiDanSettingDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + '/setting/detail')
def get_setting_detail(ctx, setting_id):
    """
    根据ID获取医生买详情
    """
    if not setting_id:
        return None
    else:
        try:
            setting_obj = MaidanSetting.objects.get(pk=setting_id)
            setting_data = to_dict(setting_obj)
            setting_data['doctor_name'] = setting_obj.doctor.name
            setting_data['hospital_name'] = setting_obj.doctor.hospital.name if \
                setting_obj.doctor and setting_obj.doctor.hospital_id else u''
            setting_data['discount'] = setting_obj.discount_rate
            setting_data['gengmei_offers'] = setting_obj.gengmei_offers_rate
            setting_data['doctor_discount_int'] = setting_obj.doctor_discount_rate
            setting_data['doctor_discount'] = '{}%'.format(
                setting_obj.doctor_discount_rate) if setting_obj.doctor_discount_rate else '100%'
            return setting_data
        except Exception:
            raise


@bind_context(uri_pre + '/setting/save')
def setting_apply_audit(ctx, setting_id, discount, gengmei_offers):
    """
    审核医生买单申请
    """
    setting_data = MaidanSetting.objects.get(pk=setting_id)
    setting_data.discount_rate = discount
    setting_data.gengmei_offers_rate = gengmei_offers
    setting_data.save()


@bind_context(uri_pre + '/order/query')
def setting_apply_list(ctx, options):
    """
    获取买单订单列表
    """
    if check_business(ctx.session.groups):
        # 判断是商务并且非商务leader
        user = ctx.session.user
        members = UserPerm.members(user)
        init_q = Q(doctor__business_partener__in=members)
    elif check_operate(ctx.session.user_id):
        business_ids = operate_business(ctx.session.user_id)
        init_q = Q(doctor__business_partener__id__in=business_ids)
    else:
        init_q = None
    dqobj = MaiDanOrderDQ(init_q=init_q)
    req_data_cache.set(ctx.session.session_key + 'maidan_order', json.dumps(options))
    return dqobj.process(**options)


@bind_context(uri_pre + '/order/orders')
def order_orders(ctx, querytype, nos):
    """
    买单订单的action操作
    """
    user = ctx.session.user
    options = json.loads(req_data_cache.get(ctx.session.session_key + 'maidan_order'))
    if check_business(ctx.session.groups):
        # 判断是商务并且非商务leader
        user = ctx.session.user
        members = UserPerm.members(user)
        init_q = Q(doctor__business_partener__in=members)
    elif check_operate(ctx.session.user_id):
        business_ids = operate_business(ctx.session.user_id)
        init_q = Q(doctor__business_partener__id__in=business_ids)
    else:
        init_q = None
    dtobj = MaiDanOrderDQ(init_q=init_q)
    if nos != 'selectall':
        orders = MaidanOrder.objects.filter(id__in=nos)
    else:
        if options.get('paging'):
            options.pop('paging')
        if options.get('columns'):
            options.pop('columns')
        orders = dtobj.build_queryset(**options)
    kwargs = {'orders': orders}
    return getattr(MaidanOrderAction, querytype)(**kwargs)


@bind_context(uri_pre + '/order/detail')
def order_detail(ctx, order_id):
    if not order_id:
        return None
    else:
        order = MaidanOrder.objects.get(id=order_id)
        order_info = to_dict(order)
        order_info['user'] = order.user.last_name
        order_info['user_id'] = order.user.id
        order_info['maidan_price_cent'] = '%0.2f' % (order.maidan_price_cent * 0.01)
        order_info['payment_cent'] = '%0.2f' % (order.payment_cent * 0.01)
        order_info['offer'] = (order.doctor_discount_rate - order.gengmei_offers_rate) * 0.1
        order_info['doctor_name'] = order.doctor.name
        order_info['hospital'] = order.doctor.hospital_id
        order_info['hospital_name'] = order.doctor.hospital.name
        order_info['source'] = ORDER_SOURCE.getDesc(order.source)
        order_info['payment_info'] = order.payment_info
        order_info['payment_info']['payment_channel'] = PAYMENT_CHANNEL.getDesc(order.payment_channel)
        order_info['payment_info']['payment_cent'] = '%0.2f' % (order.payment_cent * 0.01)
        order_info['payment_info']['payment_time'] = \
            str(order.payment_time).split('.')[0] if order.payment_time else None
        return order_info


@bind_context(uri_pre + '/statement/query')
def setting_apply_list(ctx, options):
    dqobj = MaidanStatementDQ(init_q=Q(
        status__in=[MAIDAN_STATEMENT_STATUS.CREATED, MAIDAN_STATEMENT_STATUS.SETTLED],
        statement_date__lt=201711
    ))
    return dqobj.process(**options)


@bind_context(uri_pre + '/statement/settle')
def statement_settle(ctx, statement_id):
    person = ctx.session.user.person
    statement = MaidanStatement.objects.get(id=statement_id)
    if statement.status == MAIDAN_STATEMENT_STATUS.SETTLED:
        return {
            'status': False,
            'message': u'请确认结算单状态'
        }
    statement.settle(person)
    return {
        'status': True,
        'id': statement.id
    }
