import os
import pandas as pd
import pickle
from flask import Flask, jsonify, request, json
from utils import PreProcessing
from datetime import date, datetime


from sklearn.externals import joblib

class ApiJsonEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (date, datetime)):
            return obj.isoformat()
        return super(ApiJsonEncoder, self).default(obj)


app = Flask(__name__)
app.json_encoder = ApiJsonEncoder

@app.route('/')
def index():
	""" Index Web Page
	"""
	return "Modelo Mexico PML Day Ahead Forecast"

@app.route('/predict', methods=['POST'])
def apicall():
	"""API Call
	
	Pandas dataframe (sent as a payload) from API Call
	"""
	prepro = PreProcessing()
	
	try:
		data_json = request.data
		
		data = pd.read_json(data_json, orient='split')

		data['fecha_hora'] = pd.to_datetime(data['fecha_hora'])
		data.set_index('fecha_hora', inplace=True)

		data = prepro.process(data)
		data = data[data.index.date == data.index.max().date()].drop('price', axis=1)

		#Getting the datetime into separated out
		forecast_datetime = data.index

	except Exception as e:
		
		raise e
	
	rgs = 'lbrprice_model_svr.pkl'
	dir_path = os.path.dirname(os.path.realpath(__file__))

	if data.empty:
		return(bad_request())
		
	else:
		#Load the saved model
		print("Loading the model...")
		loaded_model = None
		try:
			with open(dir_path+'/models/'+rgs,'rb') as f:
				loaded_model = pickle.load(f)
		except Exception as e:
			print("Error loading model...", e)
			raise e

		print("The model has been loaded...doing predictions now...")
		predictions = loaded_model.predict(data)
		
		"""Add the predictions as Series to a new pandas dataframe
								OR
		   Depending on the use-case, the entire test data appended with the new files
		"""
		prediction_series = list(pd.Series(predictions))

		final_predictions = pd.DataFrame({'fecha_hora': forecast_datetime, 'pred_price': prediction_series})
		
		"""We can be as creative in sending the responses.
		   But we need to send the response codes as well.
		"""
		responses = jsonify(predictions=final_predictions.to_dict(orient="records"))
		responses.status_code = 200

		return (responses)


@app.errorhandler(400)
def bad_request(error=None):
	message = {
			'status': 400,
			'message': 'Bad Request: ' + request.url + '--> Please check your data payload...',
	}
	resp = jsonify(message)
	resp.status_code = 400

	return resp

if __name__ == '__main__':
	app.run(host='0.0.0.0')
