from wtforms import (
    EmailField,
    FieldList,
    Form,
    FormField,
    PasswordField,
    StringField,
    validators,
    widgets,
)

from fief.forms import (
    ComboboxSelectField,
    CSRFBaseForm,
    empty_string_to_none,
    get_form_field,
)
from fief.models import UserField


class BaseUserForm(CSRFBaseForm):
    email = EmailField(
        "Email address", validators=[validators.InputRequired(), validators.Email()]
    )

    @classmethod
    async def get_form_class(
        cls, user_fields: list[UserField]
    ) -> type["UserCreateForm"]:
        class UserFormFields(Form):
            pass

        for field in user_fields:
            setattr(UserFormFields, field.slug, get_form_field(field))

        class UserForm(cls):  # type: ignore
            fields = FormField(UserFormFields)

        return UserForm


class UserCreateForm(BaseUserForm):
    password = PasswordField(
        "Password",
        validators=[validators.InputRequired()],
        widget=widgets.PasswordInput(hide_value=False),
    )
    tenant = ComboboxSelectField(
        "Tenant",
        query_endpoint_path="/admin/tenants/",
        validators=[validators.InputRequired(), validators.UUID()],
    )


class UserUpdateForm(BaseUserForm):
    password = PasswordField(
        "Password",
        filters=(empty_string_to_none,),
        widget=widgets.PasswordInput(hide_value=False),
    )


class UserAccessTokenForm(CSRFBaseForm):
    client = ComboboxSelectField(
        "Client",
        description="The access token will be tied to this client.",
        query_endpoint_path="/admin/clients/",
        validators=[validators.InputRequired(), validators.UUID()],
    )
    scopes = FieldList(
        StringField(validators=[validators.InputRequired()]),
        label="Scopes",
        default=["openid"],
    )


class CreateUserPermissionForm(CSRFBaseForm):
    permission = ComboboxSelectField(
        "Add new permission",
        query_endpoint_path="/admin/access-control/permissions/",
        validators=[validators.InputRequired(), validators.UUID()],
    )


class CreateUserRoleForm(CSRFBaseForm):
    role = ComboboxSelectField(
        "Add new role",
        query_endpoint_path="/admin/access-control/roles/",
        validators=[validators.InputRequired(), validators.UUID()],
    )
