"""DMS audit bounded context — API views.

All endpoints are read-only (audit data is written by services, not by API
callers).  The API surfaces the audit trail for UI dashboards and SIEM export.

Endpoints
---------
Document audit log:
  GET /dms/documents/{doc_id}/audit/
      List all audit log entries for a document.
  GET /dms/documents/{doc_id}/audit/{log_id}/
      Retrieve a single audit log entry.

Access logs:
  GET /dms/documents/{doc_id}/access-logs/
      List access log entries for a document.

Security events (document-scoped):
  GET /dms/documents/{doc_id}/security-events/
      List security events for a document.

Security events (tenant-wide):
  GET /dms/security-events/
      List all security events for the current tenant.
  GET /dms/security-events/{event_id}/
      Retrieve a single security event.
"""

from __future__ import annotations

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.audit import queries
from simorgh.apps.dms.audit.iam_permissions import (
    PERM_ACCESS_LOG_VIEW,
    PERM_AUDIT_VIEW,
    PERM_SECURITY_EVENTS_VIEW,
)
from simorgh.apps.dms.audit.serializers import (
    AccessLogSerializer,
    DocumentAuditLogSerializer,
    SecurityEventSerializer,
)
from simorgh.apps.dms.common.exceptions import AssetNotFound


# ---------------------------------------------------------------------------
# Helpers (same pattern as other DMS bounded contexts)
# ---------------------------------------------------------------------------

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}")


def _get_document(request: Request, doc_id: str):
    """Return the Document ensuring it belongs to the request tenant."""
    from simorgh.apps.dms.documents.queries import get_document

    tenant = _tenant(request)
    return get_document(tenant.pk, doc_id)


# ---------------------------------------------------------------------------
# Document audit log views
# ---------------------------------------------------------------------------

@api_view(["GET"])
@permission_classes([IsAuthenticated])
def audit_log_list(request: Request, doc_id: str) -> Response:
    """GET — list all audit log entries for a document."""
    _require_perm(request, PERM_AUDIT_VIEW)
    try:
        document = _get_document(request, doc_id)
    except AssetNotFound as exc:
        return Response({"detail": str(exc)}, status=status.HTTP_404_NOT_FOUND)

    action = request.query_params.get("action")
    tenant = _tenant(request)
    qs = queries.list_document_audit_logs(
        tenant_id=tenant.pk,
        document_id=document.pk,
        action=action or None,
    )
    return Response(DocumentAuditLogSerializer(qs, many=True).data)


@api_view(["GET"])
@permission_classes([IsAuthenticated])
def audit_log_detail(request: Request, doc_id: str, log_id: str) -> Response:
    """GET — retrieve a single audit log entry."""
    _require_perm(request, PERM_AUDIT_VIEW)
    tenant = _tenant(request)
    try:
        entry = queries.get_audit_log(tenant_id=tenant.pk, log_id=log_id)
    except AssetNotFound as exc:
        return Response({"detail": str(exc)}, status=status.HTTP_404_NOT_FOUND)
    return Response(DocumentAuditLogSerializer(entry).data)


# ---------------------------------------------------------------------------
# Access log views
# ---------------------------------------------------------------------------

@api_view(["GET"])
@permission_classes([IsAuthenticated])
def access_log_list(request: Request, doc_id: str) -> Response:
    """GET — list access log entries for a document."""
    _require_perm(request, PERM_ACCESS_LOG_VIEW)
    try:
        document = _get_document(request, doc_id)
    except AssetNotFound as exc:
        return Response({"detail": str(exc)}, status=status.HTTP_404_NOT_FOUND)

    access_type = request.query_params.get("access_type")
    tenant = _tenant(request)
    qs = queries.list_access_logs(
        tenant_id=tenant.pk,
        document_id=document.pk,
        access_type=access_type or None,
    )
    return Response(AccessLogSerializer(qs, many=True).data)


# ---------------------------------------------------------------------------
# Security event views (document-scoped)
# ---------------------------------------------------------------------------

@api_view(["GET"])
@permission_classes([IsAuthenticated])
def document_security_event_list(request: Request, doc_id: str) -> Response:
    """GET — list security events for a specific document."""
    _require_perm(request, PERM_SECURITY_EVENTS_VIEW)
    try:
        document = _get_document(request, doc_id)
    except AssetNotFound as exc:
        return Response({"detail": str(exc)}, status=status.HTTP_404_NOT_FOUND)

    tenant = _tenant(request)
    event_type = request.query_params.get("event_type")
    severity = request.query_params.get("severity")
    qs = queries.list_security_events(
        tenant_id=tenant.pk,
        document_id=document.pk,
        event_type=event_type or None,
        severity=severity or None,
    )
    return Response(SecurityEventSerializer(qs, many=True).data)


# ---------------------------------------------------------------------------
# Security event views (tenant-wide)
# ---------------------------------------------------------------------------

@api_view(["GET"])
@permission_classes([IsAuthenticated])
def security_event_list(request: Request) -> Response:
    """GET — list all security events across the tenant."""
    _require_perm(request, PERM_SECURITY_EVENTS_VIEW)
    tenant = _tenant(request)
    event_type = request.query_params.get("event_type")
    severity = request.query_params.get("severity")
    qs = queries.list_security_events(
        tenant_id=tenant.pk,
        event_type=event_type or None,
        severity=severity or None,
    )
    return Response(SecurityEventSerializer(qs, many=True).data)


@api_view(["GET"])
@permission_classes([IsAuthenticated])
def security_event_detail(request: Request, event_id: str) -> Response:
    """GET — retrieve a single security event."""
    _require_perm(request, PERM_SECURITY_EVENTS_VIEW)
    tenant = _tenant(request)
    try:
        event = queries.get_security_event(tenant_id=tenant.pk, event_id=event_id)
    except AssetNotFound as exc:
        return Response({"detail": str(exc)}, status=status.HTTP_404_NOT_FOUND)
    return Response(SecurityEventSerializer(event).data)
