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

from functools import cached_property
from typing import override

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

from debusine.db.models import Collection, CollectionItem
from debusine.db.models.collections import CollectionRelation
from debusine.web.views import ui_shortcuts
from debusine.web.views.places import IndexPlace, ResourcePlace
from debusine.web.views.ui.base import UI


class CollectionUI(UI[Collection]):
    """UI helpers for Collection instances."""

    @cached_property
    def place(self) -> ResourcePlace:
        """Return a place to show this collection."""
        place = ResourcePlace(
            title=f"{self.instance.name}@{self.instance.category} collection",
            breadcrumb=self.instance.name,
            url=self.instance.get_absolute_url(),
            description=f"{self.instance.name}@{self.instance.category}"
            " collection",
        )
        place.parent = self.instance.workspace.ui(
            self.request
        ).place_collection_list
        return place

    @cached_property
    def place_search(self) -> IndexPlace:
        """Return a place to search this collection."""
        return IndexPlace(
            title=f"Search {self.instance.name}@{self.instance.category}",
            url=self.instance.get_absolute_url_search(),
            description=f"{self.instance} collection search",
            parent=self.instance.workspace.ui(
                self.request
            ).place_collection_list,
        )

    @cached_property
    def place_update(self) -> IndexPlace:
        """Return a place to configure this collection."""
        return IndexPlace(
            title="Configure properties",
            url=reverse(
                "workspaces:collections:update",
                kwargs={
                    "wname": self.instance.workspace.name,
                    "cname": self.instance.name,
                    "ccat": self.instance.category,
                },
            ),
            parent=self.place,
        )

    @cached_property
    def place_delete(self) -> IndexPlace:
        """Return a place to delete this collection."""
        return IndexPlace(
            title="Delete",
            url=reverse(
                "workspaces:collections:delete",
                kwargs={
                    "wname": self.instance.workspace.name,
                    "cname": self.instance.name,
                    "ccat": self.instance.category,
                },
            ),
            parent=self.place,
        )

    @cached_property
    def place_collection_relation_configure(self) -> IndexPlace:
        """Return a place to configure this collection."""
        return IndexPlace(
            title="Configure relations",
            url=reverse(
                "workspaces:collections:collection_relations:list",
                kwargs={
                    "wname": self.instance.workspace.name,
                    "cname": self.instance.name,
                    "ccat": self.instance.category,
                },
            ),
        )

    @cached_property
    def place_collection_relation_list(self) -> ResourcePlace:
        """Return a place to list similar relations for this collection."""
        collection = self.instance

        url = reverse(
            "workspaces:collections:collection_relations:list",
            kwargs={
                "wname": collection.workspace.name,
                "ccat": collection.category,
                "cname": collection.name,
            },
        )

        return ResourcePlace(
            title=format_html(
                "Relations of <code>{collection}</code> collection",
                collection=collection,
            ),
            url=url,
            breadcrumb="Relations",
            parent=collection.ui(self.request).place,
        )

    @cached_property
    def place_collection_relation_create(self) -> ResourcePlace:
        """Return a place to create a CollectionRelation."""
        collection = self.instance

        return ResourcePlace(
            title=format_html(
                "Create relation for <code>{collection}</code>",
                collection=collection,
            ),
            breadcrumb="Create",
            url=reverse(
                "workspaces:collections:collection_relations:create",
                kwargs={
                    "wname": collection.workspace.name,
                    "ccat": collection.category,
                    "cname": collection.name,
                },
            ),
            parent=self.place_collection_relation_list,
        )

    @cached_property
    def place_collection_relation_reorder_requires(self) -> ResourcePlace:
        """Return a place for re-ordering Requires relations."""
        collection = self.instance

        return ResourcePlace(
            title=format_html(
                "Reorder <code>{requires}</code> for <code>{collection}</code>",
                requires=CollectionRelation.Types.SUITE_REQUIRES.label,
                collection=collection,
            ),
            breadcrumb="Reorder",
            url=reverse(
                "workspaces:collections:collection_relations:reorder_requires",
                kwargs={
                    "wname": collection.workspace.name,
                    "ccat": collection.category,
                    "cname": collection.name,
                },
            ),
            parent=self.place,
        )

    @cached_property
    def place_suite_root(self) -> ResourcePlace:
        """Return a place for showing an archive."""
        suite = self.instance
        return ResourcePlace(
            title=format_html(
                "Suite <code>{collection}</code>", collection=suite
            ),
            breadcrumb=str(suite),
            url=reverse(
                "suite-root",
                kwargs={
                    "scope": suite.workspace.scope.name,
                    "workspace": suite.workspace.name,
                    "suite": suite.name,
                },
            ),
            parent=suite.workspace.ui(self.request).place_suite_list,
        )


class CollectionItemUI(UI[CollectionItem]):
    """UI helpers for CollectionItem instances."""

    @cached_property
    def place(self) -> ResourcePlace:
        """Return a place to show this collection item."""
        return ResourcePlace(
            title=self.instance.name,
            breadcrumb=self.instance.name,
            url=self.instance.get_absolute_url(),
            parent=self.instance.parent_collection.ui(self.request).place,
        )

    @override
    def build_ui_shortcuts(self) -> list[ui_shortcuts.UIShortcut]:
        result = super().build_ui_shortcuts()
        result.append(ui_shortcuts.create_collection_item(self.instance))
        if artifact := self.instance.artifact:
            result += [
                ui_shortcuts.create_artifact_view(artifact),
                ui_shortcuts.create_artifact_download(artifact),
            ]
        return result
