# coding=utf-8
from __future__ import unicode_literals

import json
import datetime

from celery import shared_task
from django.conf import settings
from django.db import transaction
from gm_types.gaia import ORDER_STATUS
from gm_types.trade import STATEMENT_STATUS
from gm_types.plutus.rm_type import RM_STATUS
from django.db.models import Q
from gm_types.gaia import SERVICE_SELL_TYPE

from hippo.models import Merchant
from pay.tool.support_tool import send_email
from api.models import Doctor, POSSum
from api.models import Order
from pay.models import Statement
from pay.models import OrderStatementRelationship
from pay.tool.time_tool import DatetimeTool
from api.tool.log_tool import logging_exception
from rpc.all import get_rpc_remote_invoker


def _send_statement_alert(total_count, failed_count, which_type='美购'):
    dt_str = datetime.datetime.now().strftime("%Y-%m")
    subject = '{dt_str} 月 医生{which_type}结算单详情'.format(dt_str=dt_str, which_type=which_type)
    body = '总计 {total_count} 个\n失败 {failed_count} 个'.format(
        total_count=total_count,
        failed_count=failed_count
    )
    send_email(
        from_email=settings.PAY_EMAIL_USER,
        to_email_list=settings.PAY_EMAIL_STATEMENT_ALERT_LIST,
        subject=subject,
        body=body
    )


def _send_error_detail(doctor_id, error_msg):
    dt_str = datetime.datetime.now().strftime("%Y-%m")
    subject = '{dt_str} 月 {doctor_id} 医生 对账单生成错误'.format(
        dt_str=dt_str,
        doctor_id=doctor_id
    )
    body = error_msg
    send_email(
        from_email=settings.PAY_EMAIL_USER,
        to_email_list=settings.PAY_EMAIL_STATEMENT_ALERT_LIST,
        subject=subject,
        body=body
    )


def create_one_statement(merchant, last_month_dt):
    print merchant.id, merchant.name, last_month_dt
    statement_date = last_month_dt.strftime("%Y%m")
    last_month_dt = DatetimeTool(last_month_dt)
    with transaction.atomic():
        time_query = Q(validate_time__gte=last_month_dt.get_first_day_month()) & Q(
            validate_time__lte=last_month_dt.get_last_day_month())
        # 真医生
        # 当月尚未生成此医生订单
        assert merchant.user is not None
        try:
            statement = Statement.objects.select_for_update().get(doctor=merchant, statement_date=statement_date)
        except Statement.DoesNotExist:
            pass
        else:
            return statement
        statement = Statement.objects.create(doctor=merchant, statement_date=statement_date)

        # 找到商户下所有的用户,包括商户本身. e.g.私立医院 BCCKGJLSHZ
        from doctor.views.budan import get_all_doctors

        doctor_ids, user_ids = get_all_doctors(merchant)

        # 这里是之前错误的写法，暂时留着用来对比
        # user_and_doctor_ids = Doctor.objects.filter(
        #     hospital_id=merchant.hospital.id,
        #     is_merchant=False,
        #     user_id__isnull=False,
        #     allow_hospital_agent=True
        # ).values_list('user__id', 'id')
        # user_ids = [item[0] for item in user_and_doctor_ids] + [merchant.user_id]
        # doctor_ids = [item[1] for item in user_and_doctor_ids] + [merchant.id]

        # 商户及其下的医生的所有订单
        orders = Order.objects.filter(status=ORDER_STATUS.USED, is_settled=False).filter(time_query).filter(
            operate_user__in=user_ids)

        order_list = [order.id for order in orders]
        renmai_list = []
        if len(order_list) > 0:
            # installments = get_rpc_remote_invoker()['plutus/installment/installment/status'](
            #     person_id='',
            #     order_list=order_list,
            # ).unwrap()
            installments = []
            for installment in installments:
                if installment['status'] == RM_STATUS.REPAY:
                    renmai_list.append(installment['order_id'])

        total_discount = total_real_prepay = original_amount = fenxiao_amount = normal_amount = 0
        for order in orders:
            total_real_prepay += order.servicesnapshot.pre_payment_price
            total_discount += order.discount
            # http://wiki.gengmei.cc/pages/viewpage.action?pageId=3369748 增加医生承担比例
            settle_price = order.settle_data()['settle_payment']

            # 尾款分期 给医生结算金额
            original_amount += settle_price
            if order.service.service_type == SERVICE_SELL_TYPE.FENGXIANGGOU:
                fenxiao_amount += settle_price
            else:
                normal_amount += settle_price
            OrderStatementRelationship.objects.create(statement=statement, order=order,
                                                      installment=bool(order.id in renmai_list))

        statement.sub_data = json.dumps({
            'fenxiao_amount': fenxiao_amount,
            'normal_amount': normal_amount,
        })
        statement.pos_back = POSSum.sum_pos_back(doctor_ids, last_month_dt)
        statement.total_real_prepay = total_real_prepay
        statement.total_discount = total_discount
        statement.original_amount = original_amount
        if original_amount == 0:
            statement.status = STATEMENT_STATUS.VOID
        statement.save()
    return statement


@shared_task
def create_all_statements(last_month_dt):
    """确保该任务可以重复执行"""
    # add: 只对商户进行结算
    # merchants = Doctor.objects.filter(is_merchant=True, user_id__isnull=False)
    merchants = Merchant.objects.filter(is_online=True, doctor__user_id__isnull=False)
    total_count = failed_count = 0
    dt = DatetimeTool()
    # last_month_dt = dt.get_first_day_month(d_months=-1)
    for merchant in merchants:
        total_count += 1
        try:
            statement = create_one_statement(merchant.doctor, last_month_dt)
        except:
            logging_exception()
            failed_count += 1
    return total_count, failed_count
