# coding=utf8
from __future__ import unicode_literals, absolute_import, print_function

import logging
import traceback
import json
from libs.cache import redis_client
from trans2es.models.query_word_conversion import TagConversion, DoctorConversion, HospitalConversion


class TagTab(object):
    Weight = {
        'search': 0.4,
        'trans': 0.6
    }

    SearchScore = {
        0.7: 100,
        0.1: 80,
        0.05: 60,
        0.01: 40,
        0: 20,
    }

    TransScore = {
        0.7: 100,
        0.5: 80,
        0.3: 60,
        0.1: 40,
        0: 20
    }

    def cal_score(self, search_rate, conversion_rate):
        s1 = self._cal_score(search_rate, 'SearchScore') * self.Weight['search']
        s2 = self._cal_score(conversion_rate, 'TransScore') * self.Weight['trans']
        return s1 + s2

    def _cal_score(self, item, type_):
        item *= 100.0
        scoreweight = getattr(self, type_)
        for k in sorted(scoreweight.keys(), reverse=True):
            if item >= k:
                return scoreweight[k]


class DocTab(TagTab):
    SearchScore = {
        0.04: 100,
        0.01: 80,
        0.001: 60,
        0.0002: 40,
        0: 20,
    }

    TransScore = {
        0.47: 100,
        0.2: 80,
        0.1: 60,
        0.01: 40,
        0: 20
    }


class HosTab(TagTab):
    SearchScore = {
        0.47: 100,
        0.2: 80,
        0.1: 60,
        0.01: 40,
        0: 20
    }

    TransScore = {
        1: 100,
        0.45: 90,
        0.27: 80,
        0.21: 70,
        0.15: 60,
        0.12: 50,
        0.09: 40,
        0.06: 30,
        0.04: 20,
        0: 10,
    }


class QueryWordAttr(object):
    # 获取TagConversion表最新的日期
    tag_latest_date = None
    doctor_latest_date = None
    hospital_latest_date = None

    tips_num_redis_key_prefix = "search_tips:tips_mapping_num"

    tagtab = TagTab()
    doctab = DocTab()
    hostab = HosTab()

    @classmethod
    def get_project_query_word_weight(cls, name):
        try:
            if not cls.tag_latest_date:
                cls.tag_latest_date = TagConversion.objects.latest('update_date').update_date

            tag_query_results = TagConversion.objects.filter(query=name, update_date=cls.tag_latest_date)

            total_score = 0.0
            for query_item in tag_query_results:
                item_score = cls.tagtab.cal_score(query_item.search_rate, query_item.conversion_rate)
                total_score += item_score

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

    @classmethod
    def get_doctor_query_word_weight(cls, name):
        try:
            if not cls.doctor_latest_date:
                cls.doctor_latest_date = DoctorConversion.objects.latest('update_date').update_date

            doc_query_results = DoctorConversion.objects.filter(query=name, update_date=cls.doctor_latest_date)

            total_score = 0.0
            for query_item in doc_query_results:
                item_score = cls.doctab.cal_score(query_item.search_rate, query_item.conversion_rate)
                total_score += item_score

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

    @classmethod
    def get_hospital_query_word_weight(cls, name):
        try:
            if not cls.hospital_latest_date:
                cls.hospital_latest_date = HospitalConversion.objects.latest('update_date').update_date

            hospital_query_results = HospitalConversion.objects.filter(query=name, update_date=cls.hospital_latest_date)

            total_score = 0.0
            for query_item in hospital_query_results:
                item_score = cls.hostab.cal_score(query_item.search_rate, query_item.conversion_rate)
                total_score += item_score

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

    @classmethod
    def get_query_results_num(cls, name):
        try:
            redis_data = redis_client.hget(cls.tips_num_redis_key_prefix, name)
            redis_val_dict = json.loads(str(redis_data, encoding="utf-8")) if redis_data else {}
            results_num = redis_val_dict['t'] if 't' in redis_val_dict else 0

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


from gm_rpcd.all import bind
from libs.cache import redis_client
import base64
from gm_types.doris import MIND_TYPE

QUERY_KEY = "query:{}:set"

LABEL_VALUE = {
    MIND_TYPE.PROJECT: 8,
    MIND_TYPE.HOSPITAL: 7,
    MIND_TYPE.DOCTOR: 6,
    MIND_TYPE.FREE_FACE: 4,
    MIND_TYPE.FACE: 3,
    MIND_TYPE.AREA: 2,
    MIND_TYPE.USER: 1,
    MIND_TYPE.UNKNOWN: 0
}

QUERY_WORD_LABEL_NEED_MODIFIED = {
    u"玻尿酸": MIND_TYPE.PROJECT,
    u"鼻": MIND_TYPE.PROJECT,
    u"眼": MIND_TYPE.PROJECT,
    u"嘴": MIND_TYPE.PROJECT,
    u"脱毛": MIND_TYPE.PROJECT
}


def label_key(label):
    return LABEL_VALUE.get(label)


def get_tips_word_type(query=''):
    query_base64 = base64.b64encode(query.encode('utf8')).decode('utf8')
    key = QUERY_KEY.format(query_base64)
    labels = list(map(lambda x: x.decode("utf8"), list(redis_client.smembers(key))))
    labels.append(MIND_TYPE.UNKNOWN)
    if query in QUERY_WORD_LABEL_NEED_MODIFIED:
        labels.append(MIND_TYPE.PROJECT)
    labels.sort(key=label_key, reverse=True)
    return labels[0]
