"""Platform-level schema endpoints.

These wrap :class:`EntitySchema` objects in a response format that the
frontend ``SchemaClient`` expects:
  ``GET /api/v1/platform/schemas/``           → list of entity schemas
  ``GET /api/v1/platform/schemas/<name>/``    → single entity schema

The wire format includes a ``module`` / ``entity_type`` split (derived
from the dotted name) and a ``ui_hints`` block that frontend renderers
use for layout decisions.
"""

from __future__ import annotations

from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from simorgh.apps.iam.engine import is_allowed
from simorgh.apps.schema.registry import (
    EntitySchema,
    SchemaError,
    get_entity,
    list_entities,
)
from simorgh.core.context import current_request_context


def _visible(entity: EntitySchema) -> bool:
    if not entity.view_permission:
        return True
    return is_allowed(current_request_context(), entity.view_permission)


def _ui_hints(entity: EntitySchema) -> dict:
    """Build a ui_hints block from an EntitySchema's views / field metadata."""
    return {
        "views": [
            {"kind": v.kind, "fields": list(v.fields), "permission": v.permission}
            for v in entity.views
        ],
        "filterable_fields": list(entity.filterable_fields),
        "sortable_fields": list(entity.sortable_fields),
    }


def _serialize(entity: EntitySchema) -> dict:
    module, _, entity_type = entity.name.partition(".")
    return {
        "id": entity.name,
        "module": module,
        "entity_type": entity_type or module,
        "version": 1,
        "fields": [
            {
                "name": f.name,
                "type": f.type,
                "label_key": f.label_key,
                "help_key": f.help_key,
                "semantic_type": f.semantic_type,
                "ai_hint": f.ai_hint,
                "required": f.required,
                "read_only": f.read_only,
                "default": f.default,
                "enum": list(f.enum),
                "fk_entity": f.fk_entity,
                "max_length": f.max_length,
                "min_value": f.min_value,
                "max_value": f.max_value,
                "permission": f.permission,
            }
            for f in entity.fields
        ],
        "ui_hints": _ui_hints(entity),
    }


class PlatformSchemaListView(APIView):
    """``GET /api/v1/platform/schemas/`` — all entities the caller may see."""

    permission_classes = (IsAuthenticated,)

    def get(self, request):
        payload = [_serialize(e) for e in list_entities() if _visible(e)]
        return Response({"results": payload})


class PlatformSchemaDetailView(APIView):
    """``GET /api/v1/platform/schemas/<name>/`` — one entity, permission-gated."""

    permission_classes = (IsAuthenticated,)

    def get(self, request, name: str):
        try:
            entity = get_entity(name)
        except SchemaError:
            return Response({"detail": "Unknown entity"}, status=404)
        if not _visible(entity):
            return Response({"detail": "Forbidden"}, status=403)
        return Response(_serialize(entity))
