import json
from django import forms
from django.dispatch import receiver
from django.urls import resolve, reverse
from django.utils.translation import gettext_noop, ugettext_lazy as _
from i18nfield.strings import LazyI18nString
from pretix.base.settings import settings_hierarkey
from pretix.base.signals import (
    order_modified,
    order_placed,
)
from pretix.base.templatetags.rich_text import rich_text_snippet
from pretix.control.signals import nav_event_settings
from pretix.presale.signals import question_form_fields

from .tasks import keycloak_create_user

settings_hierarkey.add_default("keycloak_create_user_items", [], list)
settings_hierarkey.add_default("keycloak_create_user_authorization_token", "", str)
settings_hierarkey.add_default("keycloak_create_user_realm_url", "", str)
settings_hierarkey.add_default(
    "keycloak_create_user_hint",
    LazyI18nString.from_gettext(
        gettext_noop("Your keycloak user will be created.")
    ),
    LazyI18nString,
)
settings_hierarkey.add_default(
    "keycloak_create_user_reason",
    "",
    LazyI18nString,
)


@receiver(question_form_fields, dispatch_uid="keycloak_create_user_questions")
def add_keycloak_username_question(sender, position, **kwargs):
    if str(position.item.pk) not in sender.settings.get("keycloak_create_user_items"):
        return {}

    if (
        not sender.settings.keycloak_create_user_authorization_token
        and not sender.settings.keycloak_create_user_realm_url
    ):
        return {}

    return {
        "keycloak_create_user_keycloak_username": forms.RegexField(
            label=_("Username"),
            required=False,
            regex="[a-z0-9._=/-]+",
            strip=True,
            error_messages={
                "invalid": _("Enter a valid username")
            },
            help_text=rich_text_snippet(sender.settings.keycloak_create_user_hint),
        )
    }


@receiver(order_placed, dispatch_uid="keycloak_create_user_order_placed")
@receiver(order_modified, dispatch_uid="keycloak_create_user_order_modified")
def keycloak_create_user_create_async(sender, order, **kwargs):
    if (
        not sender.settings.keycloak_create_user_authorization_token
        and not sender.settings.keycloak_create_user_realm_url
    ):
        return

    for order_position in order.positions.all():
        if str(order_position.item.pk) not in sender.settings.get(
            "keycloak_create_user_items"
        ):
            continue

        if not order_position.meta_info_data.get("question_form_data", {}).get(
            "keycloak_create_user_keycloak_username"
        ):
            continue

        keycloak_create_user.apply_async(
                args=(
                    sender.pk,
                    order.pk,
                    order_position.pk
                )
            )


@receiver(nav_event_settings, dispatch_uid="keycloak_create_user_keycloak_username_nav_settings")
def navbar_settings(sender, request=None, **kwargs):
    url = resolve(request.path_info)
    return [
        {
            "label": _("Create User"),
            "url": reverse(
                "plugins:pretix_keycloak_create_user:settings",
                kwargs={
                    "event": request.event.slug,
                    "organizer": request.organizer.slug,
                },
            ),
            "active": url.namespace == "plugins:pretix_keycloak_create_user"
            and url.url_name == "settings",
        }
    ]