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


class ChangePasswordForm(FlaskForm):
    password = PasswordField('Old password', validators=[DataRequired()])
    new_password = PasswordField(
        'New password',
        validators=[
            DataRequired(),
            EqualTo('new_password_2', message='Passwords must match')
        ]
    )
    new_password_2 = PasswordField(
        'New password confirmation',
        validators=[
            DataRequired(),
            EqualTo('new_password', message='Passwords must match')
        ]
    )
    submit = SubmitField()

    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.user = user

    def validate_current_password(self, field):
        if not self.user.verify_password(field.data):
            raise ValidationError('Invalid password')


class EditGeneralSettingsForm(FlaskForm):
    email = StringField(
        'E-Mail',
        validators=[InputRequired(), Length(max=254), Email()]
    )
    username = StringField(
        'Username',
        validators=[
            InputRequired(),
            Length(max=64),
            Regexp(
                USERNAME_REGEX,
                message=(
                    'Usernames must have only letters, numbers, dots or '
                    'underscores'
                )
            )
        ]
    )
    submit = SubmitField()

    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.user = user

    def prefill(self, user):
        self.email.data = user.email
        self.username.data = user.username

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

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


class EditInterfaceSettingsForm(FlaskForm):
    dark_mode = BooleanField('Dark mode')
    submit = SubmitField()

    def prefill(self, user):
        self.dark_mode.data = user.setting_dark_mode

class EditNotificationSettingsForm(FlaskForm):
    job_status_mail_notification_level = SelectField(
        'Job status mail notification level',
        choices=[('', 'Choose your option')],
        validators=[DataRequired()]
    )
    submit = SubmitField()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.job_status_mail_notification_level.choices += [
            (x.name, x.name.capitalize())
            for x in UserSettingJobStatusMailNotificationLevel
        ]

    def prefill(self, user):
        self.job_status_mail_notification_level.data = \
            user.setting_job_status_mail_notification_level.name
