"""DRF serializers for the ``/mcp_server/api/teams/`` control plane.

These endpoints are the Daedalus → Mnemosyne control plane described
in §7 of ``docs/DAEDALUS_PALLAS_INTEGRATION_v1.md``. They are called
by Daedalus authenticated as the Mnemosyne user the team belongs to
(per-user ``UserToken``, ``Authorization: Bearer …``).
"""

from __future__ import annotations

from rest_framework import serializers

from ..models import Team


class TeamCreateRequestSerializer(serializers.Serializer):
    """Inbound payload for ``POST /mcp_server/api/teams/``.

    ``id`` is the Daedalus ``PallasInstance.id`` UUID. It is supplied
    by the caller (not generated by Mnemosyne) so the two control
    planes share a stable key.
    """

    id = serializers.UUIDField()
    name = serializers.CharField(max_length=200)


class TeamPublicSerializer(serializers.ModelSerializer):
    """Outbound payload for team reads / updates.

    Excludes the JWT — it is surfaced exactly once on create / rotate
    and never recoverable after. Include ``workspace_ids`` so Daedalus
    can diff its local state against what Mnemosyne actually holds.
    """

    workspace_ids = serializers.SerializerMethodField()

    class Meta:
        model = Team
        fields = [
            "id",
            "name",
            "active",
            "active_jti",
            "created_at",
            "updated_at",
            "workspace_ids",
        ]
        read_only_fields = fields

    def get_workspace_ids(self, obj: Team) -> list[str]:
        return list(
            obj.workspace_assignments.order_by("workspace_id")
            .values_list("workspace_id", flat=True)
        )


class TeamWorkspacesUpdateSerializer(serializers.Serializer):
    """Inbound payload for ``PUT /mcp_server/api/teams/{id}/workspaces/``.

    The request is an idempotent *replace* — the team's assignment set
    after the call equals ``workspace_ids`` exactly. Daedalus is the
    source of truth; Mnemosyne mirrors.
    """

    workspace_ids = serializers.ListField(
        child=serializers.CharField(max_length=64, allow_blank=False),
        allow_empty=True,
    )

    def validate_workspace_ids(self, value: list[str]) -> list[str]:
        # De-duplicate while preserving order; strip whitespace. ``unique_together``
        # would already reject dupes at the DB layer but failing earlier gives
        # the caller a cleaner 400.
        seen = set()
        out = []
        for ws in value:
            ws = ws.strip()
            if not ws:
                raise serializers.ValidationError(
                    "workspace_ids entries must be non-empty strings."
                )
            if ws not in seen:
                seen.add(ws)
                out.append(ws)
        return out
