from datetime import datetime, timedelta
from flask import Blueprint, abort, config, current_app, flash, redirect, render_template, request, url_for
import flask_login
from flask_login import current_user, login_required
from goathacks.registration.forms import LoginForm, PwResetForm, RegisterForm, ResetForm
from werkzeug.security import check_password_hash, generate_password_hash
from flask_mail import Message
import ulid

from goathacks import db, mail as app_mail
from goathacks.models import PwResetRequest, User

bp = Blueprint('registration', __name__, url_prefix="/registration")

@bp.route("/", methods=["GET", "POST"])
def register():
    if current_user.is_authenticated:
        flash("You are already registered and logged in!")

    print("got register")
    form = RegisterForm(request.form)
    print(vars(form.gender))
    if request.method == 'POST':
        print("Got form")
        email = request.form.get('email')
        first_name = request.form.get('first_name')
        last_name = request.form.get('last_name')
        password = request.form.get('password')
        password_c = request.form.get('password_confirm')
        school = request.form.get('school')
        phone = request.form.get('phone_number')
        gender = request.form.get('gender')


        if password == password_c:
            # Passwords match!

            # Count of all non-waitlisted hackers
            num_not_waitlisted = len(User.query.filter_by(waitlisted=False).all())
            waitlisted = False
            print(num_not_waitlisted)
            print(current_app.config['MAX_BEFORE_WAITLIST'])
            if num_not_waitlisted >= current_app.config['MAX_BEFORE_WAITLIST']:
                waitlisted = True
            user = User(
                    email=email,
                    password=generate_password_hash(password),
                    first_name=first_name,
                    last_name=last_name,
                    last_login=datetime.now(),
                    waitlisted=waitlisted,
                    school=school,
                    phone=phone,
                    gender=gender
            )
            db.session.add(user)
            db.session.commit()
            flask_login.login_user(user)

            if waitlisted:
                msg = Message("Goathacks - Waitlist Confirmation")
            else:
                msg = Message("GoatHacks - Registration Confirmation")

            msg.add_recipient(user.email)
            msg.sender = ("GoatHacks Team", "hack@wpi.edu")
            msg.body = render_template("emails/registration.txt", user=user)
            app_mail.send(msg)

            return redirect(url_for("dashboard.home"))
        else:
            flash("Passwords do not match")

    return render_template("register.html", form=form)

@bp.route("/login", methods=["GET", "POST"])
def login():
    form = LoginForm(request.form)

    if request.method == 'POST':
        email = request.form.get('email')
        password = request.form.get('password')

        user = User.query.filter_by(email=email).first()
        if user == None:
            flash("Email or password incorrect")
            return render_template("login.html", form=form)

        if check_password_hash(user.password, password):
            flask_login.login_user(user)

            flash("Welcome back!")

            return redirect(url_for("dashboard.home"))
        else:
            flash("Incorrect password")

    return render_template("login.html", form=form)

@bp.route("/logout")
@login_required
def logout():
    flask_login.logout_user()
    flash("See you later!")
    return redirect(url_for("registration.login"))

@bp.route("/reset", methods=["GET", "POST"])
def reset():
    form = ResetForm(request.form)

    if request.method == 'POST':
        email = request.form.get('email')

        user = User.query.filter_by(email=email).first()

        if user == None:
            flash("If that email has an account here, we've just sent it a link to reset your password.")
            return redirect(url_for("registration.login"))
        else:
            r = PwResetRequest(
                    id=str(ulid.ulid()),
                    user_id=user.id,
                    expires=datetime.now() + timedelta(minutes=30)
                    )
            db.session.add(r)
            db.session.commit()
            
            msg = Message("GoatHacks - Password Reset Request")
            msg.add_recipient(user.email)
            msg.body = render_template("emails/password_reset.txt", code=r.id)
            app_mail.send(msg)
            flash("If that email has an account here, we've just sent it a link to reset your password.")
            return redirect(url_for("registration.login"))

    else:
        return render_template("pw_reset.html", form=form)

@bp.route("/reset/complete/<string:id>", methods=["GET", "POST"])
def do_reset(id):
    form = PwResetForm(request.form)
    req = PwResetRequest.query.filter_by(id=id).first()

    if req == None:
        flash("Invalid request")
        return redirect(url_for("registration.login"))

    if req.expires < datetime.now():
        db.session.delete(req)
        db.session.commit()
        flash("Invalid request")
        return redirect(url_for("registration.login"))

    if request.method == "POST":
        password = request.form.get("password")
        password_c = request.form.get("password_confirm")

        if password == password_c:
            user = User.query.filter_by(id=req.user_id).first()
            if user == None:
                flash("Invalid user")
                return redirect(url_for("registration.login"))
            user.password = generate_password_hash(password)
            db.session.delete(req)
            db.session.commit()
            flash("Password successfully reset")
            return redirect(url_for("registration.login"))
        else:
            flash("Passwords do not match!")
            return render_template("password_reset.html", form=form)
    else:
        return render_template("password_reset.html", form=form)