import os
from flask import (
    Flask, flash, render_template,
    redirect, request, session, url_for)
from flask_pymongo import PyMongo
from bson.objectid import ObjectId
from werkzeug.security import generate_password_hash, check_password_hash
if os.path.exists("env.py"):
    import env


app = Flask(__name__)

app.config["MONGO_DBNAME"] = os.environ.get("MONGO_DBNAME")
app.config["MONGO_URI"] = os.environ.get("MONGO_URI")
app.secret_key = os.environ.get("SECRET_KEY")


mongo = PyMongo(app)


@app.route("/")
@app.route("/home")
def home():
    return render_template("home.html")


@app.route("/get_recipes")
def get_recipes():
    recipes = list(mongo.db.recipes.find())

    return render_template("recipes.html", recipes=recipes)


@app.route("/search", methods=["GET", "POST"])
def search():
    query = request.form.get("query")
    recipes = list(mongo.db.recipes.find({"$text": {"$search": query}}))
    return render_template("recipes.html", recipes=recipes)


@app.route("/register", methods=["GET", "POST"])
def register():
    if request.method == "POST":
        # Cheks if the username exists in mongo
        existing_user = mongo.db.users.find_one(
            {"username": request.form.get("username").lower()})

        if existing_user:
            flash("This username already exists, try something different")
            return redirect(url_for("register"))

        register = {
            "username": request.form.get("username").lower(),
            "password": generate_password_hash(request.form.get("password"))
        }
        mongo.db.users.insert_one(register)

        # Saves the new user as a session cookie

        session["user"] = request.form.get("username").lower()
        flash("Thank You For Registering With Le Cuire")
        return redirect(url_for("profile", username=session["user"]))

    return render_template("register.html")


@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        # Checks if the username exists in mongo
        existing_user = mongo.db.users.find_one(
            {"username": request.form.get("username").lower()})

        if existing_user:
            # Makes sure the password matches the user input
            if check_password_hash(
                                    existing_user["password"],
                                    request.form.get("password")):
                session["user"] = request.form.get("username").lower()
                flash("Welcome, {} to Le Cuire".format(
                    request.form.get("username")))
                return redirect(url_for(
                    "profile", username=session["user"]))
            else:
                # invalid password
                flash("The credentials you typed are wrong")
                return redirect(url_for("login"))

        else:
            # If the username doesnt exist
            flash("The credentials you typed are wrong")
            return redirect(url_for("login"))

    return render_template("login.html")


@app.route("/profile/<username>", methods=["GET", "POST"])
def profile(username):
    # gets the users username from mongo
    username = mongo.db.users.find_one(
        {"username": session["user"]})["username"]

    if session["user"]:
        return render_template("profile.html", username=username)

    return redirect(url_for("login"))


@app.route("/logout")
def logout():
    # Removes session cookie from browser therefore logging the user out
    flash("You are now logged out")
    session.pop("user")
    return redirect(url_for("login"))


# Connects the mongo database to the recipes page by taking the
# information collected from the manage recipes form when submitted
@app.route("/manage_recipes", methods=["GET", "POST"])
def manage_recipes():
    if request.method == "POST":
        recipe = {
            "recipe_name": request.form.get("recipe_name"),
            "recipe_type": request.form.get("recipe_type"),
            "ingredients": request.form.get("ingredients"),
            "how_to_cook": request.form.get("how_to_cook"),
            "prep_time": request.form.get("prep_time"),
            "cook_time": request.form.get("cook_time"),
            "cleanup_time": request.form.get("cleanup_time"),
            "total_time": request.form.get("total_time"),
            "created_by": session["user"]
        }
        mongo.db.recipes.insert_one(recipe)
        flash("Recipe has been Added")
        return redirect(url_for("get_recipes"))

    mealType = mongo.db.mealType.find().sort("mealType", 1)
    return render_template("manage_recipes.html", mealType=mealType)


# The below code tells the edit page to find the correct database
# item that was selected in the recipes page by clicking the edit button
@app.route("/edit_recipe/<recipe_id>", methods=["GET", "POST"])
def edit_recipe(recipe_id):
    if request.method == "POST":
        submit = {
            "recipe_name": request.form.get("recipe_name"),
            "recipe_type": request.form.get("recipe_type"),
            "ingredients": request.form.get("ingredients"),
            "how_to_cook": request.form.get("how_to_cook"),
            "prep_time": request.form.get("prep_time"),
            "cook_time": request.form.get("cook_time"),
            "cleanup_time": request.form.get("cleanup_time"),
            "total_time": request.form.get("total_time"),
            "created_by": session["user"]
        }
        mongo.db.recipes.update({"_id": ObjectId(recipe_id)}, submit)
        flash("Recipe has successfully been updated")

    recipe = mongo.db.recipes.find_one({"_id": ObjectId(recipe_id)})
    mealType = mongo.db.mealType.find().sort("mealType", 1)
    return render_template(
        "edit_recipe.html", recipe=recipe, mealType=mealType)


@app.route("/delete_recipe/<recipe_id>")
def delete_recipe(recipe_id):
    mongo.db.recipes.remove({"_id": ObjectId(recipe_id)})
    flash("Recipe has been successfully deleted")
    return redirect(url_for("get_recipes"))


if __name__ == "__main__":
    app.run(host=os.environ.get("IP"),
            port=int(os.environ.get("PORT")),
            debug=False)    # change this to False when finished development
