# -*- coding: UTF-8 -*-
from __future__ import unicode_literals
import json
from django.db.models import Q
from gm_dataquery.dataquery import DataBuilder, DataSQLQuery
from gm_dataquery.db import DB
from django.contrib.auth.models import User

from pay.models import PaymentOrderItem, PaymentOrder
from api.models import Doctor, Hospital, RefundOrder, AlipayAccoutMaintenance
from gm_types.gaia import (
    REFUND_STATUS, ORDER_OPERATION_TYPE, ORDER_OPERATION_ROLE,
)
from ..models import UserPerm
from ..utils import check_business, check_operate, operate_business


class RefundOrderDB(DataBuilder):
    def getval_gm_send_refund_no(self, obj):
        from utils.order import get_refund_no
        return get_refund_no(obj.order)

    def getval_service_name(self, obj):
        return obj.order.service.name

    def getval_service(self, obj):
        return obj.order.service.id

    def getval_user_name(self, obj):
        return obj.order.user.last_name

    def getval_user(self, obj):
        return obj.order.user.id

    def getval_item(self, obj):
        return obj.order.order_multiattribute

    def getval_doctor_name(self, obj):
        return obj.order.service.doctor.name

    def getval_hospital_name(self, obj):
        return obj.order.service.doctor.hospital.name

    def getval_doctor(self, obj):
        return obj.order.service.doctor.id

    def getval_hospital(self, obj):
        return obj.order.service.doctor.hospital.id

    def getval_status(self, obj):
        return REFUND_STATUS.getDesc(obj.status)

    def getval_fee(self, obj):
        return obj.fee or obj.estimated_fee

    def getval_sell_doctor_name(self, obj):
        id = json.loads(obj.order.service_snapshot).get(u"doctor", None)
        try:
            return Doctor.objects.get(id=id).name
        except:
            return ''

    def getval_sell_hospital_name(self, obj):
        id = json.loads(obj.order.service_snapshot).get(u"hospital", None)
        try:
            return Hospital.objects.get(id=id).name
        except:
            return ''

    def getval_email_username(self, obj):
        # email = obj.order.buyer_email
        # buyer = email and AlipayAccoutMaintenance.objects.filter(account=email).first()
        # 最新的支付宝回调里面不提供buyer_email（之前的回调，提供的buyer_email会被打码，失去了原有的作用）
        # 但是支付宝一定会提供buyer_id，之后可以考虑导出buyer_id
        return ''

    def getval_notify_data(self, obj):
        return json.loads(obj.order.payment_order.notify_data)


@DB
class RefundOrderDQ(DataSQLQuery):
    model = RefundOrder
    data_model = RefundOrderDB

    def filter_check_groups(self, srch_key, srch_val, regex=False):
        user = User.objects.get(id=srch_val)
        groups = user.belong_groups.values_list('name', flat=True)
        if check_business(groups):
            # 判断是商务并且非商务leader
            members = UserPerm.members(user)
            return Q(order__service__doctor__business_partener__in=members)
        elif check_operate(srch_val):
            business_ids = operate_business(srch_val)
            return Q(order__service__doctor__business_partener__id__in=business_ids)
        else:
            return Q()

    def filter_created_at(self, srch_key, srch_val, regex=False):
        return self._qry_time_range(srch_key, srch_val, regex)

    def filter_updated_at(self, srch_key, srch_val, regex=False):
        return self._qry_time_range(srch_key, srch_val, regex)

    def filter_refunded_at(self, srch_key, srch_val, regex=False):
        return self._qry_time_range(srch_key, srch_val, regex)

    def filter_doctor_name(self, srch_key, srch_val, regex=False):
        return Q(order__service__doctor__name__contains=srch_val)

    def filter_hospital_name(self, srch_key, srch_val, regex=False):
        return Q(order__service__doctor__hospital__name__contains=srch_val)

    def filter_service_name(self, srch_key, srch_val, regex=False):
        return Q(order__service__name__contains=srch_val)

    def filter_address(self, srch_key, srch_val, regex=False):
        return Q(order__address__contains=srch_val)

    def filter_user_name(self, srch_key, srch_val, regex=False):
        return Q(order__user__last_name__contains=srch_val)

    def filter_phone(self, srch_key, srch_val, regex=False):
        return Q(order__phone__contains=srch_val)

    def filter_payment_channel(self, srch_key, srch_val, regex=False):
        return Q(order__payment_channel=srch_val)

    def filter_staff_time(self, srch_key, srch_val, regex=False):
        q = Q(order__orderoperation__optype__in=[ORDER_OPERATION_TYPE.ARBIT_APPROVE,
                                                 ORDER_OPERATION_TYPE.ARBIT_APPROVE])
        q &= Q(order__orderoperation__role=ORDER_OPERATION_ROLE.STAFF)
        return q & self._qry_time_range('order__orderoperation__operate_at', srch_val, regex)

    def filter_optype(self, srch_key, srch_val, regex=False):
        q = Q()
        if isinstance(srch_val, list):
            for optype in srch_val:
                q |= Q(order__orderoperation__optype=int(optype))
        else:
            q |= Q(order__orderoperation__optype=int(srch_val))
        return q

    def filter_user_reason(self, srch_key, srch_val, regex=False):
        q = Q()
        if srch_val:
            if isinstance(srch_val, list):
                for reason in srch_val:
                    q |= Q(user_reason__contains=reason)
            else:
                q |= Q(user_reason__contains=srch_val)
        return q

    def filter_deal_function(self, srch_key, srch_val, regex=False):
        q = Q()
        if srch_val:
            if isinstance(srch_val, list):
                for deal_function in srch_val:
                    q |= Q(order__operation__optype=deal_function)
            else:
                q = Q(order__operation__optype=srch_val)
        return q
