# coding=utf-8
from datetime import datetime

from django.conf import settings
from gm_types.gaia import QUESTION_ORDER_TYPE

from rpc.context import get_rpc_remote_invoker
from rpc.tool.log_tool import logging_exception
from .es import get_es, get_highlight, es_index_adapt, tzlc
from .common import area_tag_id_filter


def process_filters(filters):
    f = [
        {'term': {'is_online': True}},
    ]
    if not filters:
        return f

    for k, v in filters.iteritems():
        if k == 'raw_tag_ids' and isinstance(v, list) and v:
            f.append({
                'terms': {'tag_ids': v}
            })
        elif k == 'tag_ids' and isinstance(v, list) and v:
            f.append({
                'terms': {'closure_tag_ids': v}
            })
        elif k == 'area_tag_id':
            f.append(area_tag_id_filter([''], v))
        elif k == 'has_recommended_answer':
            f.append({
                'term': {'has_recommended_answer': v}
            })
        elif k == 'created_time':
            f.append({'range': {'create_time': {'gte': tzlc(v)}}})

        elif k == 'answer_num_range':  # 新增回答数据的筛选过滤，传入是字典类型{"gte": xx,}
            f.append({'range': {'answers_num': v}})
        elif k == 'answers_num_gte':
            f.append({'range': {'answers_num': {'gte': v}}})
        elif k == 'answers_level_gte':
            f.append({
                "nested": {
                    "path": "answers",
                    "query": {
                        "bool": {
                            "must": [
                                {"range": {"answers.level": {'gte': v}}},
                            ]
                        }
                    }
                }
            })

    return f


def process_sorting(sort_type, sort_params, query=''):
    # 机构罚单下沉
    sort = [
        {
            '_script': {
                'lang': settings.ES_SCRIPT_LANG,
                'script_file': 'sort_question-sink-by-org',
                'type': 'number',
                'order': 'asc',
            }
        }
    ]
    if query == '':
        pass

    else:
        sort += ['_score']

    if sort_type == QUESTION_ORDER_TYPE.DEFAULT:
        sort += [
            {'score': {'order': 'desc'}}
        ]

    elif sort_type == QUESTION_ORDER_TYPE.DROPDOWN_REFRESH:
        sort += [
            {'recommended_answer_create_time': {'order': 'desc'}}
        ]

    elif sort_type == QUESTION_ORDER_TYPE.DOCTOR_COVER:
        sort += [
            {'has_cover': {'order': 'desc'}}
        ]

    elif sort_type == QUESTION_ORDER_TYPE.DOCTOR_RECOMMEND:
        sort += [
            {'is_recommend': {'order': 'desc'}},
            {'answers_num': {'order': 'desc'}},
            {'create_time': {'order': 'desc'}},
        ]

    elif sort_type == QUESTION_ORDER_TYPE.DOCTOR_LASTEST:
        sort += [
            {'create_time': {'order': 'desc'}}
        ]

    elif sort_type == QUESTION_ORDER_TYPE.ANSWER_NUM:
        sort += [
            {'answers_num': {'order': 'desc'}},
            {'create_time': {'order': 'desc'}},
        ]

    elif sort_type == QUESTION_ORDER_TYPE.MOUTHGUN_RECOMMEND:
        sort += [
            {'score': {'order': 'desc'}}
        ]
    elif sort_type == QUESTION_ORDER_TYPE.DISCOVERY_UPDATE:
        sort += [
            {"last_update_time_answer_reply": {"order": "desc"}},
        ]

    return sort


def search_question(query='', offset=0, size=5, filters=None, sort_params=None, sort_type=QUESTION_ORDER_TYPE.DEFAULT):
    size = min(size, settings.COUNT_LIMIT)
    sort_type = int(sort_type)
    multi_fields = {
        'tags': 4,
        'title': 2,
        'content': 1
    }
    fields = ['^'.join((k, str(v))) for (k, v) in multi_fields.iteritems()]
    multi_match = {
        'query': query,
        'type': 'cross_fields',
        'operator': 'and',
        'fields': fields,
    }

    # q = {'multi_match': multi_match}
    q = {
        'bool': {
            'should': [
                {'multi_match': multi_match},
            ]
        }
    }
    nested_fields = {
        'answers.content': 2.5,  # 5.9.2 重新加上美购名字
    }
    for nf_key, nf_boost in nested_fields.iteritems():
        q['bool']['should'].append({
            'nested': {
                'path': nf_key.split('.')[0],
                'score_mode': 'max',
                'query': {'match': {nf_key: query}},
                'boost': nf_boost,
                'inner_hits': {
                    'highlight': get_highlight(nested_fields.keys())
                }
            },
        })
    f = process_filters(filters)
    sort = process_sorting(sort_type=sort_type, sort_params=sort_params, query=query)
    q = {
        'query': {'filtered': {
            'query': q,
            'filter': {
                'bool': {
                    'must': f,
                }
            }
        }},
        'sort': sort
    }

    es = get_es()
    index = es_index_adapt(
        index_prefix=settings.ES_INDEX_PREFIX,
        doc_type='question',
        rw='read'
    )
    res = es.search(
        index=index,
        doc_type='question',
        timeout=settings.ES_SEARCH_TIMEOUT,
        body=q,
        from_=offset,
        size=size)

    question_ids = []

    for hit in res['hits']['hits']:
        source = hit['_source']
        question_id = source['id']
        # # 搜索问题时则需要重新改
        # answer_id = source['answers'][0]['id'] if source['answers'] else None
        # answer_id = inner_hits['answers']['hits']['hits']
        inner_hits = hit['inner_hits']
        if inner_hits['answers']['hits']['total']:
            answer_id = inner_hits['answers']['hits']['hits'][0]['_source']['id']
            answer_highlight = inner_hits['answers']['hits']['hits'][0]['highlight']['answers.content'][0]
        else:
            answer_id = None
            answer_highlight = None

        question_ids.append({
            'question': question_id,
            'answer': answer_id,
            'answer_highlight': answer_highlight
        })

    res['question_ids'] = question_ids
    res['total_count'] = int(res['hits']['total'])
    return res


def filter_question(offset=0, size=5, sort_type=QUESTION_ORDER_TYPE.DEFAULT, filters=None,
                    sort_params=None):
    size = min(size, settings.COUNT_LIMIT)
    f = process_filters(filters)

    sort = process_sorting(sort_type=sort_type, sort_params=sort_params)

    if sort_type in [QUESTION_ORDER_TYPE.DOCTOR_LASTEST,
                     QUESTION_ORDER_TYPE.DOCTOR_COVER,
                     QUESTION_ORDER_TYPE.DOCTOR_RECOMMEND,
                     QUESTION_ORDER_TYPE.ANSWER_NUM,
                     QUESTION_ORDER_TYPE.MOUTHGUN_RECOMMEND,
                     QUESTION_ORDER_TYPE.DISCOVERY_UPDATE]:
        es_filter = {
            'bool': {
                'must': f,
            },
        }
    else:
        es_filter = {
            'bool': {
                'must': f,
                'should': [
                    {'term': {'is_recommend': True}},
                    # must have one of the two, recommended_question or recommended_answer
                    {'term': {'has_recommended_answer': True}}
                ]
            },
        }

    q = {
        'query': {
            'filtered':
                {
                    'query': {'match_all': {}},
                    'filter': es_filter,
                }
        },
        'sort': sort
    }

    es = get_es()
    index = es_index_adapt(
        index_prefix=settings.ES_INDEX_PREFIX,
        doc_type='question',
        rw='read'
    )
    res = es.search(
        index=index,
        doc_type='question',
        timeout=settings.ES_SEARCH_TIMEOUT,
        body=q,
        from_=offset,
        size=size)

    question_ids = []
    for hit in res['hits']['hits']:
        source = hit['_source']
        question_id = source['id']
        # 搜索问题时则需要重新改
        answer_id = None
        for answer in source['answers']:
            if answer['is_recommend']:
                answer_id = answer['id']
                break
        question_ids.append(
            {
                'question': question_id,
                'answer': answer_id
            }
        )
    res['question_ids'] = question_ids
    res['total_count'] = int(res['hits']['total'])
    return res


def filter_qustion_v1(tag_id, sort_type, offset=0, size=10):
    """
    远程rpc调用 查询question
    :return:
    """
    try:
        result = get_rpc_remote_invoker()['doris/filter/question'](tag_id=tag_id, sort_type=sort_type,
                                                                   offset=offset, size=size).unwrap()
    except:
        logging_exception()
        result = {'questions': []}
    return result
