"""租户 bootstrap — 展开 tenant_init bundle。"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

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

from niannian.tenant.context import resolve_request_context
from niannian.tenant.registry import TenantUserRegistry
from niannian.tenant.sessions import TenantSessionStore
from niannian.tenant.tenant_init import TenantInitStore

if TYPE_CHECKING:
    from niannian.client import NianNian


class BootstrapBody(BaseModel):
    init_id: str | None = None


def create_tenant_bootstrap_router(nn: NianNian) -> APIRouter:
    router = APIRouter(prefix="/v1/tenant", tags=["tenant"])
    sessions = TenantSessionStore(nn._home)
    registry = TenantUserRegistry(nn._home)
    store = TenantInitStore(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 bootstrap"},
            )
        return ctx.user_id

    @router.post("/bootstrap")
    def bootstrap(body: BootstrapBody, request: Request) -> dict[str, Any]:
        username = _require_tenant_session(request)
        registry.reload()
        bootstrap_state = registry.get_bootstrap(username)

        init_id = body.init_id
        if init_id is None and bootstrap_state.get("force_reinit_pending"):
            init_id = bootstrap_state.get("force_reinit_init_id")

        try:
            result = store.bootstrap_user(
                username=username,
                target_home=nn._home,
                init_id=init_id,
            )
        except ValueError as exc:
            if str(exc) == "no_active_init":
                raise HTTPException(
                    status_code=503,
                    detail={"code": "no_active_init", "message": "no active tenant init configured"},
                ) from exc
            raise
        except KeyError:
            raise HTTPException(
                status_code=404,
                detail={"code": "init_not_found", "message": "tenant init archive not found"},
            ) from None

        registry.record_bootstrap(username, str(result["init_id"]))
        return result

    return router
