# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import time

from django.db.models import Sum
from gm_types.gaia import SERVICE_SELL_TYPE, COUPON_TYPES
from gm_types.trade import STATEMENT_OPERATION_TYPE, STATEMENT_STATUS
import tablib
from pay.models.statementall import StatementAll, StatementAllOperation
from rpc.tool.error_code import CODES, gen
from api.tool.user_tool import get_doctor_from_context
from api.models import OrderCouponInfo
from rpc.decorators import bind_context
from rpc.tool.time_tool import get_timestamp_epoch
from rpc.exceptions import RPCNotFoundException
from rpc.tool.dict_mixin import to_dict
from pay.models import statementalloperation as op
from doctor.views.order import doctor_order_detail_v2


@bind_context('doctor/statementall/list')
def statementall_list(ctx, start_num=0, count=10):
    """
    总对账单列表
    :param ctx:
    :return:
    """
    doctor = get_doctor_from_context(ctx)
    sas = StatementAll.objects.filter(doctor=doctor).order_by('-statement_date')
    data = {}
    data['total'] = sas.count()
    result = [
        {
            'statement_date': sa.statement_date,
            'service_order_num': sa.service_statement.settled_num,
            'maidan_order_num': sa.maidan_statement.order_count,
            'status': STATEMENT_STATUS.getDesc(sa.status),
            'id': sa.id,
            'service_settle_amount': sa.service_statement.new_total_settle_amount,
            'maidan_settle_amount': sa.maidan_statement.settle_amount_cent / 100,
            'total_settle_amount': sa.total_settle_amount
        } for sa in sas[start_num: start_num + count]]
    data['statements'] = result
    return data


@bind_context('doctor/statementall/operation')
def statementall_operation(ctx, statement_id, start_num=0, count=10):

    operations = StatementAllOperation.objects.filter(statementall_id=statement_id)
    operations = operations.order_by('-operate_at')
    total = operations.count()
    operations = operations[start_num: start_num + count]

    def operation_data(operation):
        operator = '系统'
        if operation.operator and operation.operator.user == get_doctor_from_context(ctx).user:
            operator = operation.operator.user.last_name
        return {
            'id': operation.id,
            'operator': operator,
            'optype': STATEMENT_OPERATION_TYPE.getDesc(operation.optype),
            'operate_time': get_timestamp_epoch(operation.operate_at),
        }

    return {
        'total': total,
        'operations': [operation_data(operation) for operation in operations],
    }


@bind_context('doctor/statementall/info')
def statementall_info(ctx, statement_id):
    sa = StatementAll.objects.get(id=statement_id)
    account = sa.get_account()
    data = {}
    bank_info = {}
    if account:
        bank_info['account_name'] = account.account_name
        bank_info['account_number'] = account.account_number
        bank_info['account_type'] = account.account_type
        bank_info['bank'] = account.bank
    else:
        bank_info['account_name'] = ''
        bank_info['account_number'] = ''
        bank_info['account_type'] = ''
        bank_info['bank'] = ''
    bank_info['statement_date'] = sa.statement_date
    settle_info = {}
    maidan_settle_info = {}
    maidan_settle_info['id'] = sa.maidan_statement.id
    maidan_settle_info['original_amount'] = sa.maidan_statement.original_amount_cent / 100
    maidan_settle_info['doctor_fee'] = sa.maidan_statement.doctor_fee_cent / 100
    maidan_settle_info['settle_amount'] = sa.maidan_statement.settle_amount_cent / 100
    settle_info['maidan_settle_info'] = maidan_settle_info
    service_settle_info = {}
    service_settle_info['id'] = sa.service_statement.id
    service_settle_info['normal_service_amount'] = sa.service_statement.normal_service_amount
    service_settle_info['fenxiao_service_amount'] = sa.service_statement.fenxiao_service_amount
    service_settle_info['pos_back'] = sa.service_statement.pos_back
    service_settle_info['settle_amount'] = sa.service_statement.new_total_settle_amount
    settle_info['service_settle_info'] = service_settle_info
    settle_info['feededuction_sum'] = sa.feededuction_sum
    settle_info['total_settle_amount'] = sa.total_settle_amount
    data['bank_info'] = bank_info
    data['settle_info'] = settle_info
    data['button_visible'] = True if sa.status == STATEMENT_STATUS.AUDITED else False
    data['service_settle_id'] = sa.service_statement.id
    data['maidan_settle_id'] = sa.maidan_statement.id

    return data


@bind_context('doctor/statementall/deduction')
def statementall_deduction(ctx, statement_id):
    """补扣款详情"""
    doctor = get_doctor_from_context(ctx)
    try:
        statement = StatementAll.objects.get(id=statement_id, doctor=doctor)
    except:
        raise RPCNotFoundException
    replenishments = [to_dict(obj) for obj in statement.fee_deduction.filter(value__lt=0)]
    for replenishment in replenishments:
        replenishment['value'] = abs(replenishment['value'])
    return {
        'deductions': [to_dict(obj) for obj in statement.fee_deduction.filter(value__gt=0)],
        'replenishment': replenishments,
        'total': statement.feededuction_sum,
    }


def calc_settle_amount(order_qs):
    amount = order_qs.aggregate(
        prepay_amount=Sum('servicesnapshot__pre_payment_price'),
        discount_amount=Sum('discount'),
    )
    prepay_amount = amount['prepay_amount'] or 0
    discount_amount = amount['discount_amount'] or 0
    data = OrderCouponInfo.objects.filter(
        order_id__in=[o.id for o in order_qs], coupon_type=COUPON_TYPES.PLATFORM,
    ).aggregate(Sum('coupon_doctor_value'))
    coupon_doctor_amount = data['coupon_doctor_value__sum'] or 0
    settle_amount = prepay_amount - discount_amount - coupon_doctor_amount
    return settle_amount


@bind_context('doctor/statementall/detail')
def statementall_detail(ctx, statement_id, start_num=0, count=10):
    doctors = StatementAll.objects.get(id=statement_id).doctor.merchant_doctors()
    s_statement = StatementAll.objects.get(id=statement_id).service_statement
    m_statement = StatementAll.objects.get(id=statement_id).maidan_statement
    data = {}
    data['total'] = len(doctors)
    b_doctors = []
    for doctor in doctors[start_num: start_num + count]:
        sub_doctor = {}
        sub_doctor['doctor_id'] = doctor.id
        sub_doctor['doctor_name'] = doctor.name
        f = s_statement.orders.filter(operate_user=doctor.user)
        service_settle_amount = calc_settle_amount(f)
        sub_doctor['service_settle_amount'] = service_settle_amount

        m_orders = m_statement.orders.filter(doctor=doctor)
        if m_orders:
            maidan_settle_amount = m_orders.aggregate(Sum('settle_price_cent'))['settle_price_cent__sum'] / 100
        else:
            maidan_settle_amount = 0
        sub_doctor['maidan_settle_amount'] = maidan_settle_amount
        sub_doctor['total_settle_amount'] = maidan_settle_amount + service_settle_amount
        b_doctors.append(sub_doctor)
    data['doctors'] = b_doctors
    return data


@bind_context('doctor/statementall/excel')
def statementall_excel(ctx, statement_id):
    doctor = get_doctor_from_context(ctx)
    if doctor is None:
        return gen(CODES.DOCTOR_NOT_FOUND)

    dataset1 = tablib.Dataset()
    dataset1.headers = (u'订单号', u'美购名称', u'所属医生', u'客户手机号', u'多属性', u'是否特殊分销',
                        u'订单总价', u'更美佣金抽成', u'应付预付款', u'应付尾款', u'活动名称', u'美券抵扣预付',
                        u'商家分摊抵扣（预付）', u'更美分摊抵扣（预付）', u'美券名称（预付）', u'美分抵扣预付',
                        u'实收预付款', u'应结预付款', u'更美抽成实收款', u'美券抵扣尾款', u'美券名称（尾款）',
                        u'分期支付尾款', u'到院支付尾款', u'验证时间')
    s_statement = StatementAll.objects.get(id=statement_id).service_statement
    order_ids = s_statement.orders.values_list('id', flat=True)
    orders = doctor_order_detail_v2.func(ctx, order_ids)
    for order in orders:
        try:
            time_local = time.localtime(order['validate_at'])
            validate_at = time.strftime("%Y-%m-%d %H:%M", time_local)
        except:
            validate_at = ""
        dataset1.append((
            ' ' + order['order_id'],
            order['service_name'],
            order['doctor']['name'],
            ' ' + order['customer_phone'],
            '+'.join(order['service_items']),
            bool(order['service_type'] == SERVICE_SELL_TYPE.FENGXIANGGOU),
            order['gengmei_price'],
            order['gengmei_discount'],
            order['pre_payment_price'],
            order['final_payment_price'],
            order['activity_title'],
            order['pre_payment_coupon_deduction'],
            order['pre_payment_coupon_info']['coupon_doctor_value'],
            order['pre_payment_coupon_info']['coupon_gengmei_value'],
            order['pre_payment_coupon_info']['coupon_name'],
            order['points_deduction'],
            order['real_pre_payment_price'],
            order['doctor_real_pre_payment_price'],
            order['gengmei_real_discount'],
            order['final_payment_coupon_deduction'],
            order['final_payment_coupon_info']['coupon_name'],
            order['installment_payment'],
            order['hospital_payment'],
            ' ' + validate_at,
        ))

    dataset2 = tablib.Dataset()
    dataset2.headers = (u'订单号', u'买单名称', u'所属医生', u'客户手机号',
                        u'买单金额', u'实际支付金额', u'应结买单金额', u'买单时间')
    m_statement = StatementAll.objects.get(id=statement_id).maidan_statement
    for order in m_statement.orders.all():
        dataset2.append((
            ' ' + order.id,
            order.maidan_name,
            order.doctor.name,
            order.user.person.phone,
            order.maidan_price_cent / 100,
            order.payment_cent / 100,
            order.settle_price_cent / 100,
            str(order.created_time),
        ))
    dataset1.title = '美购对账单'
    dataset2.title = '买单对账单'
    book = tablib.Databook((dataset1, dataset2))
    content = book.xlsx
    filename = "statement{}-{}.xlsx".format(statement_id, int(time.time())).encode('utf8')
    from gm_upload.utils.qiniu_tool import QiniuTool
    bucket_name = "gengmei-private"
    try:
        key = QiniuTool.upload(content, filename, bucket_name)['file']
    except:
        # 可能文件内容有更改,就会报错, 那么就删掉重新来一个
        QiniuTool.delete(filename, bucket_name)
        key = QiniuTool.upload(content, filename, bucket_name)['file']
    private_url = QiniuTool.get_private_url('priv.igengmei.com', key, time=300)
    return private_url


@bind_context('doctor/statementall/check')
def trade_statement_check(ctx, statement_id):
    doctor = get_doctor_from_context(ctx)
    if doctor is None:
        return gen(CODES.DOCTOR_NOT_FOUND)
    from hippo.models.merchant import MerchantRelevance, MerchantAccount
    merchant = MerchantRelevance.objects.get(doctor_id=doctor.id).merchant
    try:
        ma = MerchantAccount.objects.get(merchant_id=merchant.id)
        if not ma.account_number:
            gen(CODES.NO_MERCHANT_ACCOUNT)
    except:
        gen(CODES.NO_MERCHANT_ACCOUNT)
    statement = StatementAll.objects.get(id=statement_id)
    op.CheckOp(statement, doctor.user.person).do()


@bind_context('doctor/statementall/refuse')
def trade_statement_refuse(ctx, statement_id, reason):
    doctor = get_doctor_from_context(ctx)
    if doctor is None:
        return gen(CODES.DOCTOR_NOT_FOUND)
    statement = StatementAll.objects.get(id=statement_id)
    op.RefuseOp(statement, doctor.user.person).do(reason)
