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

from functools import cached_property

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

from debusine.db.context import context
from debusine.db.models import Workspace
from debusine.web.icons import Icons
from debusine.web.views.places import (
    PlaceValue,
    ResourceMainPlace,
    ResourcePlace,
    ResourceSubPlace,
)
from debusine.web.views.ui.base import UI


class WorkspaceUI(UI[Workspace]):
    """UI helpers for Workspace instances."""

    @cached_property
    def workspace_description(self) -> str:
        """Return a description for the workspace."""
        public = " public" if self.instance.public else ""
        return f"{self.instance.name}{public} workspace"

    @cached_property
    def place(self) -> ResourcePlace[Workspace]:
        """Return a place to show this workspace."""
        place = ResourceMainPlace(
            ui=self,
            title=PlaceValue(
                self.instance.name, page=f"{self.instance.name} workspace"
            ),
            description=self.workspace_description,
            url=self.instance.get_absolute_url(),
            icon=Icons.WORKSPACE,
        )
        place.parent = self.instance.scope.ui(self.request).place
        return place

    @cached_property
    def place_update(self) -> ResourcePlace[Workspace]:
        """Return a place to update this workspace."""
        return ResourceSubPlace(
            ui=self,
            title=PlaceValue(
                "Settings",
                page=f"{self.instance.name} settings",
            ),
            url=self.instance.get_absolute_url_configure(),
            description=self.workspace_description + " configuration",
            parent=self.place,
        )

    @cached_property
    def place_config_inspector(self) -> ResourcePlace[Workspace]:
        """Return a place to inspect this workspace task configuration."""
        from debusine.server.scopes import urlconf_scope

        with urlconf_scope(self.instance.scope.name):
            url = reverse(
                "workspaces:task_configuration_inspector",
                kwargs={"wname": self.instance.name},
            )

        return ResourceSubPlace(
            ui=self,
            title=PlaceValue(
                "Task configuration inspector",
                breadcrumb="Configuration inspector",
            ),
            url=url,
            description=self.workspace_description
            + " task configuration inspector",
            parent=self.place,
        )

    @cached_property
    def place_update_inheritance(self) -> ResourcePlace[Workspace]:
        """Return a place to update this workspace's inheritance."""
        from debusine.server.scopes import urlconf_scope

        with urlconf_scope(self.instance.scope.name):
            url = reverse(
                "workspaces:update_inheritance",
                kwargs={"wname": self.instance.name},
            )

        return ResourceSubPlace(
            ui=self,
            title=PlaceValue(
                "Inheritance",
                page=f"{self.instance.name} inheritance",
            ),
            url=url,
            description=self.workspace_description
            + " inheritance configuration",
            parent=self.place,
        )

    @cached_property
    def place_workflow_list(self) -> ResourcePlace[Workspace]:
        """Return a place to list this workspace's workflows."""
        from debusine.server.scopes import urlconf_scope

        with urlconf_scope(self.instance.scope.name):
            url = reverse(
                "workspaces:workflows:list",
                kwargs={"wname": self.instance.name},
            )

        return ResourceSubPlace(
            ui=self,
            title="Workflows",
            url=url,
            description=self.workspace_description + " workflows",
            parent=self.place,
        )

    @cached_property
    def place_collection_create(self) -> ResourcePlace[Workspace]:
        """Return a place to create a collection in this workspace."""
        from debusine.server.scopes import urlconf_scope

        with urlconf_scope(self.instance.scope.name):
            url = reverse(
                "workspaces:collections:create",
                kwargs={"wname": self.instance.name},
            )

        place = ResourceSubPlace(
            ui=self,
            title="Create collection",
            url=url,
            description="Create a new collection in "
            + self.workspace_description,
            parent=self.place,
        )
        return place

    @cached_property
    def place_collection_list(self) -> ResourcePlace[Workspace]:
        """Return a place to list this workspace's collections."""
        from debusine.server.scopes import urlconf_scope

        with urlconf_scope(self.instance.scope.name):
            url = reverse(
                "workspaces:collections:list",
                kwargs={"wname": self.instance.name},
            )

        place = ResourceSubPlace(
            ui=self,
            title="Collections",
            url=url,
            icon=Icons.COLLECTIONS,
            description=self.workspace_description + " collections",
            parent=self.place,
        )
        return place

    @cached_property
    def place_suite_list(self) -> ResourcePlace[Workspace]:
        """Return a list of archives for this workspace."""
        return ResourceSubPlace(
            ui=self,
            title=PlaceValue(
                "Suites",
                page=format_html(
                    "Suites in <code>{workspace}</code>",
                    workspace=self.instance,
                ),
            ),
            url=reverse(
                "archive-root",
                kwargs={
                    "scope": self.instance.scope.name,
                    "workspace": self.instance.name,
                },
            ),
            description=self.workspace_description + " suite list",
            parent=self.place,
        )

    @cached_property
    def candidate_parents(self) -> list[Workspace]:
        """Return a list of workspaces that can be parents to this one."""
        base_qs = Workspace.objects.select_related("scope")
        allowed = base_qs.can_display(context.pc).exclude(pk=self.instance.pk)
        allowed = allowed.union(
            base_qs.filter(pk__in=self.instance.chain_parents.values("parent"))
        )
        return list(allowed.order_by("scope", "name"))
