# 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 (
    PlaceValue,
    ResourceMainPlace,
    ResourceSubPlace,
)
from debusine.web.views.ui.base import UI


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

    @cached_property
    def collection_name(self) -> str:
        """Return a short name for the collection."""
        return f"{self.instance.name}@{self.instance.category}"

    @cached_property
    def place(self) -> ResourceMainPlace[Collection]:
        """Return a place to show this collection."""
        place = ResourceMainPlace(
            ui=self,
            title=PlaceValue(
                self.collection_name, page=f"{self.collection_name} collection"
            ),
            url=self.instance.get_absolute_url(),
            description=f"{self.collection_name} collection",
        )
        place.parent = self.instance.workspace.ui(
            self.request
        ).place_collection_list
        return place

    @cached_property
    def place_search(self) -> ResourceSubPlace[Collection]:
        """Return a place to search this collection."""
        return ResourceSubPlace(
            ui=self,
            title=PlaceValue("search", page=f"Search {self.collection_name}"),
            url=self.instance.get_absolute_url_search(),
            description=f"{self.collection_name} collection search",
            parent=self.instance.workspace.ui(
                self.request
            ).place_collection_list,
        )

    @cached_property
    def place_update(self) -> ResourceSubPlace[Collection]:
        """Return a place to configure this collection."""
        return ResourceSubPlace(
            ui=self,
            title=PlaceValue("settings", page="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) -> ResourceSubPlace[Collection]:
        """Return a place to delete this collection."""
        return ResourceSubPlace(
            ui=self,
            title=PlaceValue("delete", page="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,
    ) -> ResourceSubPlace[Collection]:
        """Return a place to configure this collection."""
        return ResourceSubPlace(
            ui=self,
            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) -> ResourceSubPlace[Collection]:
        """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 ResourceSubPlace(
            ui=self,
            title=PlaceValue(
                "Relations",
                page=format_html(
                    "Relations of <code>{collection}</code> collection",
                    collection=self.collection_name,
                ),
            ),
            url=url,
            parent=collection.ui(self.request).place,
        )

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

        return ResourceSubPlace(
            ui=self,
            title=PlaceValue(
                "Create",
                page=format_html(
                    "Create relation for <code>{collection}</code>",
                    collection=collection,
                ),
            ),
            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,
    ) -> ResourceSubPlace[Collection]:
        """Return a place for re-ordering Requires relations."""
        collection = self.instance

        return ResourceSubPlace(
            ui=self,
            title=PlaceValue(
                "Reorder",
                page=format_html(
                    "Reorder <code>{requires}</code>"
                    " for <code>{collection}</code>",
                    requires=CollectionRelation.Types.SUITE_REQUIRES.label,
                    collection=collection,
                ),
            ),
            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) -> ResourceSubPlace[Collection]:
        """Return a place for showing an archive."""
        suite = self.instance
        return ResourceSubPlace(
            ui=self,
            title=PlaceValue(
                str(suite),
                page=format_html(
                    "Suite <code>{collection}</code>", collection=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) -> ResourceMainPlace[CollectionItem]:
        """Return a place to show this collection item."""
        return ResourceMainPlace(
            ui=self,
            title=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
