import logging
import operator
import collections
import json

from celery import shared_task
from django.conf import settings
from gm_types.gaia import SEARCH_KEYWORDS_TYPE

from doris.utils.words_utils import tab, doctab, hostab
from ..models.statistic import TagConversion, DoctorConversion, HospitalConversion
from doris.models.search import WordsRecomend
logger = logging.getLogger(__name__)


@shared_task
def cal_search_words():
    logger.info('start cal search words.')

    WordsRecomend.objects.filter().delete()

    re_tab, date = _cal_tab_words()
    for province_id, words in re_tab.items():
        WordsRecomend.objects.update_or_create(
            date=date,
            province_id=province_id,
            tab=SEARCH_KEYWORDS_TYPE.DEFAULT,
            defaults={'words': json.dumps(words)}
           )

    logger.info('cal tab words done, start cal doc tab')
    re_doc, date = _cal_doc_tab()
    for province_id, words in re_doc.items():
        WordsRecomend.objects.update_or_create(
            date=date,
            province_id=province_id,
            tab=SEARCH_KEYWORDS_TYPE.DOCTOR,
            defaults={'words': json.dumps(words)}
           )

    logger.info('cal doc tab done, start cal hos tab')
    re_hos, date = _cal_hos_tab()
    for province_id, words in re_hos.items():
        WordsRecomend.objects.update_or_create(
            date=date,
            province_id=province_id,
            tab=SEARCH_KEYWORDS_TYPE.HOSPITAL,
            defaults={'words': json.dumps(words)}
           )

    logger.info('cal search words done.')
    print('done')
    return None


def _cal_tab_words():
    latest_date = TagConversion.objects.latest('update_date').update_date
    tag_cons = TagConversion.objects.filter(update_date=latest_date, province_id__isnull=False)
    score = collections.defaultdict(dict)
    for t in tag_cons:
        _score = tab.cal_score(t.search_rate, t.conversion_rate)
        score[t.province_id].update({t.query: _score})

    result = {}
    for province_id, _scores in score.items():
        re_order_score = sorted(_scores.items(), key=operator.itemgetter(1), reverse=True)
        result.update({province_id: [item[0] for item in re_order_score[:settings.RECOMMEND_SEARCH_WORDS_COUNT]]})

    return result, latest_date


def _cal_doc_tab():
    latest_date = DoctorConversion.objects.latest('update_date').update_date
    tag_cons = DoctorConversion.objects.filter(update_date=latest_date, province_id__isnull=False)
    score = collections.defaultdict(dict)
    for t in tag_cons:
        _score = doctab.cal_score(t.search_rate, t.conversion_rate)
        score[t.province_id].update({t.query: _score})

    result = {}
    for province_id, _scores in score.items():
        re_order_score = sorted(_scores.items(), key=operator.itemgetter(1), reverse=True)
        result.update({province_id: [item[0] for item in re_order_score[:settings.RECOMMEND_SEARCH_WORDS_COUNT]]})

    return result, latest_date


def _cal_hos_tab():
    latest_date = HospitalConversion.objects.latest('update_date').update_date
    tag_cons = HospitalConversion.objects.filter(update_date=latest_date, province_id__isnull=False)
    score = collections.defaultdict(dict)
    for t in tag_cons:
        _score = hostab.cal_score(t.search_rate, t.conversion_rate)
        score[t.province_id].update({t.query: _score})

    result = {}
    for province_id, _scores in score.items():
        re_order_score = sorted(_scores.items(), key=operator.itemgetter(1), reverse=True)
        result.update({province_id: [item[0] for item in re_order_score[:settings.RECOMMEND_SEARCH_WORDS_COUNT]]})

    return result, latest_date
