#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import logging
import traceback
import base64
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.models import wordresemble
from trans2es.commons.words_utils import QueryWordAttr, get_tips_word_type
from trans2es.commons.commons import get_tips_suggest_list, get_tips_suggest_list_v1
from trans2es.utils.doctor_transfer import DoctorTransfer
from trans2es.utils.itemwiki_transfer import ItemWikiTransfer
from trans2es.utils.tag_transfer import TagTransfer


class WordResemble(object):

    @classmethod
    def get_word_resemble_list(cls, keyword):
        try:
            query_sql_item = wordresemble.WordRel.objects.filter(keyword=keyword)

            temp_list = list()
            for sql_obj in query_sql_item:
                temp_list.extend(list(sql_obj.all_resembles.all().values_list('word', flat=True)))

            resemble_list = list()
            for item in temp_list:
                resemble_list.extend(item.split("、"))

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

    @classmethod
    def get_resemble_list(cls, instance):
        try:
            try:
                ret_list = list()
                item_dict = dict()
                keyword = instance.keyword
                cut_bool = False
                cut_word = ["下线", "停用", "已经下线", "账号停用"]
                for i in cut_word:
                    if keyword.find(i) >= 0:
                        cut_bool = True
                if cut_bool == False:
                    item_dict["id"] = getMd5Digest(str(instance.keyword))
                    item_dict["ori_name"] = instance.keyword
                    item_dict["is_online"] = True
                    item_dict["order_weight"] = QueryWordAttr.get_project_query_word_weight(instance.keyword)
                    item_dict["results_num"] = QueryWordAttr.get_query_results_num(instance.keyword)
                    item_dict["type_flag"] = get_tips_word_type(instance.keyword)
                    item_dict["offline_score"] = 0.0
                    item_dict["tips_name_type"] = 4
                    ret_list.append(item_dict)
                    suggest_list = get_tips_suggest_list(str(instance.keyword).lower())

                return (item_dict, suggest_list)

            except:
                logging.error("catch exception,err_msg:%s" % traceback.format_exc())
                return ([], [])
        except:
            logging.error("catch exception,err_msg:%s" % traceback.format_exc())
            return list()

    @classmethod
    def get_all_data_name_mapping_results_to_redis(cls, instance):
        try:
            total_count = 0
            instance.name = instance.keyword
            # 获取百科的
            ItemWikiTransfer.get_wiki_data_name_mapping_results_to_redis(instance)

            # 获取美购的
            TagTransfer.get_tag_data_name_mapping_results_to_redis(instance)

            # 获取医生医院的
            DoctorTransfer.get_doctor_data_name_mapping_results_to_redis(instance)

            # 获取日记的
            WordResemble.get_diary_data_name_mapping_results_to_redis(instance)

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

    @classmethod
    def get_diary_data_name_mapping_results_to_redis(cls, instance):
        try:

            tips_num_redis_key_prefix = "search_tips:tips_mapping_num"

            tag_name = instance.name.strip()
            q = dict()
            if tag_name:
                multi_fields = {
                    'tags': 8,
                    'doctor.name': 4,
                    'doctor.hospital.name': 3,
                    'doctor.hospital.officer_name': 3,
                    'user.last_name': 2,
                    'service.name': 1,
                    "title": 2}
                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,
                }
                q['query'] = {
                    'bool': {
                        "should": [
                            {'multi_match': multi_match}
                        ],
                        "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="diary", doc_type="diary", query_body=q,
                                                           offset=0, size=0)

                doctor_results = result_dict["total_count"]

                redis_data = redis_client.hget(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['r'] = doctor_results

                redis_client.hset(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 set_data_to_redis(cls, instance):
        try:
            keyword_value = []
            QUERY_KEY = "query:search_tip"
            tips_num_redis_key_prefix = "search_tips:tips_mapping_num"
            query_sql_item = wordresemble.WordRel.objects.filter(keyword=instance.keyword)
            for sql_obj in query_sql_item:
                count = 0
                words = list(sql_obj.all_resembles.all().values_list('word', flat=True))
                query_base64 = base64.b64encode(instance.keyword.encode('utf8')).decode('utf8')
                for items in words:
                    count += 1
                    wordresemble_value = []
                    # 先存储本体词
                    item_name = base64.b64encode(items.encode('utf8')).decode('utf8')
                    # 获取该同义词的结果
                    redis_data = redis_client.hget(tips_num_redis_key_prefix, items)
                    logging.info("get redis_data:%s" % redis_data)
                    redis_val_dict = json.loads(str(redis_data, encoding="utf-8")) if redis_data else {}
                    total_count = 0
                    if 't' in redis_val_dict:
                        total_count = int(redis_val_dict['t'])
                    value = {item_name: total_count}
                    keyword_value.append(value)
                    redis_data = redis_client.hget(tips_num_redis_key_prefix, instance.keyword)
                    redis_val_dict = json.loads(str(redis_data, encoding="utf-8")) if redis_data else {}
                    total_count = 0
                    if 't' in redis_val_dict:
                        total_count = int(redis_val_dict['t'])
                    value = {query_base64: total_count}
                    wordresemble_value.append(value)
                    if count == 1:
                        keyword_value.append(value)
                    if words:
                        for w in words:
                            value_name_w = base64.b64encode(w.encode('utf8')).decode('utf8')
                            redis_data = redis_client.hget(tips_num_redis_key_prefix, w)
                            redis_val_dict = json.loads(str(redis_data, encoding="utf-8")) if redis_data else {}
                            total_count = 0
                            if 't' in redis_val_dict:
                                total_count = int(redis_val_dict['t'])
                            value = {value_name_w: total_count}
                            wordresemble_value.append(value)
                    if len(wordresemble_value) > 0:
                        logging.info("get type wordresemble_value:%s" % type(json.dumps(wordresemble_value)))
                        redis_client.hset(QUERY_KEY, item_name, json.dumps(wordresemble_value))
                if len(keyword_value) > 0:
                    logging.info("get type keyword_value:%s" % type(json.dumps(keyword_value)))
                    redis_client.hset(QUERY_KEY, query_base64, json.dumps(keyword_value))
        except:
            logging.error("catch exception,err_msg:%s" % traceback.format_exc())


class WordResembleV1(object):

    @classmethod
    def get_word_resemble_list(cls, keyword):
        try:
            query_sql_item = wordresemble.WordRel.objects.filter(keyword=keyword)

            temp_list = list()
            for sql_obj in query_sql_item:
                temp_list.extend(list(sql_obj.all_resembles.all().values_list('word', flat=True)))

            resemble_list = list()
            for item in temp_list:
                resemble_list.extend(item.split("、"))

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

    @classmethod
    def get_resemble_list(cls, instance):
        try:
            try:
                ret_list = list()
                item_dict = dict()
                keyword = instance.keyword
                cut_bool = False
                cut_word = ["下线", "停用", "已经下线", "账号停用"]
                for i in cut_word:
                    if keyword.find(i) >= 0:
                        cut_bool = True
                if cut_bool == False:
                    item_dict["id"] = getMd5Digest(str(instance.keyword))
                    item_dict["ori_name"] = instance.keyword
                    item_dict["is_online"] = True
                    item_dict["order_weight"] = QueryWordAttr.get_project_query_word_weight(instance.keyword)
                    item_dict["results_num"] = QueryWordAttr.get_query_results_num(instance.keyword)
                    item_dict["type_flag"] = get_tips_word_type(instance.keyword)
                    item_dict["offline_score"] = 0.0
                    item_dict["tips_name_type"] = 4
                    ret_list.append(item_dict)
                    suggest_list = get_tips_suggest_list_v1(str(instance.keyword).lower())

                return (item_dict, suggest_list)

            except:
                logging.error("catch exception,err_msg:%s" % traceback.format_exc())
                return ([], [])
        except:
            logging.error("catch exception,err_msg:%s" % traceback.format_exc())
            return list()

    @classmethod
    def get_all_data_name_mapping_results_to_redis(cls, instance):
        try:
            total_count = 0
            instance.name = instance.keyword
            # 获取百科的
            ItemWikiTransfer.get_wiki_data_name_mapping_results_to_redis(instance)

            # 获取美购的
            TagTransfer.get_tag_data_name_mapping_results_to_redis(instance)

            # 获取医生医院的
            DoctorTransfer.get_doctor_data_name_mapping_results_to_redis(instance)

            # 获取日记的
            WordResemble.get_diary_data_name_mapping_results_to_redis(instance)

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

    @classmethod
    def get_diary_data_name_mapping_results_to_redis(cls, instance):
        try:

            tips_num_redis_key_prefix = "search_tips:tips_mapping_num"

            tag_name = instance.name.strip()
            q = dict()
            if tag_name:
                multi_fields = {
                    'tags': 8,
                    'doctor.name': 4,
                    'doctor.hospital.name': 3,
                    'doctor.hospital.officer_name': 3,
                    'user.last_name': 2,
                    'service.name': 1,
                    "title": 2}
                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,
                }
                q['query'] = {
                    'bool': {
                        "should": [
                            {'multi_match': multi_match}
                        ],
                        "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="diary", doc_type="diary", query_body=q,
                                                           offset=0, size=0)

                doctor_results = result_dict["total_count"]

                redis_data = redis_client.hget(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['r'] = doctor_results

                redis_client.hset(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 set_data_to_redis(cls, instance):
        try:
            keyword_value = []
            QUERY_KEY = "query:search_tip"
            tips_num_redis_key_prefix = "search_tips:tips_mapping_num"
            query_sql_item = wordresemble.WordRel.objects.filter(keyword=instance.keyword)
            for sql_obj in query_sql_item:
                count = 0
                words = list(sql_obj.all_resembles.all().values_list('word', flat=True))
                query_base64 = base64.b64encode(instance.keyword.encode('utf8')).decode('utf8')
                for items in words:
                    count += 1
                    wordresemble_value = []
                    # 先存储本体词
                    item_name = base64.b64encode(items.encode('utf8')).decode('utf8')
                    # 获取该同义词的结果
                    redis_data = redis_client.hget(tips_num_redis_key_prefix, items)
                    logging.info("get redis_data:%s" % redis_data)
                    redis_val_dict = json.loads(str(redis_data, encoding="utf-8")) if redis_data else {}
                    total_count = 0
                    if 't' in redis_val_dict:
                        total_count = int(redis_val_dict['t'])
                    value = {item_name: total_count}
                    keyword_value.append(value)
                    redis_data = redis_client.hget(tips_num_redis_key_prefix, instance.keyword)
                    redis_val_dict = json.loads(str(redis_data, encoding="utf-8")) if redis_data else {}
                    total_count = 0
                    if 't' in redis_val_dict:
                        total_count = int(redis_val_dict['t'])
                    value = {query_base64: total_count}
                    wordresemble_value.append(value)
                    if count == 1:
                        keyword_value.append(value)
                    if words:
                        for w in words:
                            value_name_w = base64.b64encode(w.encode('utf8')).decode('utf8')
                            redis_data = redis_client.hget(tips_num_redis_key_prefix, w)
                            redis_val_dict = json.loads(str(redis_data, encoding="utf-8")) if redis_data else {}
                            total_count = 0
                            if 't' in redis_val_dict:
                                total_count = int(redis_val_dict['t'])
                            value = {value_name_w: total_count}
                            wordresemble_value.append(value)
                    if len(wordresemble_value) > 0:
                        logging.info("get type wordresemble_value:%s" % type(json.dumps(wordresemble_value)))
                        redis_client.hset(QUERY_KEY, item_name, json.dumps(wordresemble_value))
                if len(keyword_value) > 0:
                    logging.info("get type keyword_value:%s" % type(json.dumps(keyword_value)))
                    redis_client.hset(QUERY_KEY, query_base64, json.dumps(keyword_value))
        except:
            logging.error("catch exception,err_msg:%s" % traceback.format_exc())
