"""Typed registry of the stable generated-app browser client surface
(``src/domain/codegen/runtime/p2hs-app-client.js``, re-exported wholesale by
``useP2hs.ts``).

The JS module itself stays one flat set of exports -- renaming or regrouping it
into literal ``p2hs.auth.*``/``p2hs.forms.*``/``p2hs.records.*`` namespaces would be
a breaking change across every already-generated app that imports from it, so this
is not that rewrite. This registry is the typed, Python-side contract over that
existing stable surface instead: it groups the real exports into the namespaces the
architecture conceptually organizes them into (auth, forms, records, files,
bookings, contact, admin, jobs, config), and gives
``tests/test_codegen_runtime_client_contract.py`` something concrete to check the
real JS file's exports against -- so an accidental rename or removal of a function
every previously-generated app calls gets caught here, not in production.

Every one of these functions already targets same-origin ``/api/*`` only, never a
Cloud/provider URL directly. That is what lets the same client work unmodified
whether the project is on W4P + shared BFF or legacy Pages Functions -- see
``src.domain.hosting.runtime_projection``. Framework wrappers (``useP2hs.ts`` today;
any future framework adapter) must depend on this one client rather than defining
their own fetch/transport logic -- also enforced by the same test module.
"""
from __future__ import annotations

RUNTIME_CLIENT_SOURCE = "src/domain/codegen/runtime/p2hs-app-client.js"
RUNTIME_CLIENT_FRAMEWORK_WRAPPER = "src/domain/codegen/runtime/useP2hs.ts"

RUNTIME_CLIENT_NAMESPACES: dict[str, tuple[str, ...]] = {
    "auth": (
        "getAccessToken",
        "setAccessToken",
        "authHeaders",
        "signIn",
        "signUp",
        "signOut",
        "me",
        "updateProfile",
        "refreshSession",
        "getSession",
        "requestMagicLink",
        "signInWithGoogle",
        "verifyMagicLink",
        "requestOtp",
        "verifyOtp",
        "verifyEmail",
        "acceptInvite",
        "requestPasswordReset",
        "confirmPasswordReset",
        "totpStatus",
        "totpSetup",
        "totpEnable",
        "totpDisable",
        "verifyTotpLogin",
        "passkeyRegistrationOptions",
        "passkeyRegistrationVerify",
        "passkeyAuthenticationOptions",
        "passkeyAuthenticationVerify",
        "listPasskeys",
        "deletePasskey",
    ),
    "forms": ("submitGeneratedForm", "uploadFormFile"),
    "records": ("listRecords", "getRecord", "createRecord", "patchRecord"),
    "files": (
        "fileToBase64",
        "uploadApplicationFile",
        "getApplicationFile",
        "downloadApplicationFile",
        "deleteApplicationFile",
        "attachFile",
        "listAttachments",
        "removeAttachment",
        "listStorageFiles",
        "presignStorageUpload",
    ),
    "bookings": (
        "listBookingResources",
        "upsertBookingResource",
        "getBookingAvailability",
        "reserveBooking",
        "getBooking",
        "cancelBooking",
    ),
    "contact": ("submitContact", "listInbox", "inboxRows", "listActivity"),
    "admin": ("listAppUsers", "updateAppUser"),
    "jobs": ("sendEmail", "executeIntegration"),
    "config": ("publicConfig",),
    "imports": (
        "createImportSession",
        "previewImportSession",
        "mapImportFields",
        "validateImportSession",
        "commitImportSession",
    ),
    "permissions": ("checkPermission",),
}


def all_contract_exports() -> frozenset[str]:
    return frozenset(name for names in RUNTIME_CLIENT_NAMESPACES.values() for name in names)


def namespace_for(export_name: str) -> str | None:
    for namespace, names in RUNTIME_CLIENT_NAMESPACES.items():
        if export_name in names:
            return namespace
    return None
