"""Read-only HTTP views over `statement.view`.

Plain Django views (no DRF): the runtime is pinned to exactly the four
packages in requirements.txt, and DRF is not one of them. Every view here is
GET-only and touches no write path.
"""

from __future__ import annotations

from django.http import JsonResponse
from django.views.decorators.http import require_GET

from adjustments.models import Account, Invoice
# Through the package, not the module. `statement/__init__.py` carries an
# ops-contract saying the customer-facing view enters via
# `statement.build_statement` and that where the implementation lives is the
# candidate's choice. Importing `statement.view` directly contradicts that:
# a candidate who relocates the implementation -- exactly what the shim
# invites -- would leave this API serving the old tree, or failing to import.
from statement import VIEWPORTS, build_statement

from .serializers import serialize_node


@require_GET
def statement(request, account_id: str, period_key: str):
    viewport = request.GET.get("viewport", "phone")
    if viewport not in VIEWPORTS:
        return JsonResponse(
            {"error": f"unknown viewport {viewport!r}; expected one of {VIEWPORTS}"},
            status=400,
        )

    try:
        account = Account.objects.get(account_id=account_id)
    except Account.DoesNotExist:
        return JsonResponse({"error": "account not found"}, status=404)

    try:
        node = build_statement(account, period_key, viewport)
    except Invoice.DoesNotExist:
        return JsonResponse({"error": "period not found"}, status=404)

    return JsonResponse(serialize_node(node))


@require_GET
def periods(request, account_id: str):
    try:
        account = Account.objects.get(account_id=account_id)
    except Account.DoesNotExist:
        return JsonResponse({"error": "account not found"}, status=404)

    # A period "has a statement" exactly when build_statement's own lookup
    # (`account.invoices.get(period_key=..., revision_of__isnull=True)`)
    # would succeed for it -- so the filter here has to match that one.
    period_keys = (
        account.invoices.filter(revision_of__isnull=True)
        .order_by("-period_key")
        .values_list("period_key", flat=True)
        .distinct()
    )
    return JsonResponse(list(period_keys), safe=False)
