# 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.

"""
View extension to model page descriptions.

A Place describes information about a page that can be used to generate
elements like page titles and breadcrumb elements.
"""

from dataclasses import dataclass

from django.utils.html import format_html
from django.utils.safestring import SafeString


@dataclass(kw_only=True)
class Place:
    """Describe a page in Debusine's web space."""

    #: Short title
    title: str
    #: Long title (defaulting to short)
    long_title: str | None = None
    #: URL
    url: str | None = None
    #: Icon
    icon: str | None = None
    #: Icon title
    icon_title: str | None = None

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

        :returns: the rendered HTML, or an empty string if this Place has no
          icon
        """
        if self.icon is None:
            return SafeString()
        if self.icon_title is not None:
            return format_html(
                """<span class="bi bi-{icon}" """
                """title="{icon_title}"></span> """,
                icon=self.icon,
                icon_title=self.icon_title,
            )
        else:
            return format_html(
                """<span class="bi bi-{icon}"></span> """, icon=self.icon
            )

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

    def as_head_title(self) -> str:
        """Render as a <title> element."""
        return format_html(
            "<title>Debusine - {title}</title>",
            title=self.long_title or 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,
        )
