# coding=utf-8

import datetime
from django.db import IntegrityError
from api.models.advertise import AdvertiseService, AdvertiseDoctor, AdvertiseHospital, WikiAdver
from api.models.tag import Tag
from hippo.models.advertise import DeviceBlackList, IpBlackList, IpBlackClient, DeviceBlackClient
from rpc.decorators import bind_context, bind
from rpc.exceptions import RPCNotFoundException, RPCIntegrityError
from rpc.tool.log_tool import info_logger
from rpc.tool.dict_mixin import to_dict
from rpc.tool.error_code import gen, CODES
from hera.queries.wikiadver import WikiadverDQ 
from hera.queries.black_name import IpBlackDQ, DeviceBlackDQ

advertise_pre = 'hera/advertise'
advertise_ip_pre = 'hera/advertise/ip'
advertise_device_pre = 'hera/advertise/device'


@bind_context(advertise_pre + "/service_get")
def service_get(ctx, type_=1):
    try:
        service = AdvertiseService.objects.filter(advertise_type=type_)
        service_dt = [
            {
                "service_id": item.service_id,
                "rank": item.rank
            }
            for item in service]
    except Exception as e:
        raise RPCNotFoundException
    if service_dt is None:
        return None

    return service_dt


@bind_context(advertise_pre + "/service_edit")
def service_edit(ctx, service_info, type_=1):
    if service_info is None:
        return None
    try:
        AdvertiseService.objects.filter(advertise_type=type_).delete()
        services = []
        if len(service_info) > 0:
            for item in service_info:
                services.append(AdvertiseService(service_id=item["service_id"],
                                                 rank=item["rank"],
                                                 advertise_type=type_))
            AdvertiseService.objects.bulk_create(services)
    except Exception as e:
        raise e


@bind_context(advertise_pre + "/doctor_get")
def doctor_get(ctx):
    doctor = AdvertiseDoctor.objects.all()
    doctor_dt = [
        {
            "doctor_id": item.doctor_id,
            "rank": item.rank
        }
        for item in doctor]
    return doctor_dt


@bind_context(advertise_pre + "/doctor_edit")
def doctor_edit(ctx, doctor_info):
    if doctor_info is None:
        return None
    try:
        AdvertiseDoctor.objects.all().delete()
        doctors = []
        if len(doctor_info) > 0:
            for item in doctor_info:
                doctors.append(AdvertiseDoctor(doctor_id=item["doctor_id"],
                                               rank=item["rank"]))
            AdvertiseDoctor.objects.bulk_create(doctors)
    except Exception as e:
        raise e


@bind_context(advertise_pre + "/hospital_get")
def hospital_get(ctx):
    try:
        hospitals = AdvertiseHospital.objects.all()
        hospital_dt = [
            {
                "hospital_id": item.hospital_id,
                "portrait": item.portrait,
                "rank": item.rank
            }
            for item in hospitals]
    except Exception as e:
        raise RPCNotFoundException
    return hospital_dt


@bind_context(advertise_pre + "/hospital_edit")
def hospital_edit(ctx, hospital_infos):
    if hospital_infos is None:
        return None
    try:
        AdvertiseHospital.objects.all().delete()
        hospitals = []
        if len(hospital_infos) > 0:
            for item in hospital_infos:
                hospitals.append(AdvertiseHospital(hospital_id=item["hospital_id"],
                                                   rank=item["rank"],
                                                   portrait=item["portrait"]))
            AdvertiseHospital.objects.bulk_create(hospitals)
    except Exception as e:
        raise e


@bind_context(advertise_pre + "/query")
def wikiadver_query(ctx, options):
    dqobj = WikiadverDQ()
    return dqobj.process(**options)


@bind_context(advertise_pre + "/wikiadver_get")
def wikiadver_get(ctx, wikiadver_id, options=None):
    try:
        wikiadver = WikiAdver.objects.get(id=wikiadver_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    wikiadver_data = to_dict(wikiadver, **options)
    return wikiadver_data


@bind_context(advertise_pre + "/wikiadver_edit")
def wikiadver_edit(ctx, wikiadver_id=None, wikiadver_info=None):
    if wikiadver_info is None:
        return None
    wikiadver_info['itemwiki_id'] = wikiadver_info.pop('itemwiki')

    if wikiadver_id is None:
        try:
            if WikiAdver.objects.filter(itemwiki_id=wikiadver_info['itemwiki_id']).count():
                return {
                    'state': False,
                    'msg': u'请确认需要关联的百科'
                }
            wikiadver = WikiAdver.objects.create(**wikiadver_info)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            wikiadver = WikiAdver.objects.get(id=wikiadver_id)
            if wikiadver.itemwiki_id and int(wikiadver.itemwiki_id) != int(wikiadver_info['itemwiki_id']):
                if WikiAdver.objects.filter(itemwiki_id=wikiadver_info['itemwiki_id']).count():
                    return {
                        'state': False,
                        'msg': u'请确认需要关联的百科'
                    }

            for k, v in wikiadver_info.iteritems():
                setattr(wikiadver, k, v)
            wikiadver.save()
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
    return {
        'state': True,
        'wikiadver_id': wikiadver.id
    }


@bind_context(advertise_ip_pre + '/search')
def ip_search(ctx, options):
    dtobj = IpBlackDQ()
    return dtobj.process(**options)

@bind_context(advertise_device_pre + '/search')
def device_search(ctx, options):
    dtobj = DeviceBlackDQ()
    return dtobj.process(**options)

@bind_context(advertise_device_pre + '/add')
def device_add(ctx, device_id, pull_black_type):
    if DeviceBlackList.objects.filter(device_id=device_id):
        error = CODES.DEVICE_BLACK_EXISTS
        message = u"设备id已存在"
        return {"error": error, "message": message}
    else:
        DeviceBlackList.objects.create(device_id=device_id, pull_black_type=pull_black_type)
        device_client = DeviceBlackClient()
        res = device_client.set_key(device_id, "hera")
        if res:
            DeviceBlackList.objects.update(is_redis=True)
        return gen(CODES.SUCCESS)

@bind_context(advertise_ip_pre + '/add')
def ip_add(ctx, ip, pull_black_type):
    if IpBlackList.objects.filter(ip=ip, pull_black_type=pull_black_type):
        error = CODES.IP_BLACK_EXISTS
        message = u'IP已存在' 
        return {"error": error, "message": message}
    else:
        IpBlackList.objects.create(ip=ip, pull_black_type=pull_black_type)
        ip_client = IpBlackClient()
        res = ip_client.set_key(ip, "hera")
        if res:
            IpBlackList.objects.update(is_redis=True)
        return gen(CODES.SUCCESS)


@bind(advertise_ip_pre + '/artemis/one_day')
def get_oneday_new_ip_device():
    """
    获取从昨天0点开始到调用此接口时新增的黑名单IP和设备
    目前用于广告系统 cpc返款
    :return:
    """
    yes_day = datetime.datetime.now() - datetime.timedelta(days=1)
    yes = datetime.datetime(yes_day.year, yes_day.month, yes_day.day, 0, 0, 0, 0)
    ips = IpBlackList.objects.filter(create_at__gte=yes).values_list('ip', flat=True)
    device_ids = DeviceBlackList.objects.filter(create_at__gte=yes).values_list('device_id', flat=True)
    return {'ips': list(ips), 'device_ids': list(device_ids)}
