#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
#   Author  :   zhangxiaolin
#   E-mail  :   petelin1120@gmail.com
#   Date    :   17/7/4 15:38
#   Desc    :   ...
from __future__ import absolute_import

import datetime

from celery import shared_task
from dateutil.relativedelta import relativedelta
from gm_types.gaia import BUDAN_STATUS, ORDER_STATUS, BUDAN_SETTLEMENT_STATUS, BUDAN_TYPE
from gm_types.doctor import BUDAN_LURU_STATUS

from api.models import BuDan, BuDanSettlement, Sum, Doctor, Order, BuDanLuRu
from hippo.models import Merchant
from rpc.tool.log_tool import logging_exception


@shared_task
def settlement_create_event():
    """
    创建补单结算单, 可以重复执行
    """
    success, fail = 0, 0
    # doctors = Doctor.objects.filter(is_merchant=True, user__isnull=False)
    merchants = Merchant.objects.filter(is_online=True)
    for merchant in merchants:
        try:
            do_one_doctor(merchant.doctor)
            success += 1
        except:
            logging_exception()
            fail += 1
    print success, fail


def do_one_doctor(doctor):
    current_month_first_day = datetime.date.today().replace(day=1)
    # 上个月
    before_month_first_day = current_month_first_day + relativedelta(months=-1)
    # 上上个月
    bb_month_first_day = current_month_first_day + relativedelta(months=-2)

    # 上上个月结转
    try:
        bb_balance = BuDanSettlement.objects.get(doctor=doctor, month_at=bb_month_first_day).balance
        bb_balance *= 100
    except BuDanSettlement.DoesNotExist:
        bb_balance = 0

    from doctor.views.budan import get_all_doctors
    doctor_ids, user_ids = get_all_doctors(doctor)
    budan_total = BuDan.objects.filter(
        doctor_id__in=doctor_ids,
        create_time__gte=before_month_first_day,
        create_time__lt=current_month_first_day
    ).exclude(
        status=BUDAN_STATUS.CANCEL
    ).exclude(
        budan_type=BUDAN_TYPE.TRANSFER_BUDAN
    ).aggregate(total_payment=Sum('payment'), total_extra_consume=Sum('extra_consume'))

    # 上个月应该支付的
    should_pay = (budan_total['total_payment'] or 0) * 100
    total_extra_consume = (budan_total['total_extra_consume'] or 0) * 100

    # 上个月已经支付的
    alread_pay = Order.objects.filter(
        user_id__in=user_ids,
        status__in=(ORDER_STATUS.USED, ORDER_STATUS.SETTLED),
        validate_time__gte=before_month_first_day,
        validate_time__lt=current_month_first_day
    ).aggregate(total=Sum('discount'))['total'] or 0
    # 上个月直接录入的
    luru_base = BuDanLuRu.objects.filter(
        doctor_id__in=doctor_ids,
        created_time__gte=before_month_first_day,
        created_time__lt=current_month_first_day,
        status=BUDAN_LURU_STATUS.ENTERED,
        is_settle=False
    )
    luru_amount = luru_base.aggregate(total=Sum('amount'))['total'] or 0
    luru_base.update(is_settle=True)
    alread_pay = (alread_pay + luru_amount) * 100

    # 添加结转逻辑
    if bb_balance > 0:
        alread_pay += bb_balance
    elif bb_balance < 0:
        should_pay += -bb_balance
    # 剩余的
    before_balance = alread_pay - should_pay

    settlement, create = BuDanSettlement.objects.get_or_create(doctor=doctor, month_at=before_month_first_day,
                                                               defaults=dict(
                                                                   extra_consume=total_extra_consume / 100.0,
                                                                   payment=should_pay / 100.0,
                                                                   alread_payment=alread_pay / 100.0,
                                                                   balance=before_balance / 100.0,
                                                                   status=BUDAN_SETTLEMENT_STATUS.PAY_SUCCESS,
                                                               ))

    if create:
        BuDan.objects.filter(
            doctor_id__in=doctor_ids,
            create_time__gte=before_month_first_day,
            create_time__lt=current_month_first_day,
            status__in=(BUDAN_STATUS.CREATED, BUDAN_STATUS.APPEAL)
        ).update(settlement=settlement, status=BUDAN_STATUS.CREATE_SETTLEMENT)
