import math
import numpy as np
import pandas  as pd
import operator
from nltk import word_tokenize, FreqDist
from nltk.corpus import stopwords
from models import *

class Metrics:

    def __init__(self):
        # self.mgclient = pymongo.MongoClient("mongodb://localhost:27017/")
        # self.sp_db = self.mgclient["semproxydb"]

        # self.D = self.sp_db.text_total.count()
        self.D = Content.select().count()
        self.df_dict = TermsDf.select(TermsDf.term).where(TermsDf.df > 2).dicts()
        self.df_dict = [i['term'] for i in self.df_dict]
        # self.df_dict = [i['term'] for i in self.sp_db['terms_df'].find({'df': {'$gt' : 2, '$lt': 50000}})]


    def get_idf(self, term):
        """Кол-во документов со словом в базе mongodb"""
        idf = False

        # df = self.sp_db.terms_df.find_one({'term':term})
        df = TermsDf.get(TermsDf.id == term).df
        if df is not None:
            if df['df'] > 0:
                idf = math.log(self.D / df['df'])
            else:
                idf = 0

        else:
            print('Нет слова в базе DF: {}'.format(term))

        return idf


    def get_tf(self, text, ones=False):

        tokens = [i for i in word_tokenize(text) if i in self.df_dict]

        lemmaFreq = FreqDist(tokens)
        sum_doc = np.array([lemmaFreq[i] for i in lemmaFreq]).sum()
        lemmaFreq = sorted(lemmaFreq.items(), key=operator.itemgetter(1))
        lemmaFreq.reverse()


        term_freq = [(i[0], i[1], round(i[1] / sum_doc, 5)) for i in lemmaFreq]

        # if ones:
        #     term_freq = [(i[0], i[1], round(i[1] / sum_doc, 5)) for i in lemmaFreq if i[1] == 1]
            #print(term_freq)
        # else:
        #     term_freq = [(i[0], i[1], round(i[1] / sum_doc, 5)) for i in lemmaFreq if i[1] > 1]
            #print(term_freq)
        return term_freq


    def get_tf_idf(self,term, tf):
        """Расчет TF IDF"""
        idf = self.get_idf(term)

        try:
            tfidf = round(tf * idf, 5)
        except:
            tfidf = False

        return tfidf


    def get_term_tfidf(self,term_freq):
        """вычисление tfidf по списку слов с частотами"""

        term_freq_tfidf = [(i[0], i[1], self.get_tf_idf(i[0], i[2])) \
            for i in term_freq if self.get_tf_idf(i[0], i[2]) is not False]

        term_freq_tfidf = sorted(term_freq_tfidf, key=operator.itemgetter(2))
        term_freq_tfidf.reverse()

        return term_freq_tfidf


    def get_text_tfidf(self, text):
        """вычисление tf-idf для всего текста. если минимально не набирается 10
        вводим слова единичные"""
        min = 10
        term_freq = self.get_tf(text)
        text_tfidf = self.get_term_tfidf(term_freq)

        # if len(text_tfidf) < min:
        #     term_freq_ones = self.get_tf(text, ones=True)
        #     text_tfidf_ones = self.get_term_tfidf(term_freq_ones)
        #     limit = min - len(text_tfidf)
        #     text_tfidf = text_tfidf + text_tfidf_ones[:limit]

        return text_tfidf


    def stopwords():

        stop_words = ["c","а","алло","без","белый","близко","более","больше","большой","будем",
              "будет","будете","будешь","будто","буду","будут","будь","бы","бывает","бывь","был",
              "была","были","было","быть","в","важная","важное","важные","важный","вам","вами","вас",
              "ваш","ваша","ваше","ваши","вверх","вдали","вдруг","ведь","везде","вернуться","весь","вечер",
              "взгляд","взять","вид","видел","видеть","вместе","вне","вниз","внизу","во","вода","война",
              "вокруг","вон","вообще","вопрос","восемнадцатый","восемнадцать","восемь","восьмой","вот",
              "впрочем","времени","время","все","все еще","всегда","всего","всем","всеми","всему","всех",
              "всею","всю","всюду","вся","всё","второй","вы","выйти","г","где","главный","глаз","говорил",
              "говорит","говорить","год","года","году","голова","голос","город","да","давать","давно","даже",
              "далекий","далеко","дальше","даром","дать","два","двадцатый","двадцать","две","двенадцатый",
              "двенадцать","дверь","двух","девятнадцатый","девятнадцать","девятый","девять","действительно",
              "дел","делал","делать","делаю","дело","день","деньги","десятый","десять","для","до","довольно",
              "долго","должен","должно","должный","дом","дорога","друг","другая","другие","других","друго",
              "другое","другой","думать","душа","е","его","ее","ей","ему","если","есть","еще","ещё","ею","её",
              "ж","ждать","же","жена","женщина","жизнь","жить","за","занят","занята","занято","заняты","затем",
              "зато","зачем","здесь","земля","знать","значит","значить","и","иди","идти","из","или","им","имеет",
              "имел","именно","иметь","ими","имя","иногда","их","к","каждая","каждое","каждые","каждый","кажется",
              "казаться","как","какая","какой","кем","книга","когда","кого","ком","комната","кому","конец","конечно",
              "которая","которого","которой","которые","который","которых","кроме","кругом","кто","куда",
              "лежать","лет","ли","лицо","лишь","лучше","любить","люди","м","маленький","мало","мать","машина",
              "между","меля","менее","меньше","меня","место","миллионов","мимо","минута","мир","мира","мне",
              "много","многочисленная","многочисленное","многочисленные","многочисленный","мной","мною","мог",
              "могу","могут","мож","может","может быть","можно","можхо","мои","мой","мор","москва","мочь","моя",
              "моё","мы","на","наверху","над","надо","назад","наиболее","найти","наконец","нам","нами","народ",
              "нас","начала","начать","наш","наша","наше","наши","не","него","недавно","недалеко","нее","ней",
              "некоторый","нельзя","нем","немного","нему","непрерывно","нередко","несколько","нет",
              "нею","неё","ни","нибудь","ниже","низко","никакой","никогда","никто","никуда","ним","ними",
              "них","ничего","ничто","но","новый","нога","ночь","ну","нужно","нужный","нх","о","об","оба",
              "обычно","один","одиннадцатый","одиннадцать","однажды","однако","одного","одной","оказаться",
              "окно","около","он","она","они","оно","опять","особенно","остаться","от","ответить","отец","откуда",
              "отовсюду","отсюда","очень","первый","перед","писать","плечо","по","под","подойди","подумать",
              "пожалуйста","позже","пойти","пока","пол","получить","помнить","понимать","понять","пор","пора",
              "после","последний","посмотреть","посреди","потом","потому","почему","почти","правда","прекрасно",
              "при","про","просто","против","процентов","путь","пятнадцатый","пятнадцать","пятый","пять","работа",
              "работать","раз","разве","рано","раньше","ребенок","решить","россия","рука","русский","ряд","рядом",
              "с","с кем","сам","сама","сами","самим","самими","самих","само","самого","самой","самом","самому",
              "саму","самый","свет","свое","своего","своей","свои","своих","свой","свою","сделать","сеаой","себе",
              "себя","сегодня","седьмой","сейчас","семнадцатый","семнадцать","семь","сидеть","сила","сих","сказал",
              "сказала","сказать","сколько","слишком","слово","случай","смотреть","сначала","снова","со","собой",
              "собою","советский","совсем","спасибо","спросить","сразу","стал","старый","стать","стол","сторона",
              "стоять","страна","суть","считать","т","та","так","такая","также","таки","такие","такое","такой","там",
              "твои","твой","твоя","твоё","те","тебе","тебя","тем","теми","теперь","тех","то","тобой","тобою",
              "товарищ","тогда","того","тоже","только","том","тому","тот","тою","третий","три","тринадцатый",
              "тринадцать","ту","туда","тут","ты","тысяч","у","увидеть","уж","уже","улица","уметь","утро",
              "хороший","хорошо","хотел бы","хотеть","хоть","хотя","хочешь","час","часто","часть","чаще","чего",
              "человек","чем","чему","через","четвертый","четыре","четырнадцатый","четырнадцать","что","чтоб",
              "чтобы","чуть","шестнадцатый","шестнадцать","шестой","шесть","эта","эти","этим","этими","этих",
              "это","этого","этой","этом","этому","этот","эту","я","являюсь"]

        return stop_words
