"""PRD §4.3.4 — Scholarship API surface.

Programme scoping mirrors the RIMS API: a scholar sees their own profile,
admins see everything, grants/program staff see scholars whose scholarship
ties back to a funding record they manage. Finance staff see the full set
because stipend reporting cuts across programmes.
"""
from __future__ import annotations

from rest_framework import permissions, viewsets

from apps.core.permissions.roles import UserRole
from apps.rims.scholarships.models import Scholar, Scholarship
from apps.rims.scholarships.serializers import ScholarSerializer, ScholarshipSerializer


_SCHOLARSHIP_STAFF_ROLES = frozenset(
    {
        UserRole.ADMIN.value,
        UserRole.SYSTEM_ADMIN.value,
        UserRole.GRANTS_MANAGER.value,
        UserRole.PROGRAM_MANAGER.value,
        UserRole.PROGRAM_DIRECTOR.value,
        UserRole.PROGRAMME_OFFICER.value,
        UserRole.FINANCE_OFFICER.value,
        UserRole.FINANCE_DIRECTOR.value,
    }
)


class ScholarshipViewSet(viewsets.ReadOnlyModelViewSet):
    """All active scholarship programmes — visible to staff and to scholars."""

    serializer_class = ScholarshipSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return Scholarship.objects.filter(is_active=True).order_by("name")


class ScholarViewSet(viewsets.ReadOnlyModelViewSet):
    """Programme-scoped scholar list."""

    serializer_class = ScholarSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        user = self.request.user
        qs = Scholar.objects.select_related("user", "scholarship").prefetch_related(
            "stipends", "progress_reports"
        )
        if not user or not user.is_authenticated:
            return qs.none()
        if user.is_superuser:
            return qs
        role = getattr(user, "role", "") or ""
        if role in _SCHOLARSHIP_STAFF_ROLES:
            return qs
        # Default: scholars see their own profile only.
        return qs.filter(user=user)
