# coding=utf-8
from django.contrib.auth.models import User
from django.db import IntegrityError, transaction
from gm_types.gaia import SEARCH_ACTIVITY_TYPE

from api.models import SearchActivity, SearchSubActivity, SearchKeywordOperationRecord
from api.tool.user_tool import get_user_from_context
from rpc.decorators import bind_context, bind

from rpc.tool.datatables import DataTable
from api.models.others import SearchKeyword, SearchKeywordDefault, SearchKeywordRecommend
from rpc.exceptions import RPCNotFoundException, RPCIntegrityError, GaiaRPCFaultException
from rpc.tool.log_tool import info_logger
from rpc.tool.dict_mixin import to_dict
from ..queries.searchkeyword import SearchKeywordDQ

searchkeyword_pre = 'hera/searchkeyword'


@bind_context(searchkeyword_pre + '/query')
def searchkeyword_query(ctx, options):
    dqobj = SearchKeywordDQ()
    return dqobj.process(**options)


@bind_context(searchkeyword_pre + '/list')
def searchkeyword_datatable(request, req_data):
    dtobj = DataTable(SearchKeyword)
    return dtobj.process(req_data)


@bind_context(searchkeyword_pre + '/get')
def searchkeyword_detail(ctx, keyword_id, options=None):
    try:
        keyword = SearchKeyword.objects.get(id=keyword_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    data = to_dict(keyword, **options)
    return data


@bind_context(searchkeyword_pre + '/edit')
def searchkeyword_edit(ctx, keyword_id=None, keyword_info=None):
    if keyword_info is None:
        return None
    rank = keyword_info.get('rank')
    keyword = keyword_info.get('keyword')
    type = keyword_info.get('type')
    searchkeyword = SearchKeyword.objects.exclude(id=keyword_id).filter(type=type, rank=rank, is_online=True)\
                    | SearchKeyword.objects.exclude(id=keyword_id).filter(keyword=keyword, type=type)
    if searchkeyword:
        message = u'该位置已存在已上线的搜索词，或搜索词名称重复！'
        raise GaiaRPCFaultException(error=1, message=message, data=None)
    if keyword_id is None:
        try:
            keyword_new = SearchKeyword.objects.create(**keyword_info)
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            keyword_new = SearchKeyword.objects.get(id=keyword_id)
            for k, v in keyword_info.iteritems():
                setattr(keyword_new, k, v)
            keyword_new.save()
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException

    return keyword_new.id


@bind_context(searchkeyword_pre + '/default/get')
def searchkeyword_default_get(ctx):
    return SearchKeywordDefault.get()


@bind_context(searchkeyword_pre + '/default/set')
def searchkeyword_default_edit(ctx, deploy_info):
    SearchKeywordDefault.set(deploy_info=deploy_info)


@bind_context(searchkeyword_pre + '/recommend/get')
def searchkeyword_recommend_get(ctx):
    return SearchKeywordRecommend.get()


@bind_context(searchkeyword_pre + '/recommend/edit')
def searchkeyword_recommend_edit(ctx, deploy_info):
    SearchKeywordRecommend.set(deploy_info=deploy_info)


@bind_context(searchkeyword_pre + '/replication')
def searchkeyword_detail(ctx, keyword_id):
    # 搜索发现配置复制功能
    with transaction.atomic():
        old_keyword = SearchKeyword.objects.get(id=keyword_id)
        searchkeyword = SearchKeyword.objects.create(
            keyword=old_keyword.keyword,
            is_online=old_keyword.is_online,
            rank=old_keyword.rank,
            type=old_keyword.type,
            position=old_keyword.position,
            is_special=old_keyword.is_special,
            jump_type=old_keyword.jump_type,
            jump_target=old_keyword.jump_target,
            img_url=old_keyword.img_url,
            aggregate_id=old_keyword.aggregate_id,
            start_time=old_keyword.start_time,
            end_time=old_keyword.end_time
        )
        searchkeyword.regions = list(old_keyword.regions.values_list('id', flat=True))
        searchkeyword.cities = list(old_keyword.cities.values_list('id', flat=True))

    return {
        'id': searchkeyword.id,
    }


@bind('hera/search_activity/get')
def get_search_activity(search_activity_id):
    try:
        search_activity = SearchActivity.objects.get(id=search_activity_id)
    except SearchActivity.DoesNotExist:
        return {}
    data = {
        'title': search_activity.title,
        'image': search_activity.image,
        'jump_url': search_activity.jump_url,
        'sub_title': search_activity.sub_title,
        'keywords': search_activity.keywords,
        'style': search_activity.style,
        'tab': search_activity.tab,
        'is_online': search_activity.is_online,
        'start_time': str(search_activity.start_time),
        'end_time': str(search_activity.end_time),
        'operator_id': search_activity.operator_id,
    }
    details = SearchSubActivity.objects.filter(
        activity_id=search_activity_id
    ).order_by('id')
    sub_data = []
    for item in details:
        sub_data.append({
            'title': item.title,
            'image': item.image,
            'jump_url': item.jump_url,
        })

    data.update({'details': sub_data})

    return {'result': data}


@bind('hera/search_activity/edit')
def search_activity_edit(search_activity_id, data):
    sub_data = data.pop('details', [])
    valid_sub_activities = filter(
        lambda x: all([x['image'], x['jump_url'], x['title']]), sub_data
    )

    if not search_activity_id:
        data['is_online'] = True
        search_activity = SearchActivity.objects.create(**data)
    else:
        search_activity = SearchActivity.objects.get(id=search_activity_id)
        for key, value in data.items():
            setattr(search_activity, key, value)
            search_activity.save()
    try:
        SearchSubActivity.objects.filter(activity_id=search_activity.id).delete()
        if int(data['style']) == SEARCH_ACTIVITY_TYPE.POLYMER:
            sub_activity_list = []
            for item in valid_sub_activities:
                sub_activity_list.append(
                    SearchSubActivity(
                        activity_id=search_activity.id,
                        title=item['title'],
                        image=item['image'],
                        jump_url=item['jump_url'],
                    )
                )
            SearchSubActivity.objects.bulk_create(sub_activity_list)
    except:
        return {'error': 1, 'message': '创建子活动失败', 'data': search_activity.id}
    return {'error': 0, 'message': '', 'data': search_activity.id}

@bind_context(searchkeyword_pre + '/delete')
def searchkeyword_delete(ctx, searchkeyword_id):
    """
    根据ID删除一个specialitem
    """
    user = get_user_from_context(ctx)
    # user = User.objects.get(id=20296583)
    specialitem = SearchKeyword.objects.get(pk=searchkeyword_id)
    keyword = specialitem.keyword
    with transaction.atomic():
        specialitem.delete()
        SearchKeywordOperationRecord.objects.create(
            searchkeyword_id=searchkeyword_id,
            operate_user_id=user.id,
            content=u'删除默认搜索词{}'.format(keyword)
        )

    return {'id': searchkeyword_id}

