# coding=utf-8

from __future__ import absolute_import

import datetime
from django.db import transaction
from django.conf import settings
from django.db import IntegrityError
from django.db.models import Q
from doctor.models import Content, HomePopup, HomeSlide, Bulletin, BulletinExtra
from api.models import DocBusinessRecord
from django.contrib.auth.models import User
from hera.datatables import ContentDT, PopupsDT, DoctorSlideDT, BulletinDT
from rpc.decorators import bind_context
from rpc.exceptions import RPCIntegrityError, RPCNotFoundException
from rpc.tool.dict_mixin import to_dict
from rpc.tool.log_tool import info_logger
from hera.queries.agreement import AgreementDQ
from api.models.doctor import Agreement
from gm_types.gaia import AGREEMENT_TYPE
from ..queries.doctorsoperate import ContentDQ, PopupsDQ, HomeSlideDQ, BulletinDQ


uri_pre = 'hera/'


@bind_context(uri_pre + 'doctorcontent/edit')
def edit_content(ctx, content_id=None, content_info=None):
    """
    新增或者编辑医生端运营内容
    :param ctx:
    :param content_id: content的id
    :param content_info: content的实体
    """
    if content_info is None:
        return None
    if content_id is None:
        try:
            content = Content.objects.create(**content_info)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            content = Content.objects.get(id=content_id)
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
        for k, v in content_info.iteritems():
            setattr(content, k, v)
        content.save()
    return {"content_id": content.id}


@bind_context(uri_pre + 'doctorcontent/get')
def get_content(ctx, content_id):
    """
    获取医生端运营内容
    """
    if content_id is None:
        return None
    try:
        content = Content.objects.get(id=content_id)
    except IntegrityError:
        raise RPCIntegrityError
    content_data = to_dict(content)
    return content_data


@bind_context(uri_pre + 'doctorcontent/query')
def content_query(ctx, options):
    dqobj = ContentDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + 'doctorcontent/list')
def content_datatable(ctx, req_data):
    dtobj = ContentDT(Content)
    return dtobj.process(req_data)


@bind_context(uri_pre + 'doctorcontent/choices')
def content_choices(ctx, q='', page=1, num=30, initial=None):
    """
    :param ctx:
    :param num:
    :param page:
    :param q:查询关键字

    """
    page = int(page)
    num = int(num)
    if initial is not None:
        if isinstance(initial, (list, tuple)):
            qry = Q(id__in=initial)
        else:
            qry = Q(id=initial)
    else:
        qry = Q(id__contains=q) | Q(title__contains=q)
    query = Content.objects.using(settings.SLAVE_DB_NAME).filter(qry).order_by('-id')
    total_count = query.count()
    start_pos = (page - 1) * num
    start_pos = start_pos if start_pos >= 0 else 0
    results = [
        {
            'id': obj.id,
            'text': u'{}:{}'.format(
                obj.id, obj.title),
        } for obj in query[start_pos: start_pos + num]
        ]
    return {'total_count': total_count, 'results': results, 'page': page, 'num': num}


@bind_context(uri_pre + 'doctorpopups/edit')
def edit_popups(ctx, popups_id=None, popups_info=None):
    """
    新增或者编辑医生端运营内容
    :param ctx:
    :param content_id: content的id
    :param content_info: content的实体
    """
    if popups_info is None:
        return None
    if popups_id is None:
        try:
            popups = HomePopup.objects.create(**popups_info)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            popups = HomePopup.objects.get(id=popups_id)
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
        for k, v in popups_info.iteritems():
            setattr(popups, k, v)
        popups.save()
    return {"popups_id": popups.id}


@bind_context(uri_pre + 'doctorpopups/get')
def get_popups(ctx, popups_id):
    """
    获取医生端运营内容
    :param popups_id:
    :param ctx:
    """
    if popups_id is None:
        return None
    try:
        popups = HomePopup.objects.get(id=popups_id)
    except IntegrityError:
        raise RPCIntegrityError
    popups_data = to_dict(popups)
    return popups_data


@bind_context(uri_pre + 'doctorspopups/query')
def content_query(ctx, options):
    dqobj = PopupsDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + 'doctorspopups/list')
def popups_datatable(ctx, req_data):
    dtobj = PopupsDT(HomePopup)
    return dtobj.process(req_data)


@bind_context(uri_pre + 'doctorspopups/popups_set_is_online')
def setpopups_is_online(ctx, popups_id, is_online):
    try:
        popups = HomePopup.objects.get(id=popups_id)

    except:
        info_logger.info(__import__('traceback').format_exc())
        raise RPCNotFoundException
    popups.is_online = is_online
    popups.save()
    return {'success': True}


@bind_context(uri_pre + 'doctorslide/edit')
def edit_slide(ctx, slide_id=None, slide_info=None):
    """
    新增或者编辑医生端运营内容
    :param ctx:
    :param content_id: content的id
    :param content_info: content的实体
    """
    if slide_info is None:
        return None
    if slide_id is None:
        try:
            slide = HomeSlide.objects.create(**slide_info)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            slide = HomeSlide.objects.get(id=slide_id)
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
        for k, v in slide_info.iteritems():
            setattr(slide, k, v)
        slide.save()
    return {"slide_id": slide.id}


@bind_context(uri_pre + 'doctorslide/get')
def get_slide(ctx, slide_id):
    """
    获取医生端运营内容
    :param popups_id:
    :param ctx:
    """
    if slide_id is None:
        return None
    try:
        slide = HomeSlide.objects.get(id=slide_id)
    except IntegrityError:
        raise RPCIntegrityError
    slide_data = to_dict(slide)
    return slide_data


@bind_context(uri_pre + 'doctorslide/query')
def content_query(ctx, options):
    dqobj = HomeSlideDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + 'doctorslide/list')
def slide_datatable(ctx, req_data):
    dtobj = DoctorSlideDT(HomeSlide)
    return dtobj.process(req_data)


@bind_context(uri_pre + 'doctorslide/slide_set_is_online')
def setslide_is_online(ctx, slide_id, is_online):
    try:
        slide = HomeSlide.objects.get(id=slide_id)

    except:
        info_logger.info(__import__('traceback').format_exc())
        raise RPCNotFoundException
    slide.is_online = is_online
    slide.save()
    return {'success': True}


@bind_context(uri_pre + 'doctorbulletin/edit')
def edit_bulletin(ctx, bulletin_id=None, bulletin_info=None):
    """
    新增或者编辑医生端公告
    :param ctx:
    :param bulletin_id: bulletin的id
    :param bulletin_info: bulletin的实体
    """
    if bulletin_info is None:
        return None
    if bulletin_id is None:
        try:
            merchant_ids = bulletin_info.pop('merchant_id', None)
            city_ids = bulletin_info.pop('city', None)
            area = bulletin_info.pop('area')
            slide = Bulletin.objects.create(**bulletin_info)
            if area == '1':
                BulletinExtra.objects.create(area=area, bulletin=slide)
            elif area == '2':
                for city_id in city_ids:
                    BulletinExtra.objects.create(area=area, bulletin=slide, city_id=city_id)
            elif area == '3':
                for merchant_id in merchant_ids:
                    BulletinExtra.objects.create(area=area, bulletin=slide, merchant_id=merchant_id)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            slide = Bulletin.objects.get(id=bulletin_id)
            objs = BulletinExtra.objects.filter(bulletin_id=bulletin_id)
            if objs:
                objs.delete()
            merchant_ids = bulletin_info.pop('merchant_id', None)
            city_ids = bulletin_info.pop('city', None)
            area = bulletin_info.pop('area')
            if area == '1':
                BulletinExtra.objects.create(area=area, bulletin=slide)
            elif area == '2':
                for city_id in city_ids:
                    BulletinExtra.objects.create(area=area, bulletin=slide, city_id=city_id)
            elif area == '3':
                for merchant_id in merchant_ids:
                    BulletinExtra.objects.create(area=area, bulletin=slide, merchant_id=merchant_id)
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
        for k, v in bulletin_info.iteritems():
            setattr(slide, k, v)
        slide.save()
    return {"bulletin_id": slide.id}


@bind_context(uri_pre + 'doctorbulletin/get')
def get_bulletin(ctx, bulletin_id):
    """
    获取医生端消息公告
    :param bulletin_id:
    :param ctx:
    """
    if bulletin_id is None:
        return None
    try:
        bulletin = Bulletin.objects.get(id=bulletin_id)
    except IntegrityError:
        raise RPCIntegrityError
    bulletin_data = to_dict(bulletin)
    """
    城市和商户获取
    """
    city = []
    merchant_id = []
    area = None
    for obj in BulletinExtra.objects.filter(bulletin_id=bulletin_id):
        city.append(obj.city_id)
        merchant_id.append(obj.merchant_id)
        area = obj.area
    bulletin_data.update(merchant_id=merchant_id, city=city, area=area)
    return bulletin_data


@bind_context(uri_pre + 'doctorbulletin/query')
def content_query(ctx, options):
    dqobj = BulletinDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + 'doctorbulletin/list')
def slide_datatable(ctx, req_data):
    dtobj = BulletinDT(Bulletin)
    return dtobj.process(req_data)


@bind_context(uri_pre + 'doctorbulletin/bulletin_set_is_online')
def setbulletin_is_online(ctx, bulletin_id, is_online):
    try:
        bulletin = Bulletin.objects.get(id=bulletin_id)

    except:
        info_logger.info(__import__('traceback').format_exc())
        raise RPCNotFoundException
    bulletin.is_online = is_online
    bulletin.online_time = datetime.datetime.now()
    bulletin.save()
    return {'success': True}


@bind_context(uri_pre + 'dotorsoperate/agreement/query')
def agreement_query(ctx, options):
    dqobj = AgreementDQ()
    return dqobj.process(**options)


@bind_context(uri_pre + 'doctorsoperate/agreement/get')
def agreement_detail(ctx, agreement_id, options=None):
    try:
        agreement = Agreement.objects.get(id=agreement_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    agreement_data = to_dict(agreement, **options)

    if agreement_data['status'] == AGREEMENT_TYPE.IS_ONLINE:
        agreement_data['is_online'] = True
        if agreement.send_time < datetime.datetime.now():
            agreement_data['show_status'] = AGREEMENT_TYPE.IS_ONLINE
        else:
            agreement_data['show_status'] = AGREEMENT_TYPE.DEFAULT
    else:
        agreement_data['show_status'] = agreement_data['status']
        agreement_data['is_online'] = False

    return agreement_data


@bind_context(uri_pre + 'doctorsoperate/agreement/edit')
def agreement_edit(ctx, agreement_id, agreement_info=None):
    agreement_info.pop('show_status')
    if agreement_info.pop('is_online'):
        agreement_info['status'] = AGREEMENT_TYPE.IS_ONLINE
    else:
        agreement_info['status'] = AGREEMENT_TYPE.DEFAULT
    if agreement_id is None:
        try:
            agreement = Agreement.objects.create(**agreement_info)
            agreement_id = agreement.id
        except:
            raise RPCIntegrityError
    else:
        try:
            agreement = Agreement.objects.get(id=agreement_id)
        except:
            raise RPCNotFoundException

        for k, v in agreement_info.iteritems():
            setattr(agreement, k, v)
        agreement.save()
    return agreement_id


@bind_context(uri_pre + 'doctorsoperate/agreement/recall')
def agreement_recall(ctx, agreement_id):
    try:
        agreement = Agreement.objects.get(id=agreement_id)
    except:
        raise RPCNotFoundException
    if agreement.can_recall:
        agreement.status = AGREEMENT_TYPE.IS_RECALL
        agreement.save()
        message = u'协议已撤回'
    else:
        message = u'协议撤回失败'
    return message
