# coding=utf-8

from talos.models.topic import TopicScore, Problem, PgcClassify
from api.models.user import MEMBERSHIP_LEVEL
from api.tool.user_tool import get_user_from_context, get_user_city_tagid
from rpc.decorators import bind_context
from rpc.tool.log_tool import search_logger
from rpc.tool.time_tool import get_timestamp_epoch
from rpc.decorators import list_interface
from search.utils.topic import search_topic, search_topic_admin, filter_topic
from search.suggest.topic_test import suggest_topic_test, merge_topic_chunks
from relation.models import UserTagRelation
from gm_types.gaia import PROBLEM_ORDER_TYPE
from search.utils.common import get_query_matched_tags


@bind_context('search/topic/admin')
@list_interface(offset_name='offset', limit_name='size', element_model=Problem)
def search_es_topic_admin(ctx, query='', offset=0, size=5, filters={}, nfilters={}, sort=[]):
    results = []

    user = get_user_from_context(ctx)
    doctor_city_tag_id = get_user_city_tagid(user.id)

    es_results = search_topic_admin(
        query=query, user_city_tag_id=doctor_city_tag_id,
        offset=offset, size=size,
        filters=filters, nfilters=nfilters, sort=sort)
    topic_ids = es_results['topic_ids']
    total_count = es_results['total_count']
    for topic_id in topic_ids:
        try:
            problem = Problem.objects.get(pk=topic_id)
        except Problem.DoesNotExist:
            search_logger.info(u"Problem {} not found".format(topic_id))
            continue
        topic = {
            'id': problem.id,
            'ask': problem.ask,
            'title': problem.ask or problem.title,
            'content': problem.answer[:30],
            'last_modified': get_timestamp_epoch(problem.last_modified),
            'province': '',  # wtf???
            'user_name': problem.user.nickname or '更美用户',
            'doctor_num': problem.doctor_num,
            'reply_num': problem.reply_num,
        }

        try:
            if user:
                ts = TopicScore.objects.get(topic=problem, user_id=user.id)
            else:
                ts = TopicScore.objects.get(topic=problem)
            topic['score'] = ts.score
        except TopicScore.DoesNotExist:
            topic['score'] = 0
        results.append(topic)

    return {
        'topics': results,
        'total_count': total_count,
    }


@bind_context("search/topic/esquery")
@list_interface(offset_name='offset', limit_name='size', element_model=Problem)
def search_es_topic(ctx, query='', offset=0, size=5, topic_type=None, topic_types=[], nfilters={}):
    '''
    :param query:
    :param offset:
    :param size:
    :return
        total    匹配结果数量
        id
        username   帖子作者昵称
        answer     内容
        images      图片列表
        tags  关联tag的列表
        匹配的相关评论数
    '''
    ctx.logger.app(search_esquery=dict(type='topic', query=query))
    user = get_user_from_context(ctx)
    results = []
    filters = {}
    if topic_type:
        # TODO Deprecated 以后使用topic_types
        filters['topic_type'] = topic_type
    elif topic_types:
        filters['topic_types'] = topic_types
    es_data = search_topic(query=query, offset=offset, size=size, filters=filters, nfilters=nfilters)

    total = es_data['hits']['total']
    hits = es_data["hits"]["hits"]
    for hit in hits:
        source = {}
        id = hit['_id']
        try:
            problem = Problem.objects.get(pk=id)
        except Problem.DoesNotExist:
            search_logger.info(u"Problem {} not found".format(id))
            continue
        keys = ['id', 'answer', 'reply_num']
        source = {key: getattr(problem, key) for key in keys}
        source['images'] = [p['image_url'] for p in problem.images.all().values('image_url')]
        source['tags'] = hit['_source'].get('tags', '')
        source['last_name'] = problem.user.nickname

        source['membership_level'] = problem.user.membership_level or MEMBERSHIP_LEVEL.NORMAL

        highlight = hit.get('highlight', None)  # TODO: report bug in elasticsearch
        data = problem.get_topic_info(user)
        # 如果图片和content均为空 则把title设置为content
        if data['problem']['content'] == '' and data['problem']['images'] == []:
            data['problem']['content'] = data['problem']['title']

        results.append({
            'source': source,
            'highlight': highlight,
            'data': data,
        })

    return {
        'matched_tag_ids':[tag.id for tag in get_query_matched_tags(query)],
        'hits': results,
        'total': total
    }


@bind_context('search/topic/pgc')
def search_topic_pgc(ctx, query='', offset=0, size=5, filters=None):
    results = []

    es_data = search_topic(query=query, offset=offset, size=size, filters=filters, sort_type=PROBLEM_ORDER_TYPE.PGC)

    topic_ids = es_data['topic_ids']
    problems = Problem.objects.filter(pk__in=topic_ids).select_related('pgc_classfy')
    problems = dict([(p.id, p) for p in problems])
    total_count = es_data['total_count']
    hits = es_data['hits']['hits']

    for hit in hits:
        id = int(hit['_id'])
        if id in problems:
            problem = problems[id]
        else:
            search_logger.info(u"Problem {} not found".format(id))
            continue
        problem_data = {
            'id': problem.id,
            'title': problem.pgc_classfy and problem.pgc_classfy.name,
            'content': problem.ask,
            'pgc_name': problem.pgc_classfy and problem.pgc_classfy.name,
            'pgc_category': problem.pgc_classfy and problem.pgc_classfy.id,
            'time': problem.created_time.strftime('%Y-%m-%d %H:%M:%S') if problem.created_time else '',
        }
        results.append({
            'data': problem_data,
        })

    result = {
        'matched_tag_ids':[tag.id for tag in get_query_matched_tags(query)],
        'hits': results,
        'total_count': total_count,
    }
    pgc_id = filters.get('pgc_category')
    if pgc_id is not None:
        try:
            pgc_name = PgcClassify.objects.get(pk=pgc_id).name
        except PgcClassify.DoesNotExist:
            pgc_name = ''
        result['pgc_id'] = pgc_id
        result['title'] = pgc_name

    return result


@bind_context('search/topic/suggest_test')
def suggest_topic_test_call(ctx, calc_params):
    user = get_user_from_context(ctx)
    user_followed_tags = UserTagRelation.followed_tags_obj(user.id)
    calc_params['user_related_tag']['user_related_tag_ids'] = [tag.id for tag in user_followed_tags]
    result = suggest_topic_test(calc_params)
    return {'task_id':result['task_id']}


@bind_context('search/topic/suggest_test_res')
def suggest_topic_test_res_call(ctx, task_id):
    result = merge_topic_chunks(task_id)
    if result['status']==0:
        topic_ids = [t['topic_id'] for t in result['topics']]
        topic_scores = {t['topic_id']: t for t in result['topics']}
        topics = Problem.objects.filter(id__in=topic_ids)
        topics = {topic.id: topic for topic in topics}

        user = get_user_from_context(ctx)

        res = {
            'status':result['status'],
            'topics':[],
            'scores':topic_scores,
        }
        for tid in topic_ids:
            if tid not in topics:
                continue
            res['topics'].append(topics[tid].get_topic_info(user))
        return res
    else:
        return {'status':result['status']}