from flask_wtf import FlaskForm
from wtforms import (
    BooleanField,
    PasswordField,
    StringField,
    SubmitField,
    ValidationError
)
from wtforms.validators import InputRequired, Email, EqualTo, Length, Regexp
from app.models import User
from . import USERNAME_REGEX


class RegistrationForm(FlaskForm):
    email = StringField(
        'Email',
        validators=[InputRequired(), Email(), Length(max=254)]
    )
    username = StringField(
        'Username',
        validators=[
            InputRequired(),
            Length(max=64),
            Regexp(
                USERNAME_REGEX,
                message=(
                    'Usernames must have only letters, numbers, dots or '
                    'underscores'
                )
            )
       ]
    )
    password = PasswordField(
        'Password',
        validators=[
            InputRequired(),
            EqualTo('password_2', message='Passwords must match')
        ]
    )
    password_2 = PasswordField(
        'Password confirmation',
        validators=[
            InputRequired(),
            EqualTo('password', message='Passwords must match')
        ]
    )
    submit = SubmitField()

    def validate_email(self, field):
        if User.query.filter_by(email=field.data.lower()).first():
            raise ValidationError('Email already registered')

    def validate_username(self, field):
        if User.query.filter_by(username=field.data).first():
            raise ValidationError('Username already in use')


class LoginForm(FlaskForm):
    user = StringField('Email or username', validators=[InputRequired()])
    password = PasswordField('Password', validators=[InputRequired()])
    remember_me = BooleanField('Keep me logged in')
    submit = SubmitField()


class ResetPasswordRequestForm(FlaskForm):
    email = StringField('Email', validators=[InputRequired(), Email()])
    submit = SubmitField()


class ResetPasswordForm(FlaskForm):
    password = PasswordField(
        'New password',
        validators=[
            InputRequired(),
            EqualTo('password_2', message='Passwords must match')
        ]
    )
    password_2 = PasswordField(
        'New password confirmation',
        validators=[
            InputRequired(),
            EqualTo('password', message='Passwords must match')
        ]
    )
    submit = SubmitField()