# coding: utf-8
from __future__ import unicode_literals, absolute_import, print_function

import random
import datetime
from django.db.models import Q, Max

from agile.models import TagV3
from api.models.others import (
    SearchKeyword,
    UserBlackList,
    City,
)
from api.models import Province, City, SearchActivity, SearchSubActivity, Special, Tag
from api.tool.user_tool import get_user_from_context
from rpc.decorators import bind, bind_context, cache_page
from api.models.others import SearchKeywordDefault, SearchKeywordRecommend
from api.models.search.topic_aggregation import TopicAggregation
from gm_types.gaia import SEARCH_KEYWORDS_POSITION, SEARCH_KEYWORDS_TYPE, WORLD_AREA_TYPE, SEARCH_TAB_TYPE, TAG_V3_TYPE, \
    TAG_TYPE
from gm_types.gaia import HOT_SEARCH_JUMP_TYPE
from api.tool.searchkeyword_procotol_tool import format_search_keyword
from api.models.types import BLOCK_USER_REASON


@bind('api/search/keywords')
@cache_page(5 * 60)
def get_search_keywords(current_city_id='beijing',
                        category=SEARCH_KEYWORDS_TYPE.DEFAULT,
                        position=SEARCH_KEYWORDS_POSITION.HOT):
    query = Q(is_online=True) & Q(type=category) & Q(position=position) & Q(jump_type=HOT_SEARCH_JUMP_TYPE.NORMAL)

    if current_city_id and current_city_id not in WORLD_AREA_TYPE:
        # 筛选词库中没有配置大区和城市的词
        query_city_region = Q(cities=None) & Q(regions=None)
        try:
            city = City.objects.get(id=current_city_id)
            city_query = Q(cities=city)
            if city.province and city.province.region:
                city_query |= Q(regions=city.province.region)

            query_city_region |= city_query
        except City.DoesNotExist:
            pass
        query &= query_city_region
    if int(position) == SEARCH_KEYWORDS_POSITION.HOT:
        now = datetime.datetime.now()
        query1 = query & Q(start_time=None) & Q(end_time=None)
        query2 = query & Q(start_time__lte=now) & Q(end_time__gte=now)
        query = query1 | query2
    keywords = SearchKeyword.objects.filter(query).order_by('-rank').values_list("keyword", flat=True).distinct()

    return {'keywords': list(keywords)}


@bind('api/search/keywords_v2')
@cache_page(5 * 60)
def get_search_keywords_v2(current_city_id='beijing',
                        category=SEARCH_KEYWORDS_TYPE.DEFAULT,
                        position=SEARCH_KEYWORDS_POSITION.HOT):
    query = Q(is_online=True) & Q(type=category) & Q(position=position)

    if current_city_id and current_city_id not in WORLD_AREA_TYPE:
        # 筛选词库中没有配置大区和城市的词
        query_city_region = Q(cities=None) & Q(regions=None)
        try:
            city = City.objects.get(id=current_city_id)
            city_query = Q(cities=city)
            if city.province and city.province.region:
                city_query |= Q(regions=city.province.region)

            query_city_region |= city_query
        except City.DoesNotExist:
            pass
        query &= query_city_region
    if int(position) == SEARCH_KEYWORDS_POSITION.HOT:
        now = datetime.datetime.now()
        query1 = query & Q(start_time=None) & Q(end_time=None)
        query2 = query & Q(start_time__lte=now) & Q(end_time__gte=now)
        query = query1 | query2
    obj = SearchKeyword.objects.filter(query)\
        .order_by('-rank').values_list("keyword", 'is_special', 'jump_type', 'jump_target').distinct()
    keywords = [{'keyword': x[0], 'is_special': x[1], 'jump_type': x[2], 'url': format_search_keyword(x[2], x[3])} for x in obj]
    return {'keywords': keywords}


@bind('api/search/placeholder')
@cache_page(5 * 60)
def get_search_placeholder(current_city_id='beijing', position=SEARCH_KEYWORDS_POSITION.DEFAULT):
    query = Q(is_online=True) & Q(position=position)

    if current_city_id and current_city_id not in WORLD_AREA_TYPE:
        query_city_region = Q(cities=None) & Q(regions=None)
        try:
            city = City.objects.get(id=current_city_id)
            city_query = Q(cities=city)
            if city.province and city.province.region:
                city_query |= Q(regions=city.province.region)

            query_city_region |= city_query
        except City.DoesNotExist:
            pass
        query &= query_city_region

    keywords = SearchKeyword.objects.filter(query).order_by('-rank').values_list("keyword", flat=True).distinct()

    return {'keywords': list(keywords)}


@bind('api/search/recommend_keywords')
@cache_page(5 * 60)
def get_search_recommends():
    """
    Search recommends.
    :return:
    """
    return SearchKeywordRecommend.get()


@bind('api/user/add_blacklist')
def user_in_blacklist(user_id, phone):
    if UserBlackList.user_in_black_list(user_id=user_id):
        return True
    else:
        UserBlackList.objects.create(user=phone, bind_user_id=user_id, reason=BLOCK_USER_REASON.other)
    return True


@bind('api/user/in_blacklist')
def user_in_blacklist(user_id):
    return UserBlackList.user_in_black_list(user_id=user_id)


@bind('api/device/in_blacklist')
def device_in_blacklist(device_id, platform, idfv=None):
    kw = locals()
    return UserBlackList.device_in_black_list(**kw)


@bind('api/search/keywords_everybody')
@cache_page(5 * 60)
def get_search_keywords_v2(version=None):

    keywords = []
    objs = TopicAggregation.objects.filter(is_online=True).values("position").annotate(
        create_time=Max("create_time")).order_by('position')[:8]
    for i in objs:
        obj = TopicAggregation.objects.filter(position=i['position'], create_time=i['create_time']).first()
        if version:
            keywords.append({
                'title': obj.title,
                'img_url': obj.img_url,
                'position': i['position'],
                'aggregate_id': obj.aggregate_id,
                'group_id': obj.group_id,
                'related_url': obj.related_url,
                'topic_id': obj.topic_id,
            })
        else:
            keywords.append({
                'title': obj.title,
                'img_url': obj.img_url,
                'position': i['position'],
                'aggregate_id': obj.aggregate_id,
            })
    return keywords


@bind('api/search/placeholder_v2')
@cache_page(5 * 60)
def get_search_placeholder_v2(current_city_id='beijing', position=SEARCH_KEYWORDS_POSITION.DEFAULT):
    # query = Q(is_online=True) & Q(position=position)
    query = Q(position=position)
    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    if current_city_id and current_city_id not in WORLD_AREA_TYPE:
        query_city_region = Q(cities=None) & Q(regions=None)
        try:
            city = City.objects.get(id=current_city_id)
            city_query = Q(cities=city)
            if city.province and city.province.region:
                city_query |= Q(regions=city.province.region)

            query_city_region |= city_query
        except City.DoesNotExist:
            pass
        query &= query_city_region
        query &= Q(start_time__lt=now)
        query &= Q(end_time__gt=now)
        query &= ~Q(explicit_word='')
    data=[]
    obj = SearchKeyword.objects.filter(query).order_by('-rank').order_by('-id').distinct()[:2]
    for i in obj:
        data.append({
            'keyword': i.explicit_word,
            'aggregate_id': i.aggregate_id
        })
    return data


@bind('api/search/placeholder_activity')
def get_search_placeholder(current_city_id='beijing', position=SEARCH_KEYWORDS_POSITION.DEFAULT):
    # query = Q(is_online=True) & Q(position=position)
    query = Q(position=position)

    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    if current_city_id and current_city_id not in WORLD_AREA_TYPE:
        query_city_region = Q(cities=None) & Q(regions=None)
        try:
            city = City.objects.get(id=current_city_id)
            city_query = Q(cities=city)
            if city.province and city.province.region:
                city_query |= Q(regions=city.province.region)

            query_city_region |= city_query
        except City.DoesNotExist:
            pass
        query &= query_city_region
        query &= Q(start_time__lt=now)
        query &= Q(end_time__gt=now)

    keywords = SearchKeyword.objects.filter(query).order_by('rank')
    data = []
    for k in keywords:
        keyword_dict = {
            'explicit_word': k.explicit_word,
            'keyword': k.keyword,
            'rank': k.rank,
            'jump_type': k.jump_type,
            'jump_target': k.jump_target,
        }
        if k.jump_type == HOT_SEARCH_JUMP_TYPE.SPECIAL:
            special = Special.objects.filter(id=int(k.jump_target)).first()
            keyword_dict['is_new_special'] = special.is_new_special if special else ''
        if k.explicit_word and k.explicit_word != k.keyword:
            keyword_dict_v2 = {
                'explicit_word': k.explicit_word,
                'keyword': k.explicit_word,
                'rank': k.rank,
                'jump_type': k.jump_type,
                'jump_target': k.jump_target,
            }
            if k.jump_type == HOT_SEARCH_JUMP_TYPE.SPECIAL:
                special = Special.objects.filter(id=int(k.jump_target)).first()
                keyword_dict_v2['is_new_special'] = special.is_new_special if special else ''
            data.append(keyword_dict_v2)

        data.append(keyword_dict)

    return {'data': data}


@bind('api/search/activity')
def get_search_activity(keywords=''):
    data = []
    date = datetime.datetime.now()
    activities = SearchActivity.objects.filter(
        keywords=keywords, tab=SEARCH_TAB_TYPE.ALL, is_online=True, start_time__lte=date, end_time__gte=date,
    ).order_by('style', '-id')
    for item in activities:
        sub_activities = SearchSubActivity.objects.filter(
            activity_id=item.id
        ).order_by('id')
        data.append({
            'id': item.id,
            'title': item.title,
            'sub_title': item.sub_title,
            'img': item.image,
            'jump_url': item.jump_url,
            'style': item.style,
            'keyword': item.keywords,
            'type': 'hera',
            'sub_content': [
                {
                    'sub_title': sub_activity.title,
                    'sub_img': sub_activity.image,
                    'jump_url': sub_activity.jump_url,
                } for sub_activity in sub_activities
            ]
        })
    return {'data': data}

@bind('api/is_new_special')
def is_new_special(target_id=0):
    special = Special.objects.filter(id=target_id).first()
    is_new = special.is_new_special if special else False
    return {'is_new':is_new}
