from warnings import warn

from django import forms
from django.core.exceptions import ImproperlyConfigured
from django.urls import reverse
from django.urls.exceptions import NoReverseMatch
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _

from wagtail.admin.staticfiles import versioned_static
from wagtail.admin.telepath import register
from wagtail.admin.widgets import BaseChooser, BaseChooserAdapter
from wagtail.admin.widgets.button import Button
from wagtail.utils.deprecation import RemovedInWagtail80Warning


class AdminSnippetChooser(BaseChooser):
    display_title_key = "string"
    classname = "snippet-chooser"
    js_constructor = "SnippetChooser"

    def __init__(self, model, **kwargs):
        self.model = model
        name = self.model._meta.verbose_name
        self.choose_one_text = _("Choose %(object)s") % {"object": name}
        self.choose_another_text = _("Choose another %(object)s") % {"object": name}
        self.link_to_chosen_text = _("Edit this %(object)s") % {"object": name}

        super().__init__(**kwargs)

    def get_chooser_modal_url(self):
        try:
            return reverse(
                self.model.snippet_viewset.chooser_viewset.get_url_name("choose")
            )
        except NoReverseMatch as e:
            # This most likely failed because the model is not registered as a snippet.
            # Check whether this is the case, and if so, output a more helpful error message
            from .models import get_snippet_models

            if self.model not in get_snippet_models():
                raise ImproperlyConfigured(
                    "AdminSnippetChooser cannot be used on non-snippet model %r"
                    % self.model
                ) from e
            else:
                raise

    @cached_property
    def media(self):
        return forms.Media(
            js=[
                versioned_static("wagtailsnippets/js/snippet-chooser.js"),
            ]
        )


class SnippetChooserAdapter(BaseChooserAdapter):
    js_constructor = "wagtail.snippets.widgets.SnippetChooser"

    @cached_property
    def media(self):
        return forms.Media(
            js=[
                versioned_static("wagtailsnippets/js/snippet-chooser-telepath.js"),
            ]
        )


register(SnippetChooserAdapter(), AdminSnippetChooser)


class SnippetListingButton(Button):
    def __init__(self, *args, **kwargs):
        warn(
            "`SnippetListingButton` is deprecated. "
            "Use `wagtail.admin.widgets.button.Button` "
            "or `wagtail.admin.widgets.button.ListingButton` instead.",
            category=RemovedInWagtail80Warning,
        )
        super().__init__(*args, **kwargs)
