# -*- coding: UTF-8 -*-
from django.db.models import Sum, FloatField, F, Count, Q
from django.db.models.functions import Coalesce
from gm_dataquery.dataquery import DataBuilder, DataSQLQuery
from gm_dataquery.db import DB
from gm_types.trade import STATEMENT_OPERATION_TYPE

from hera.models import BackendGroup
from pay.models import Statement
from pay.models.operation import StatementOperation


class StatementDB(DataBuilder):

    def __init__(self, **kwargs):
        super(StatementDB, self).__init__(**kwargs)
        self._accounts = {}

    def get_account(self, obj):
        account = getattr(self._accounts, obj.id, None)
        if not account:
            account = obj.get_account()
            self._accounts[obj.id] = account
        return account

    def getval_doctor__account__city__name(self, obj):
        if obj.doctor.merchant.account is None:
            return ''
        if obj.doctor.merchant.account.city is None:
            return ''
        else:
            return obj.doctor.merchant.account.city.name

    def getval_doctor__account__province__name(self, obj):
        if obj.doctor.merchant.account is None:
            return ''
        if obj.doctor.merchant.account.province is None:
            return ''
        else:
            return obj.doctor.merchant.account.province.name

    def getval_account_city(self, obj):
        account = self.get_account(obj)
        return account.city.name

    def getval_account_province(self, obj):
        account = self.get_account(obj)
        return account.province.name

    def getval_account_bank(self, obj):
        account = self.get_account(obj)
        return account.bank

    def getval_subbranch(self, obj):
        account = self.get_account(obj)
        return account.subbranch

    def getval_account_name(self, obj):
        account = self.get_account(obj)
        return account.account_name

    def getval_account_number(self, obj):
        account = self.get_account(obj)
        return account.account_number

    def getval_account_is_change(self, obj):
        return obj.account_has_changed


@DB
class StatementDQ(DataSQLQuery):
    model = Statement
    data_model = StatementDB
    distinct = True

    def order_order_total_price(self, qs, field):
        qs = qs.annotate(totalprice=Sum(u'orders__servicesnapshot__gengmei_price'))
        return qs, u'totalprice'

    def order_settle_price(self, qs, field):
        qs = qs.annotate(
            settleprice=(Coalesce(F(u'original_amount'), 0) - Coalesce(Sum(
                u'fee_deduction__value', output_field=FloatField()), 0)) * (100 - Coalesce(F(u'poundage_rate'), 0)))
        return qs, u'settleprice'

    def order_settled_num(self, qs, field):
        qs = qs.annotate(settlednum=Count(u'orders'))
        return qs, u'settlednum'

    def filter_account_name(self, srch_key, srch_val, regex=False):
        return Q(doctor__account__account_name__contains=srch_val) | Q(account__account_name__contains=srch_val)

    def filter_opuser(self, srch_key, srch_val, regex=False):
        is_staf = BackendGroup.objects.filter(members=srch_val, name='business').exists()
        if not is_staf:
            return Q()
        else:
            return Q(doctor__business_partener_id=srch_val)



class StatementOperationDB(DataBuilder):
    def getval_operator__user__last_name(self, obj):
        if obj.optype == STATEMENT_OPERATION_TYPE.CREATE:
            return u'系统'
        if obj.optype in [STATEMENT_OPERATION_TYPE.CHECK, STATEMENT_OPERATION_TYPE.REFUSE]:
            return obj.operator.user.doctor.name + u'医生'
        return obj.operator.user.last_name or obj.operator.user.username


class StatementOperationDQ(DataSQLQuery):
    model = StatementOperation
    data_model = StatementOperationDB
