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

"""debusine views."""

import datetime as dt
from typing import Any, override

from django.contrib import messages
from django.http import (
    HttpRequest,
    HttpResponse,
    HttpResponseBase,
    HttpResponseRedirect,
)
from django.urls import reverse
from django.utils.safestring import SafeString
from django.views.generic import TemplateView, View

from debusine.db.context import context
from debusine.db.models import WorkRequest, Workspace
from debusine.web.views.base import BaseUIView
from debusine.web.views.table import NumberColumn, StringColumn, Table
from debusine.web.views.tables import WorkflowTable


class ScopeWorkspaceTable(Table[Workspace]):
    """Table showing scopes and workspaces."""

    scope = StringColumn("Scope")
    workspace = StringColumn("Workspace")
    role = StringColumn("Role")
    running = NumberColumn(
        SafeString(
            '<span title="Running workflows"'
            ' class="badge text-bg-info">R</span>'
        )
    )
    input_needed = NumberColumn(
        SafeString(
            '<span title="Input needed workflows"'
            ' class="badge text-bg-info">I</span>'
        )
    )
    completed = NumberColumn(
        SafeString(
            '<span title="Completed and aborted workflows"'
            ' class="badge text-bg-primary">C</span>'
        )
    )

    template_name = "web/_scope_workspace-list.html"


class HomepageView(BaseUIView, TemplateView):
    """Class for the homepage view."""

    base_template = "web/_base_debusine.html"
    template_name = "web/homepage.html"
    title = "Main page"

    @override
    def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
        """Return context_data with work_request_list and workspace_list."""
        ctx = super().get_context_data(**kwargs)

        if self.request.user.is_authenticated:
            workflows = (
                WorkRequest.objects.select_related(
                    "workspace__scope", "workflow_root"
                )
                .can_display(context.pc)
                .filter(created_by=self.request.user)
                .workflows()
                .filter(parent__isnull=True)
            )
            ctx["workflows_current"] = WorkflowTable(
                self.request,
                workflows.running(),
                prefix="current",
                preview=True,
            ).get_paginator(per_page=5)

            ctx["workflows_completed"] = WorkflowTable(
                self.request,
                workflows.filter(
                    status__in=(
                        WorkRequest.Statuses.COMPLETED,
                        WorkRequest.Statuses.ABORTED,
                    )
                ),
                prefix="completed",
                preview=True,
            ).get_paginator(per_page=5)

        ctx["workspaces"] = ScopeWorkspaceTable(
            self.request,
            Workspace.objects.can_display(context.pc)
            .select_related("scope")
            .order_by("scope", "name")
            .annotate_with_workflow_stats()
            .with_role_annotations(context.pc),
            prefix="workspaces",
        ).get_paginator(per_page=10)

        return ctx


class ToastView(BaseUIView, TemplateView):
    """Plumbing view to test toasts."""

    base_template = "web/_base_debusine.html"
    template_name = "web/toasts.html"
    title = "Test showing django messages"

    @override
    def dispatch(
        self, request: HttpRequest, *args: Any, **kwargs: Any
    ) -> HttpResponseBase:
        """Dispatch the request, setting appropriate response headers."""
        response = super().dispatch(request, *args, **kwargs)

        match request.GET.get("type"):
            case "debug":
                messages.debug(request, "This is a debugging message.")
            case "info":
                messages.info(request, "This is an informational message.")
            case "success":
                messages.success(request, "This message represents success.")
            case "warning":
                messages.warning(request, "This is supposed to be a warning.")
            case "error":
                messages.error(request, "An error has not occurred.")
            case None:
                pass
            case _:
                messages.error(request, "Unknown toast type.")

        return response


class ThemeSelectionView(View):
    """Select and save the current theme."""

    def post(
        self, request: HttpRequest, *args: Any, **kwargs: Any
    ) -> HttpResponse:
        """Set the selected theme."""
        value = request.POST.get("theme", "auto")
        next_url = request.POST.get("next", None)
        if next_url is None:
            next_url = reverse("homepage:homepage")
        response = HttpResponseRedirect(next_url)
        if value == "auto":
            response.delete_cookie("theme")
        else:
            response.set_cookie(
                "theme", value, httponly=False, max_age=dt.timedelta(days=3650)
            )
        return response
