"""租户 D22 inbox — GET pending-fetches · POST fetch-response。"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel, Field

from niannian.http.deps import _resolve_bearer_token
from niannian.tenant.context import resolve_request_context
from niannian.tenant.pending_fetch import PendingFetchStore, fetch_push_token_ttl_sec
from niannian.tenant.sessions import TenantSessionStore

if TYPE_CHECKING:
    from niannian.client import NianNian


class FetchResponseBody(BaseModel):
    fetch_id: str = Field(..., min_length=1)
    push_token: str = Field(..., min_length=1)
    payload: Any = None


def create_tenant_fetch_router(nn: NianNian) -> APIRouter:
    router = APIRouter(prefix="/v1/tenant", tags=["tenant"])
    sessions = TenantSessionStore(nn._home)
    pending = PendingFetchStore(nn._home)

    def _require_tenant_session(request: Request) -> str:
        ctx = resolve_request_context(
            request,
            nn._config,
            home=nn._home,
            sessions=sessions,
        )
        if not ctx.session_token:
            raise HTTPException(
                status_code=403,
                detail={"code": "tenant_session_required", "message": "valid tenant X-NianNian-Session required"},
            )
        if ctx.role != "tenant":
            raise HTTPException(
                status_code=403,
                detail={"code": "tenant_only", "message": "tenant session required for fetch inbox"},
            )
        return ctx.user_id

    @router.get("/pending-fetches")
    def pending_fetches(request: Request) -> dict[str, Any]:
        username = _require_tenant_session(request)
        items = pending.list_for_user(username)
        return {"items": items}

    @router.post("/fetch-response")
    def fetch_response(body: FetchResponseBody, request: Request) -> dict[str, Any]:
        username = _require_tenant_session(request)
        bearer = _resolve_bearer_token(nn._config)
        if not bearer:
            raise HTTPException(
                status_code=503,
                detail={"code": "auth_misconfigured", "message": "NIANNIAN_API_TOKEN required for fetch-response"},
            )
        row = pending.get(body.fetch_id)
        if row is None:
            raise HTTPException(
                status_code=404,
                detail={"code": "fetch_not_found", "message": "pending fetch not found"},
            )
        if str(row.get("username", "")).lower() != username.lower():
            raise HTTPException(
                status_code=403,
                detail={"code": "fetch_user_mismatch", "message": "fetch belongs to another user"},
            )
        try:
            result = pending.complete_fetch(
                fetch_id=body.fetch_id,
                push_token=body.push_token,
                bearer_secret=bearer,
                payload=body.payload,
            )
        except KeyError:
            raise HTTPException(
                status_code=404,
                detail={"code": "fetch_not_found", "message": "pending fetch not found"},
            ) from None
        except ValueError as exc:
            code = str(exc)
            if code == "fetch_expired":
                from niannian.tenant.registry import TenantUserRegistry

                TenantUserRegistry(nn._home).record_fetch_status(username, status="timeout")
                raise HTTPException(
                    status_code=410,
                    detail={"code": "fetch_expired", "message": "push_token window expired"},
                ) from exc
            if code == "fetch_already_closed":
                raise HTTPException(
                    status_code=409,
                    detail={"code": "fetch_already_closed", "message": "fetch already completed"},
                ) from exc
            raise HTTPException(
                status_code=403,
                detail={"code": "push_token_invalid", "message": "invalid push_token"},
            ) from exc

        from niannian.tenant.registry import TenantUserRegistry

        TenantUserRegistry(nn._home).record_fetch_status(username, status="ok")
        ttl = fetch_push_token_ttl_sec(nn._config)
        return {**result, "ttl_sec": ttl}

    return router
