# coding=utf-8
""""""
from __future__ import absolute_import, division, print_function, \
    unicode_literals

import sqlalchemy as sa
from wtforms.fields import BooleanField, StringField
from wtforms.validators import ValidationError

from abilian.core.models.subjects import Group
from abilian.i18n import _, _l
from abilian.services.security.models import Role
from abilian.web.forms import Form, widgets
from abilian.web.forms.fields import QuerySelect2Field, Select2MultipleField
from abilian.web.forms.filters import strip
from abilian.web.forms.validators import optional, required


class BaseUserAdminForm(Form):

    email = StringField(
        _l('Email'),
        description=_l('Users log in with their email address.'),
        view_widget=widgets.EmailWidget(),
        filters=(strip,),
        validators=[required()],
    )
    first_name = StringField(
        _l('First Name'),
        description=_l('ex: John'),
        filters=(strip,),
        validators=[required()],
    )
    last_name = StringField(
        _l('Last Name'),
        description=_l('ex: Smith'),
        filters=(strip,),
        validators=[required()],
    )

    can_login = BooleanField(
        _l('Login enabled'),
        description=_l('If unchecked, user will not be able to connect.'),
        widget=widgets.BooleanWidget(),
    )

    groups = QuerySelect2Field(
        _l('Groups'),
        validators=(optional(),),
        multiple=True,
        collection_class=set,
        query_factory=
        lambda: Group.query.order_by(sa.sql.func.lower(Group.name).asc(),),
        get_label='name',
    )

    roles = Select2MultipleField(
        _l('Roles'),
        description=_l(
            'Prefer groups to manage access rights. Directly assigning roles '
            'to users is possible but discouraged.',
        ),
        choices=lambda: [(r.name, r.label) for r in Role.assignable_roles()],
    )

    password = StringField(
        _l('New Password'),
        description=_l('If empty the current password will not be changed.'),
        widget=widgets.PasswordInput(autocomplete='off'),
    )


class UserAdminForm(BaseUserAdminForm):

    confirm_password = StringField(
        _l('Confirm new password'),
        widget=widgets.PasswordInput(autocomplete='off'),
    )

    def validate_password(self, field):
        pwd = field.data
        confirmed = self['confirm_password'].data

        if pwd != confirmed:
            raise ValidationError(
                _(
                    'Passwords differ. Ensure you have typed same password in both'
                    ' "password" field and "confirm password" field.',
                ),
            )


class UserCreateForm(BaseUserAdminForm):

    password = StringField(
        _l('Password'),
        description=_l('If empty a random password will be generated.'),
        widget=widgets.PasswordInput(autocomplete='off'),
    )
