#Flask imports
from flask import Blueprint, render_template, flash, redirect, url_for, abort
from flask.ext.login import LoginManager, login_required, logout_user, login_user

#App imports
from app import app
from app.mod_auth.forms import LoginForm, UserForm, EmailForm, PasswordForm
from app.mod_auth.models import User
from utils import ts, send_email

lm = LoginManager()
lm.init_app(app)
lm.login_view = "auth.user_login"
mod_auth = Blueprint('auth', __name__, url_prefix='/user', 
    template_folder='templates')


@lm.user_loader
def user_load(id):
    return User.get_by_id(int(id))


@mod_auth.route('/login/', methods=['GET', 'POST'])
def user_login():
    #special case if database is empty we should create an user
    if len(User.get_all()) == 0:
        return redirect(url_for('auth.user_create'))

    form = LoginForm()

    if form.validate_on_submit():
        user = User.get_by_email(email=form.email.data)
        if user and User.check_password(user.password, form.password.data):
            login_user(user)
            return redirect(url_for('index'))
        flash('Wrong email or password')
    return render_template("login.html", form=form)


@mod_auth.route('/logout/')
@login_required
def user_logout():
    logout_user()
    return redirect(url_for('index'))

@mod_auth.route('/create', methods=["GET", "POST"])
def user_create():
    form = UserForm()
    if form.validate_on_submit():
        user = User()
        user.name = form.name.data
        user.email = form.email.data
        user.password = form.password.data
        user.is_admin = form.is_admin.data
        #TODO Fix possible duplicated keys!
        User.save(user)

        # Now we'll send the email confirmation link
        subject = "Confirm your email"

        token = ts.dumps(user.email, salt='email-confirm-key')

        confirm_url = url_for(
            'auth.user_confirm_email',
            token=token,
            _external=True)

        html = render_template(
            'activate.html',
            confirm_url=confirm_url)

        # We'll assume that send_email has been defined in myapp/util.py
        app.logger.info('Url use to confirm: {0}'.format(confirm_url))
        send_email(user.email, subject, html)

        return redirect(url_for("index"))

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

@mod_auth.route('/confirm/<token>')
def user_confirm_email(token):
    try:
        email = ts.loads(token, salt="email-confirm-key", max_age=86400)
    except:
        abort(404)

    user = User.get_by_email(email=email)
    user.email_confirmed = True
    User.save(user)

    return redirect(url_for('auth.user_login'))

@mod_auth.route('/reset', methods=["GET", "POST"])
def user_password_reset():
    form = EmailForm()
    if form.validate_on_submit():
        user = User.get_by_email(email=form.email.data)

        subject = "Password reset requested"

        # Here we use the URLSafeTimedSerializer we created in `util` at the
        # beginning of the chapter
        token = ts.dumps(user.email, salt='recover-key')

        recover_url = url_for(
            'auth.user_reset_password_with_token',
            token=token,
            _external=True)

        html = render_template(
            'recover.html',
            recover_url=recover_url)

        # Let's assume that send_email was defined in myapp/util.py
        send_email(user.email, subject, html)

        return redirect(url_for('index'))
    return render_template('reset.html', form=form)

@mod_auth.route('/reset/<token>', methods=["GET", "POST"])
def user_reset_password_with_token(token):
    try:
        email = ts.loads(token, salt="recover-key", max_age=86400)
    except:
        abort(404)

    form = PasswordForm()

    if form.validate_on_submit():
        user = User.get_by_email(email=email)
        user.password = form.password.data
        User.save(user)
        return redirect(url_for('auth.user_login'))

    return render_template('reset_with_token.html', form=form, token=token)
