import functools

from django.conf import settings
from gm_types.gaia import (
    QUESTION_ORDER_TYPE,
    TOP_QUESTION_ORDER_TYPE,
)
from gm_rpcd.all import bind

from libs.es import es_query, get_must_query, get_es
from libs.algorithms import variousness,variousness_for_problem

from search.utils.question import (
    recall_question,
    recall_problem,
    recall_recommend_question_and_sku,
    recall_top_question,
)

MAX_LOAD = 200
GROUP_SIZE = 10
variousness_per_10 = functools.partial(variousness,variety_size=GROUP_SIZE)
variousness_for_problem_per_10 = functools.partial(variousness_for_problem,variety_size=GROUP_SIZE)

def query_by_question_term(es, term, sort, offset, size):
    f = [
        {"term": {"is_online": True}},
    ]
    f.append(term)
    sorting = [
        {
            '_script': {
                'lang': settings.ES_SCRIPT_LANG,
                'script_file': 'sort_question-sink-by-org',
                'type': 'number',
                'order': 'asc',
            }
        }
    ]

    if sort == QUESTION_ORDER_TYPE.HOT:
        sorting += {'answers_num': {
            'order': 'desc'
        }}
    elif sort == QUESTION_ORDER_TYPE.UPDATE:
        sorting += {'create_time': {
            'order': 'desc'
        }}

    q = get_must_query(f)
    if sorting:
        q['sort'] = sorting
    res = es_query('question', q, offset, size, es)
    hits = res['hits']['hits']
    hit_ids = [hit['_source']['id'] for hit in hits]
    return hit_ids


@bind('doris/filter/question')
def filter_question(tag_id, sort_type, offset=0, size=10, filters={},use_fresh_tag=False):
    # term = {"term": {"closure_tag_ids": tag_id}}
    # es = get_es()
    # hits = query_by_question_term(es, term, sort_type, offset, size)
    _filters = {}
    if filters:
        _filters = filters

    tag_ids = _filters.get("tag_ids", [])
    if tag_id:
        tag_ids.append(tag_id)

    questions = recall_question(
        query='',
        offset=offset,
        size=size,
        filters=_filters,
        sort_type=sort_type,
        use_fresh_tag=use_fresh_tag
    )
    question_ids = [item['id'] for item in questions]

    return {"questions": question_ids}


@bind("doris/search/recommend_question")
def recommend_question(query="", offset=0, size=10, filters={}, sort_type=QUESTION_ORDER_TYPE.DEFAULT):
    res = recall_recommend_question_and_sku(query,offset,size,filters,sort_type)
    return {"result":res}

@bind("doris/search/question")
def search_question(query="", offset=0, size=10, filters={}, sort_type=QUESTION_ORDER_TYPE.DEFAULT, drop_duplicated=True, need_diary_data=False):
    tail = offset + size
    question_ids = []

    if not need_diary_data:
        if tail < MAX_LOAD:
            questions = recall_question(query,0, MAX_LOAD,filters,sort_type,fields=["id","user.id"])
            if drop_duplicated:
                items = [{"id":question['id'],"group":question["user"]["id"] if "user" in question else 0} for question in questions]
                items = variousness_per_10(items)
                question_ids = [item['id'] for item in items[offset:tail]]
            else:
                question_ids = [question['id'] for question in questions[offset:tail]]

        if len(question_ids) == 0:
            questions = recall_question(query, offset, size, filters, sort_type, fields=["id"])
            question_ids = [item['id'] for item in questions]

        return {"question_ids":question_ids}

    else:
        if tail < MAX_LOAD:
            questions = recall_question(query, 0, MAX_LOAD, filters, sort_type, fields=["id","user.id"])
            items = [{"id":question["id"],"group":question["user"]["id"],"last_update_time":question["last_update_time"],"type":0 if "user" in question else 0} for question in questions]

            problems = recall_problem(query, 0, MAX_LOAD, filters, sort_type)
            problem_items = [{"id":problem["id"],"last_update_time":problem["latest_reply_time"], "type":1, "diary_id":problem["diary_id"]} for problem in problems]

            items.extend(problem_items)

            sorted_items = sorted(items,key=lambda item:item["last_update_time"],reverse=True)
            question_ids = variousness_for_problem_per_10(sorted_items,drop_duplicated)[offset:tail]

        if len(question_ids) == 0:
            question_ids = recall_question(query, 0, MAX_LOAD, filters, sort_type, fields=["id", "user.id"])
            problems = recall_problem(query, 0, MAX_LOAD, filters, sort_type)
            question_ids.extend(problems)


        return {"question_problem_ids": question_ids}


@bind('doris/filter/top_question')
def filter_top_question(sort_type=TOP_QUESTION_ORDER_TYPE.DEFAULT, filters={}, offset=0, size=10):
    """
    召回置顶问题
    :param sort_type:
    :param filters:
    :param offset:
    :param size:
    :return:
    """
    questions = recall_top_question(
        offset=offset,
        size=size,
        filters=filters,
        sort_type=sort_type
    )
    question_ids = [item['question_id'] for item in questions]

    return {"questions": question_ids}
