from __future__ import annotations

from typing import TYPE_CHECKING

from edc_protocol.research_protocol_config import ResearchProtocolConfig
from edc_utils.text import convert_from_camel

from ..url_config import UrlConfig

if TYPE_CHECKING:
    from django.urls import URLPattern


class UrlRequestContextError(Exception):
    pass


class UrlRequestContextMixin:
    urlconfig_getattr = "dashboard_urls"
    urlconfig_identifier_label = "subject_identifier"
    urlconfig_identifier_pattern = ResearchProtocolConfig().subject_identifier_pattern
    urlconfig_label = None
    url_name = None

    # @classmethod
    # def get_urlname(cls):
    #     return cls.url_name

    @classmethod
    def urls(
        cls,
        *,
        namespace: str,
        url_names_key: str,
        identifier_label: str | None = None,
        identifier_pattern: str | None = None,
    ) -> list[URLPattern]:
        """Returns a list of url patterns generated by UrlConfig.

        Each url pattern has the same name; `cls.url_name`.
        """
        url_names_key = (
            url_names_key
            or cls.urlconfig_label
            or convert_from_camel(cls.__name__.replace("view", "")).lower()
        )
        urlconfig = UrlConfig(
            view_class=cls,
            namespace=namespace,
            url_names_key=url_names_key,
            identifier_label=identifier_label or cls.urlconfig_identifier_label,
            identifier_pattern=identifier_pattern or cls.urlconfig_identifier_pattern,
        )
        if cls.urlconfig_getattr not in [
            "dashboard_urls",
            "listboard_urls",
            "review_listboard_urls",
        ]:
            raise UrlRequestContextError(
                f"Invalid urlconfig attr. Got {cls.urlconfig_getattr}."
            )
        return getattr(urlconfig, cls.urlconfig_getattr)

    # @staticmethod
    # def add_url_to_context(new_key=None, existing_key=None) -> dict[str, str]:
    #     """Add url as new_key to the context using the value
    #     of the existing_key from request.context_data.
    #     """
    #     if new_key != existing_key:
    #         try:
    #             url_data = {new_key: url_names.get(existing_key)}
    #         except InvalidDashboardUrlName as e:
    #             raise UrlRequestContextError(
    #                 f"Url name not defined in url_names. "
    #                 f"Expected one of {url_names.registry}. Got {e}. "
    #                 f"Hint: check if dashboard middleware is loaded."
    #             ) from e
    #         return url_data
    #     return {existing_key: url_names.get(existing_key)}
