# -*- coding: utf-8 -*-
# @Time    : 2020/2/13 8:55 PM
# @Author  : hexy

from django.db import IntegrityError
from django.db.models import Q
from django.db import transaction
from django.conf import settings
import pinyin

from api.models.area import Country, Province, City, Area, Region
from api.models.toprank import TopRankBanner,TopRankMeddle
from api.models import Hospital, Doctor

from rpc.decorators import bind_context
from rpc.tool.dict_mixin import to_dict
from hera.queries.toprank import TopRankBannerDQ,TopRankMeddleDQ
from gm_types.gaia import TOPRANK_TYPE

from redis import ConnectionPool, StrictRedis

def getRedisClient(host=None, port=None, db=None, password=None, **kwargs):
    pool = ConnectionPool(host=host, port=port, db=db, password=password)
    return StrictRedis(connection_pool=pool)
redis_client = getRedisClient(**settings.DEFAULT_REDIS)

def get_rank_cache_key(rank_type,city_id):
    return 'backend:rank:{0}:{1}'.format(rank_type,city_id)

def delete_toprank_cache(rank_type,city_id):
    return redis_client.delete(get_rank_cache_key(rank_type=rank_type,city_id=city_id))


uri_pre = 'hera/toprank/'

@bind_context(uri_pre + 'banner/query')
def topic_query(ctx, options):
    dqobj = TopRankBannerDQ()
    ret = dqobj.process(**options)
    for x in ret.get('data',[]):
        x['rank_type'] = TOPRANK_TYPE.getDesc(x['rank_type'])
    return ret

@bind_context(uri_pre + 'banner/edit')
def edit_slide(ctx, banner_id=None, banner_info=None):
    """
    新增或者编辑医生端运营内容
    :param ctx:
    :param content_id: content的id
    :param content_info: content的实体
    """
    if banner_info is None:
        return None
    city_id = banner_info.get('city_id')
    rank_type = banner_info.get('rank_type')
    if banner_id is None:
        try:
            res = City.objects.get(id=city_id)
            banner_info['city_name'] = res.name
            cnt = TopRankBanner.objects.filter(city_id=city_id, rank_type=rank_type).count()
            if cnt != 0:
                raise Exception('改城市已经配置过头图了')

            banner = TopRankBanner.objects.create(**banner_info)
        except Exception as e:
            raise Exception(e)
    else:
        try:
            banner = TopRankBanner.objects.get(id=banner_id)

            if (city_id != banner.city_id) or (rank_type != banner.rank_type):
                res = City.objects.get(id=city_id)
                banner_info['city_name'] = res.name
                cnt = TopRankBanner.objects.filter(city_id=city_id, rank_type=rank_type).count()
                if cnt != 0:
                    raise Exception('改城市已经配置过头图了')

            if is_online:
                cnt = TopRankMeddle.objects.filter(city_id=city_id, rank_type=rank_type,sort_idx=sort_idx, is_online=True).count()
                if cnt != 0:
                    raise Exception('名次{0}已经存在了'.format(sort_idx))

            for k, v in banner_info.iteritems():
                setattr(banner, k, v)
            banner.save()

        except Exception as e:
            raise Exception(e)
    delete_toprank_cache(rank_type=rank_type,city_id=city_id)
    return {"banner_id": banner.id}


@bind_context(uri_pre + 'banner/get')
def get_slide(ctx, banner_id):
    """
    获取医生端运营内容
    :param popups_id:
    :param ctx:
    """
    if banner_id is None:
        return None
    try:
        slide = TopRankBanner.objects.get(id=banner_id)
    except Exception as e:
        raise Exception(e)

    return to_dict(slide)


@bind_context(uri_pre + 'meddle/query')
def topic_query(ctx, options):
    print options
    dqobj = TopRankMeddleDQ()
    ret = dqobj.process(**options)
    for x in ret.get('data',[]):
        x['rank_type'] = TOPRANK_TYPE.getDesc(x['rank_type'])
    return ret


@bind_context(uri_pre + 'meddle/edit')
def edit_slide(ctx, banner_id=None, banner_info=None):
    """
    新增或者编辑医生端运营内容
    :param ctx:
    :param content_id: content的id
    :param content_info: content的实体
    """
    if banner_info is None:
        return None

    rank_type = banner_info.get('rank_type')
    target_id = banner_info.get('target_id')
    city_id = banner_info.get('city_id')
    sort_idx = banner_info.get('sort_idx')
    is_online = banner_info.get('is_online')

    if rank_type == TOPRANK_TYPE.hospital:
        try:
            res = Hospital.objects.get(id=target_id)
            banner_info['target_name'] = res.name
        except Exception as _:
            raise Exception('医院{0}查询失败'.format(target_id))

    elif rank_type == TOPRANK_TYPE.doctor:
        try:
            res = Doctor.objects.get(id=target_id)
            banner_info['target_name'] = res.name
        except Exception as _:
            raise Exception('医生{0}查询失败'.format(target_id))

    if banner_id is None:
        try:
            res = City.objects.get(id=city_id)
            banner_info['city_name'] = res.name

            cnt = TopRankMeddle.objects.filter(city_id=city_id, rank_type=rank_type, target_id=target_id).count()
            if cnt != 0:
                raise Exception('干预目标{target_id}已经存在于城市{city_id}'.format(target_id=target_id, city_id=res.name))

            if is_online:
                cnt = TopRankMeddle.objects.filter(city_id=city_id,rank_type=rank_type,sort_idx=sort_idx,is_online=True).count()
                if cnt != 0:
                    raise Exception('名次{0}已经存在了'.format(sort_idx))

            banner = TopRankMeddle.objects.create(**banner_info)
        except Exception as e:
            raise Exception(e)
    else:
        try:
            banner = TopRankMeddle.objects.get(id=banner_id)

            if (target_id != banner.target_id) or (city_id != banner.city_id) or (rank_type != banner.rank_type):
                res = City.objects.get(id=city_id)
                banner_info['city_name'] = res.name
                cnt = TopRankMeddle.objects.filter(city_id=city_id, rank_type=rank_type, target_id=target_id).count()
                if cnt != 0:
                    raise Exception('干预目标{target_id}已经存在于城市{city_id}'.format(target_id=target_id, city_id=city_id))

            for k, v in banner_info.iteritems():
                setattr(banner, k, v)
            banner.save()

        except Exception as e:
            raise Exception(e)
    delete_toprank_cache(rank_type=rank_type, city_id=city_id)
    return {"banner_id": banner.id}



@bind_context(uri_pre + 'meddle/get')
def get_slide(ctx, banner_id):
    """
    获取医生端运营内容
    :param popups_id:
    :param ctx:
    """
    if banner_id is None:
        return None
    try:
        slide = TopRankMeddle.objects.get(id=banner_id)
    except Exception as e:
        raise Exception(e)

    return to_dict(slide)


@bind_context(uri_pre + 'city/choices')
def city_choices(ctx, q='', page=1, num=30, initial=None, need_province=False):
    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(name__contains=q)

    if need_province:
        pro_id_list = Province.objects.values_list('id', flat=True)
        qry &= Q(province_id__in=pro_id_list)

    query = City.objects.using(settings.SLAVE_DB_NAME).filter(qry)
    # total_count = query.count()
    total_count = 0
    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.name),
        } for obj in query[start_pos: start_pos + num]
        ]
    return {'total_count': total_count, 'results': results, 'page': page, 'num': num}

@bind_context(uri_pre + 'cache/get')
def get_cache_data(ctx,rank_type,city_id):
    cc = redis_client.get(get_rank_cache_key(rank_type=rank_type,city_id=city_id))
    if cc:
        return {'data':cc}
    return {'data':''}

@bind_context(uri_pre + 'cache/set')
def set_cache_data(ctx,rank_type,city_id,data):
    r = redis_client.set(get_rank_cache_key(rank_type=rank_type,city_id=city_id),data,ex=24*60*60)
    return {'r':r}

@bind_context(uri_pre + 'cache/delete')
def delete_cache_data(ctx,rank_type,city_id):
    r = delete_toprank_cache(rank_type=rank_type,city_id=city_id)
    return {'r':r}