#!flask/bin/python
from flask import Flask, jsonify, request
from flask_cors import CORS, cross_origin

# Slack
import os
from slackclient import SlackClient


# things we need for NLP
import nltk
from nltk.stem.lancaster import LancasterStemmer

# things we need for Tensorflow
import numpy as np
import tflearn
import tensorflow as tf
import random

# restore all of our data structures
import pickle
import json

stemmer = LancasterStemmer()

#english data
nltk.download('punkt')

data = pickle.load( open( "training_data", "rb" ) )
words = data['words']
classes = data['classes']
train_x = data['train_x']
train_y = data['train_y']

# import our chat-bot intents file
with open('intents.json') as json_data:
    intents = json.load(json_data)

# Build neural network
net = tflearn.input_data(shape=[None, len(train_x[0])])
net = tflearn.fully_connected(net, 8)
net = tflearn.fully_connected(net, 8)
net = tflearn.fully_connected(net, len(train_y[0]), activation='softmax')
net = tflearn.regression(net)

# Define model and setup tensorboard
model = tflearn.DNN(net, tensorboard_dir='tflearn_logs')


def clean_up_sentence(sentence):
    # tokenize the pattern
    sentence_words = nltk.word_tokenize(sentence)
    # stem each word
    sentence_words = [stemmer.stem(word.lower()) for word in sentence_words]
    return sentence_words

# return bag of words array: 0 or 1 for each word in the bag that exists in the sentence
def bow(sentence, words, show_details=False):
    # tokenize the pattern
    sentence_words = clean_up_sentence(sentence)
    # bag of words
    bag = [0]*len(words)
    for s in sentence_words:
        for i,w in enumerate(words):
            if w == s:
                bag[i] = 1
                if show_details:
                    print ("found in bag: %s" % w)

    return(np.array(bag))


model.load('./model.tflearn')


# create a data structure to hold user context
context = {}

ERROR_THRESHOLD = 0.25

def classify(sentence):
    # generate probabilities from the model
    results = model.predict([bow(sentence, words)])[0]
    # filter out predictions below a threshold
    results = [[i,r] for i,r in enumerate(results) if r>ERROR_THRESHOLD]
    # sort by strength of probability
    results.sort(key=lambda x: x[1], reverse=True)
    return_list = []
    for r in results:
        return_list.append((classes[r[0]], r[1]))
    # return tuple of intent and probability
    return return_list

def response(sentence, userID='123', show_details=False):
    results = classify(sentence)
    # if we have a classification then find the matching intent tag
    if results:
        # loop as long as there are matches to process
        while results:
            for i in intents['intents']:
                # find a tag matching the first result
                if i['tag'] == results[0][0]:
                    # set context for this intent if necessary
                    if 'context_set' in i:
                        if show_details: print ('context:', i['context_set'])
                        context[userID] = i['context_set']

                    # check if this intent is contextual and applies to this user's conversation
                    if not 'context_filter' in i or \
                        (userID in context and 'context_filter' in i and i['context_filter'] == context[userID]):
                        if show_details: print ('tag:', i['tag'])
                        # a random response from the intent
                        return random.choice(i['responses'])

            results.pop(0)

SLACK_TOKEN = os.environ['SLACK_TOKEN']
sc = SlackClient(SLACK_TOKEN)


app = Flask(__name__)
CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'


def jarvisResponse(channel, message):
    # sends a response
    print(channel)
    print(response(message))
    sc.api_call(
      "chat.postMessage",
      channel=channel,
      text=response(message),
    )


@app.route("/", methods=['POST'])
def hello():
    print(request.json)
    if "event" in request.json:
        print(request.json["event"])
        if(request.json["event"]["type"] == "message"):
            if("user" in request.json["event"]):
                if(request.json["event"]["user"] is not "B7H3RC753"):
                    jarvisResponse(request.json["event"]["channel"],
                                   request.json["event"]["text"])

    if "challenge" in request.json:
        return jsonify({'challenge': request.json["challenge"]})

    return jsonify({'challenge': 'test'})


@app.route('/getAnwser', methods=['POST'])
@cross_origin()
def get_answer():
    if request.json is not None:
        if request.json['message'] is not None:
            return jsonify({'message': response(request.json['message'])})
        else:
            print('request message is none')
            return ''
    else:
        return''
