import pandas as pd
import numpy as np
import keras
import tensorflow as tf
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import *
from keras.utils.np_utils import to_categorical
from keras.initializers import Constant
from keras.engine import Layer, InputSpec
from tensorflow.keras import backend
from keras import initializers
from keras import regularizers
from keras import constraints
import re
from keras.callbacks import ModelCheckpoint
from att_keras import Attention
from sklearn.model_selection import ParameterGrid
from sklearn.metrics import classification_report, f1_score, accuracy_score, confusion_matrix, make_scorer, precision_recall_fscore_support

#random_seed={555,666,777}
np.random.seed(555)
tf.set_random_seed(555)

train=pd.read_csv("../yida_mu/tr1.csv")
dev=pd.read_csv("../yida_mu/de1.csv")
test=pd.read_csv("../yida_mu/te1.csv")
###
xtrain=train['text'].values
ytrain = train.labels.values
###
xdev=dev['text'].values
ydev = dev.labels.values
###
xtest=test['text'].values
ytest = test.labels.values
###
max_features=50000
sequence_length=3000
tk = Tokenizer(num_words=max_features, lower=False)
tk.fit_on_texts(xtrain)
###
xtrain=tk.texts_to_sequences(xtrain)
xdev=tk.texts_to_sequences(xdev)
xtest=tk.texts_to_sequences(xtest)
###
xtr=pad_sequences(xtrain, sequence_length)
xde=pad_sequences(xdev, sequence_length)
xte=pad_sequences(xtest, sequence_length)
###

embeddings_index = {}
f = open('../data/glove.twitter.27B.200d.txt')
for line in f:
    values = line.split()
    word = values[0]
    coefs = np.asarray(values[1:], dtype='float32')
    embeddings_index[word] = coefs

f.close()

###
word_index=tk.word_index
embedding_dim = 200
num_words=max_features+1
embedding_matrix = np.zeros((num_words, embedding_dim))
###
for word, i in tk.word_index.items():
    if i > max_features:
        break
    else:
        embedding_vector = embeddings_index.get(word)
        if embedding_vector is not None:
            embedding_matrix[i] = embedding_vector


p_grid = {"unit": [50, 75, 100], "dropout": [0.2, 0.5]}
params_comb = list(ParameterGrid(p_grid))

for i in params_comb:
    model = Sequential()
    model.add(Embedding(num_words,
                        embedding_dim,
                        weights=[embedding_matrix],
                        input_length=sequence_length,
                        trainable=False))
    model.add(Bidirectional(CuDNNGRU(units=i["unit"], return_sequences=True)))
    model.add(Dropout(i["dropout"]))
    model.add(Attention())
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss = 'binary_crossentropy', optimizer='adam',metrics = ['accuracy'])
    checkpointer = ModelCheckpoint(filepath="../data/a4x.hdf5", monitor='val_loss', verbose=1, save_best_only=True)
    history=model.fit(xtr, ytrain, validation_data=[xde, ydev], epochs = 10, batch_size=64, callbacks=[checkpointer])
    model.load_weights('../data/a4x.hdf5')
    pre=model.predict(xte, batch_size=64)
    pres=[]
    for i in pre:
        pres.append(1 if i>0.5 else 0)
    print(precision_recall_fscore_support(ytest, pres, average='macro'))