"""DMS workflow — API views.

Endpoint
--------
  POST /api/v1/dms/documents/{document_id}/transition/

Body
----
  {
    "action": "<action_name>",
    "comment": "<optional text>"
  }

Permissions
-----------
  Checked per-action: manage / approve / publish.
"""

from __future__ import annotations

import uuid

from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response

from simorgh.apps.dms.workflow.transitions import TRANSITIONS, WorkflowError


def _tenant(request: Request):
    tenant = getattr(request, "tenant", None)
    if tenant is None:
        from rest_framework.exceptions import PermissionDenied
        raise PermissionDenied("Tenant required.")
    return tenant


def _require_perm(request: Request, codename: str) -> None:
    from rest_framework.exceptions import PermissionDenied
    from simorgh.core.context import current_request_context

    ctx = current_request_context()
    if ctx.is_superuser:
        return
    if codename not in (ctx.permissions or set()):
        raise PermissionDenied(f"Permission required: {codename}")


@api_view(["POST"])
@permission_classes([IsAuthenticated])
def transition_document_view(request: Request, document_id: str) -> Response:
    """Trigger a workflow transition on a document."""
    from simorgh.apps.dms.documents.models import Document
    from simorgh.apps.dms.workflow.services import trigger_workflow_transition

    tenant = _tenant(request)

    # Resolve document
    try:
        doc_uuid = uuid.UUID(str(document_id))
    except (ValueError, AttributeError):
        return Response({"detail": "Invalid document ID."}, status=status.HTTP_400_BAD_REQUEST)

    try:
        doc = Document.objects.get(public_id=doc_uuid, tenant=tenant, is_deleted=False)
    except Document.DoesNotExist:
        return Response({"detail": "Document not found."}, status=status.HTTP_404_NOT_FOUND)

    # Validate request body
    action = request.data.get("action", "")
    if not action:
        return Response({"detail": "Field 'action' is required."}, status=status.HTTP_400_BAD_REQUEST)

    if action not in TRANSITIONS:
        return Response(
            {"detail": f"Unknown action: {action!r}. Valid actions: {sorted(TRANSITIONS)}."},
            status=status.HTTP_400_BAD_REQUEST,
        )

    comment = request.data.get("comment", "")

    # Permission check — resolved from the transition spec
    spec = TRANSITIONS[action]
    _require_perm(request, spec.required_permission)

    # Execute transition
    try:
        doc = trigger_workflow_transition(
            doc=doc,
            action=action,
            actor_id=request.user.pk,
            comment=comment,
        )
    except WorkflowError as exc:
        return Response({"detail": str(exc)}, status=status.HTTP_400_BAD_REQUEST)

    return Response(
        {
            "document_id": str(doc.public_id),
            "action": action,
            "workflow_status": doc.workflow_status,
            "document_status": doc.status,
        },
        status=status.HTTP_200_OK,
    )
