#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import logging
import traceback
from libs.tools import tzlc, getMd5Digest
from libs.es import ESPerform
from libs.cache import redis_client
import json
from django.conf import settings

from trans2es.commons.commons import get_tips_suggest_list, get_tips_suggest_list_v1
from trans2es.commons.words_utils import QueryWordAttr, get_tips_word_type


class TagTransfer(object):
    tips_num_redis_key_prefix = "search_tips:tips_mapping_num"

    @classmethod
    def get_tag_data_name_mapping_results_to_redis(cls, instance):
        try:
            tag_name = instance.name.strip()
            q = dict()
            if tag_name:
                multi_fields = {
                    'short_description': 1,
                    'doctor.name': 1,
                    'doctor.hospital.name': 1,
                    'doctor.hospital.city_name': 1,
                    'doctor.hospital.city_province_name': 1,
                    'closure_tags': 1,  # 5.9版 搜索所有tag
                    'doctor.hospital.officer_name': 1  # 搜索机构管理者
                }
                query_fields = ['^'.join((k, str(v))) for (k, v) in multi_fields.items()]
                multi_match = {
                    'query': tag_name,
                    'type': 'cross_fields',
                    'operator': 'and',
                    'fields': query_fields,
                }
                sku_query = {
                    "nested": {
                        "path": "sku_list",
                        "query": {
                            "multi_match": {
                                "query": tag_name,
                                "fields": ["sku_list.name^2"],
                                'operator': 'and',
                                'type': 'cross_fields'
                            }
                        }
                    }
                }

                q['query'] = {
                    'bool': {
                        "should": [
                            {'multi_match': multi_match},
                            sku_query
                        ],
                        "must": [
                            {"term": {"is_online": True}}
                        ],
                        "minimum_should_match": 1
                    }
                }

                result_dict = ESPerform.get_search_results(ESPerform.get_cli(settings.GM_ORI_ES_INFO_LIST),
                                                           sub_index_name="service", doc_type="service", query_body=q,
                                                           offset=0, size=0)

                service_results = result_dict["total_count"]

                if service_results == 0:
                    service_results = cls.get_content_results_to_redis(instance=instance)

                redis_data = redis_client.hget(cls.tips_num_redis_key_prefix, tag_name)

                redis_val_dict = json.loads(str(redis_data, encoding="utf-8")) if redis_data else {}

                total_count = service_results
                if 't' in redis_val_dict:
                    total_count += int(redis_val_dict['t'])

                redis_val_dict['t'] = total_count
                redis_val_dict['s'] = service_results

                redis_client.hset(cls.tips_num_redis_key_prefix, tag_name, json.dumps(redis_val_dict))
        except:
            logging.error("catch exception,err_msg:%s" % traceback.format_exc())

    @classmethod
    def get_content_results_to_redis(cls, instance):
        try:
            word = instance.name.strip()
            answer_query = {
                "query": {
                    "bool": {
                        "minimum_should_match": 1,
                        "should": [{"match_phrase": {"title": {"query": word, "analyzer": "gm_default_index"}}},
                                   {"match_phrase": {"desc": {"query": word, "analyzer": "gm_default_index"}}},
                                   {"match_phrase": {"answer": {"query": word, "analyzer": "gm_default_index"}}}],
                        "must": [{"term": {"is_online": True}}]
                    }
                }
            }
            answer_result_dict = ESPerform.get_search_results(ESPerform.get_cli(settings.GM_ORI_ES_INFO_LIST),
                                                              sub_index_name="answer", doc_type="answer",
                                                              query_body=answer_query,
                                                              offset=0, size=0)
            answer_results = answer_result_dict["total_count"]

            tractate_query = {
                "query": {
                    "bool": {
                        "minimum_should_match": 1,
                        "should": [{"match_phrase": {"content": {"query": word, "analyzer": "gm_default_index"}}}, {
                            "match_phrase": {"tractate_tag_name": {"query": word, "analyzer": "gm_default_index"}}}, {
                                       "match_phrase": {"tractate_tag_name_content": {"query": word,
                                                                                      "analyzer": "gm_default_index"}}}],
                        "must": [{"term": {"is_online": True}}]
                    }
                }
            }
            tractate_result_dict = ESPerform.get_search_results(ESPerform.get_cli(settings.GM_ORI_ES_INFO_LIST),
                                                                sub_index_name="tractate", doc_type="tractate",
                                                                query_body=tractate_query,
                                                                offset=0, size=0)
            tractate_results = tractate_result_dict["total_count"]

            diary_query = {
                "query": {
                    "bool": {
                        "minimum_should_match": 1,
                        "should": [{"match_phrase": {"tags": {"query": word, "analyzer": "gm_default_index"}}},
                                   {"match_phrase": {"answer": {"query": word, "analyzer": "gm_default_index"}}},
                                   {"match_phrase": {"service.name": {"query": word, "analyzer": "gm_default_index"}}}],
                        "must": [{"term": {"is_online": True}}, {"range": {"content_level": {"gte": "3"}}}]
                    }
                },
            }
            diary_result_dict = ESPerform.get_search_results(ESPerform.get_cli(settings.GM_ORI_ES_INFO_LIST),
                                                             sub_index_name="diary", doc_type="diary",
                                                             query_body=diary_query,
                                                             offset=0, size=0)
            diary_results = diary_result_dict["total_count"]

            total_count = int(answer_results) + int(tractate_results) + int(diary_results)

            logging.info("get content_info:%s" % total_count)

            return total_count
        except:
            logging.error("catch exception,err_msg:%s" % traceback.format_exc())
            return 0

    @classmethod
    def get_tag_suggest_data_list(cls, instance):
        try:
            ret_list = list()
            suggest_list = list()
            keyword = instance.name
            cut_bool = False
            cut_word = ["下线", "停用", "已经下线", "账号停用"]
            for i in cut_word:
                if keyword.find(i) >= 0:
                    cut_bool = True
            item_dict = dict()
            ret_bol = QueryWordAttr.save_query_to_redis(query=str(instance.name))
            if not cut_bool and ret_bol:
                item_dict["id"] = getMd5Digest(str(instance.name))
                item_dict["ori_name"] = instance.name
                item_dict["is_online"] = instance.is_online
                item_dict["order_weight"] = QueryWordAttr.get_project_query_word_weight(instance.name)
                item_dict["results_num"] = QueryWordAttr.get_query_results_num(instance.name)
                item_dict["type_flag"] = get_tips_word_type(instance.name)
                item_dict["offline_score"] = 0.0
                item_dict["tips_name_type"] = 0
                ret_list.append(item_dict)
                suggest_list = get_tips_suggest_list(str(instance.name).lower())
            return (item_dict, suggest_list)
        except:
            logging.error("catch exception,err_msg:%s" % traceback.format_exc())
            return ([], [])


class TagTransferV1(object):
    tips_num_redis_key_prefix = "search_tips:tips_mapping_num"

    @classmethod
    def get_tag_data_name_mapping_results_to_redis(cls, instance):
        try:
            tag_name = instance.name.strip()
            q = dict()
            if tag_name:
                multi_fields = {
                    'short_description': 1,
                    'doctor.name': 1,
                    'doctor.hospital.name': 1,
                    'doctor.hospital.city_name': 1,
                    'doctor.hospital.city_province_name': 1,
                    'closure_tags': 1,  # 5.9版 搜索所有tag
                    'doctor.hospital.officer_name': 1  # 搜索机构管理者
                }
                query_fields = ['^'.join((k, str(v))) for (k, v) in multi_fields.items()]
                multi_match = {
                    'query': tag_name,
                    'type': 'cross_fields',
                    'operator': 'and',
                    'fields': query_fields,
                }
                sku_query = {
                    "nested": {
                        "path": "sku_list",
                        "query": {
                            "multi_match": {
                                "query": tag_name,
                                "fields": ["sku_list.name^2"],
                                'operator': 'and',
                                'type': 'cross_fields'
                            }
                        }
                    }
                }

                q['query'] = {
                    'bool': {
                        "should": [
                            {'multi_match': multi_match},
                            sku_query
                        ],
                        "must": [
                            {"term": {"is_online": True}}
                        ],
                        "minimum_should_match": 1
                    }
                }

                result_dict = ESPerform.get_search_results(ESPerform.get_cli(settings.GM_ORI_ES_INFO_LIST),
                                                           sub_index_name="service", doc_type="service", query_body=q,
                                                           offset=0, size=0)

                doctor_results = result_dict["total_count"]

                redis_data = redis_client.hget(cls.tips_num_redis_key_prefix, tag_name)

                redis_val_dict = json.loads(str(redis_data, encoding="utf-8")) if redis_data else {}

                total_count = doctor_results
                if 't' in redis_val_dict:
                    total_count += int(redis_val_dict['t'])

                redis_val_dict['t'] = total_count
                redis_val_dict['s'] = doctor_results

                redis_client.hset(cls.tips_num_redis_key_prefix, tag_name, json.dumps(redis_val_dict))
        except:
            logging.error("catch exception,err_msg:%s" % traceback.format_exc())

    @classmethod
    def get_tag_suggest_data_list(cls, instance):
        try:
            ret_list = list()
            suggest_list = list()
            keyword = instance.name
            cut_bool = False
            cut_word = ["下线", "停用", "已经下线", "账号停用"]
            for i in cut_word:
                if keyword.find(i) >= 0:
                    cut_bool = True
            item_dict = dict()
            ret_bol = QueryWordAttr.save_query_to_redis(query=str(instance.name), type_v1=True)
            if not cut_bool and ret_bol:
                item_dict["id"] = getMd5Digest(str(instance.name))
                item_dict["ori_name"] = instance.name
                item_dict["is_online"] = instance.is_online
                item_dict["order_weight"] = QueryWordAttr.get_project_query_word_weight(instance.name)
                item_dict["results_num"] = QueryWordAttr.get_query_results_num(instance.name)
                item_dict["type_flag"] = get_tips_word_type(instance.name)
                item_dict["offline_score"] = 0.0
                item_dict["tips_name_type"] = 0
                ret_list.append(item_dict)
                suggest_list = get_tips_suggest_list_v1(str(instance.name).lower())
            return (item_dict, suggest_list)
        except:
            logging.error("catch exception,err_msg:%s" % traceback.format_exc())
            return ([], [])
