# Copyright © The Debusine Developers
# See the AUTHORS file at the top-level directory of this distribution
#
# This file is part of Debusine. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution. No part of Debusine, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the LICENSE file.

"""UI helpers for scopes."""

from functools import cached_property

from django.urls import reverse
from django.utils.html import format_html

from debusine.db.models import Scope
from debusine.web.icons import Icons
from debusine.web.views.places import Place
from debusine.web.views.ui.base import UI


class CustomURLPlace(Place):
    """
    Place with a custom URL.

    This subclass tweaks rendering to use images from static files instead of
    bootstrap icons.
    """

    icon: str

    def as_icon(self) -> str:
        """
        Render the icon.

        :returns: the rendered HTML, or an empty string if this Place has no
          icon
        """
        from django.contrib.staticfiles.storage import staticfiles_storage

        url = staticfiles_storage.url(self.icon)
        if self.icon_title is not None:
            return format_html(
                """<img src="{url}" alt="{title}" style="height: 1em;" """
                """ class="d-inline-block align-middle"> """,
                url=url,
                title=self.icon_title,
            )
        else:
            return format_html(
                """<img src="{url}" style="height: 1em;" """
                """ class="d-inline-block align-middle"> """,
                url=url,
            )

    def as_nav(self) -> str:
        """Render as a <nav> link."""
        return format_html(
            """<a class="nav-link btn btn-light" href="{url}">"""
            "{icon}{title}</a>",
            url=self.url,
            icon=self.as_icon(),
            title=self.title,
        )

    def as_page_title(self) -> str:
        """Render as a page title."""
        return format_html(
            """<h1 class="mb-4">{icon}{title}</h1>""",
            icon=self.as_icon(),
            title=self.long_title or self.title,
        )


class ScopeUI(UI[Scope]):
    """UI helpers for Scope instances."""

    @cached_property
    def place(self) -> Place:
        """Return a place to show this scope."""
        from debusine.server.scopes import urlconf_scope

        with urlconf_scope(self.instance.name):
            url = reverse(
                "scopes:detail",
            )
        # Scope has an icon attribute which may be set to the appropriate
        # logo. If set, use a custom place implementation so we generate icons
        # as <img> tags instead of <span> ones
        if self.instance.icon:
            return CustomURLPlace(
                title=self.instance.name, url=url, icon=self.instance.icon
            )
        else:
            return Place(title=self.instance.name, url=url, icon=Icons.SCOPE)
