import numpy as np
from spacy import load as LOAD
from spacy.matcher import Matcher
from collections import Counter
import matplotlib.pyplot as plt
from spacy import util as util
import subprocess

if not util.is_package("es_core_news_md"):
    subprocess.run("python -m spacy download es_core_news_md")
    print("instalando el modelo de leguanje 'es_core_news_md', el kernel será reiniciado, porfavor vuelva a ejecutar su codigo")
else:  
    nlp = LOAD('es_core_news_md', disable=['parser','ner','textcat','...'] )
    matcher = Matcher(nlp.vocab)

    pattern_1 = [{"POS": "NOUN"},{"LOWER": "de"}, {"POS": "NOUN"}]
    pattern_2 = [{"POS": "NOUN"}, {"POS": "ADJ"}]

    matcher.add("NOUN-de-NOUN", [pattern_1])
    matcher.add("NOUN-ADJ", [pattern_2])




def get_keywords(dataFrame):
    new_row=np.zeros(len(dataFrame.index))
    dataFrame['keywords']=new_row
    for index,rows in dataFrame.iterrows():
        text=rows["text"]
        filteredText=''.strip()
        tokens = nlp(text)
        '''tokens = [token
                 for token in tokens
                 if not token.is_stop and not token.is_punct]'''
        for token in tokens:
            if token.pos_ == "NOUN" :
                filteredText=filteredText+str(token.text.lower().strip())+","
                
        matches = matcher(tokens)
        for mach_id, start, end in matches:
            span = tokens[start:end]
            filteredText=filteredText+str(span.text.lower().strip())+","
        dataFrame.loc[index,'keywords']=filteredText
        
def get_frequency(df):
    if "keywords" not in df:
        get_keywords(df)
    concept_freq_total=Counter({})

    for index, row in df.iterrows():
        arreglo=row["keywords"].split(",")
        arreglo.pop()
        concept_freq = Counter(arreglo)
        concept_freq_total = concept_freq_total + concept_freq
    return {"total_elements": sum(concept_freq_total.values()), "dictionary": concept_freq_total}

def group_by_date(dataset, granularity="month"):
    if granularity == "month":
        return dataset.groupby(by=["month","year"])
    if granularity == "year":
        return dataset.groupby(by=["year"])
    if granularity == "day":
        return dataset.groupby(by=["date"])
    
    
def build_sophia2_ngram_struct(dataset1,granularity="month"):
    if "keywords" not in dataset1:
        get_keywords(dataset1)
    dataset=dataset1.copy()
    dataset["month"]=dataset['date'].apply(lambda x: x.split("-")[1])
    dataset["year"]=dataset['date'].apply(lambda x: x.split("-")[0])
    gb_dataset=group_by_date(dataset, granularity)
    sophia2_ngram_struct = {}
    if granularity == "day":
        for key, ds in gb_dataset:
            sophia2_ngram_struct[key.strftime("%Y/%m/%d")] = get_frequency(ds)
    elif granularity == "month":
        for (month,year), ds in gb_dataset:
            sophia2_ngram_struct[(str(year)+"/"+str(month))] = get_frequency(ds)
    elif granularity == "year":
        for year, ds in gb_dataset:
            sophia2_ngram_struct[str(year)] = get_frequency(ds)
    else: return "Wrong granularity parameter, please use 'day', 'month' or 'year' as granularity parameter instead of "+granularity
    
    return sophia2_ngram_struct

def sophia_ngram_view(struct, words, annotate):
    ngram_dictionary={}
    for palabra in words:
        ngram_dictionary[palabra]=[]
        keys=[]
        for key in struct:
            keys.append(key)
            ngram_dictionary[palabra].append(struct[key]["dictionary"][palabra])
        plt.plot(keys,ngram_dictionary[palabra],label=palabra)
        plt.legend(loc=5, bbox_to_anchor=(1.3, 0.5), fancybox=True, shadow=True )
        plt.title("PySophia NGramViewer")
        if(annotate):
            for xy in zip(keys, ngram_dictionary[palabra]):                                       # <--
                plt.annotate('%s' % xy[1], xy=xy, textcoords='data')
    plt.xlabel('Fecha', fontsize=12)
    plt.ylabel('Apariciones', fontsize=12)
    
    
def get_n_most_freq(freq_struct, n, graph=False):
    '''provides a list with all the countries that currently have media outlets in Sun

    Returns:
        [string]: [country_name]
    '''
    dict_orders = sorted(freq_struct["dictionary"].items(), key=lambda x: x[1], reverse=True)
    if graph:
        
        x = [x[0] for x in dict_orders[:n]]
        y = [x[1]/freq_struct["total_elements"] for x in dict_orders[:n]]
        plt.bar(x,y)
        plt.title("term frequency top %i words" %(n))
    return dict_orders[:n]


