"""Repository ↔ RIMS grant linkage (PRD REPO-SP2 FRREP-MCL009).

The submit wizard links a document to a RIMS funding record by storing the
grant's ``public_grant_id`` on ``Document.grant_reference``. These helpers back
the searchable picker and validate that a typed/picked id resolves to a real,
linkable grant — only *active or completed* records (APPROVED / CLOSED) are
offered, never drafts or pending-approval ones.
"""

from __future__ import annotations

from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import JsonResponse
from django.views.generic import View

from apps.rims.grants.models import FundingRecord

# Statuses a document may link to — a grant must be approved (active) or closed
# (completed). Drafts / pending-approval records aren't real funding yet.
LINKABLE_GRANT_STATUSES = (
    FundingRecord.Status.APPROVED,
    FundingRecord.Status.CLOSED,
)


def linkable_grants_qs():
    """Funding records eligible to be linked from a document."""
    return FundingRecord.objects.filter(
        status__in=LINKABLE_GRANT_STATUSES
    ).exclude(public_grant_id="")


def lookup_grant(public_grant_id: str) -> FundingRecord | None:
    """Resolve a stored ``grant_reference`` to a linkable funding record."""
    public_grant_id = (public_grant_id or "").strip()
    if not public_grant_id:
        return None
    return linkable_grants_qs().filter(public_grant_id=public_grant_id).first()


def is_linkable_grant(public_grant_id: str) -> bool:
    return lookup_grant(public_grant_id) is not None


class GrantSearchView(LoginRequiredMixin, View):
    """JSON typeahead over linkable RIMS grants (FRREP-MCL009).

    GET ``?q=`` matches the query against ``public_grant_id`` and ``title``.
    Returns ``{"results": [{"id": <public_grant_id>, "text": "<id> — <title>",
    "title": ...}]}``. Login-gated; only exposes the id + title of approved /
    closed grants (low-sensitivity, and the linkage is shown on the document
    page anyway).
    """

    http_method_names = ["get"]

    def get(self, request, *args, **kwargs):
        q = (request.GET.get("q") or "").strip()
        qs = linkable_grants_qs()
        if q:
            from django.db.models import Q

            qs = qs.filter(Q(public_grant_id__icontains=q) | Q(title__icontains=q))
        qs = qs.order_by("-created_at")[:20]
        results = [
            {
                "id": fr.public_grant_id,
                "text": f"{fr.public_grant_id} — {fr.title}",
                "title": fr.title,
                "status": fr.status,
            }
            for fr in qs
        ]
        return JsonResponse({"results": results})
