from __future__ import annotations

from typing import TYPE_CHECKING, Annotated, Any, Literal

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

from niannian.http.core_auth import require_admin_owner

if TYPE_CHECKING:
    from niannian.client import NianNian


class BackupBody(BaseModel):
    scope: Literal["atoms_wiki", "atoms_wiki_vault", "full_except_subject"] = "full_except_subject"


class WipeBody(BaseModel):
    scope: Literal["atoms_wiki", "atoms_wiki_vault", "full_except_subject"]
    confirm: str = Field(min_length=1)
    backup_id: str | None = None


class MarginalizeBody(BaseModel):
    percent: float = Field(ge=5.0, le=30.0, default=10.0)


def create_memory_admin_router(nn: NianNian) -> APIRouter:
    router = APIRouter(prefix="/v1/admin/memory", tags=["admin"])

    def _user_id(request: Request) -> str:
        from niannian.tenant.context import resolve_request_context

        ctx = resolve_request_context(request, nn._config, home=nn._home)
        return ctx.user_id

    @router.get("/maturity")
    def get_memory_maturity(
        request: Request,
        _role: Annotated[str, Depends(require_admin_owner)],
    ) -> dict:
        from niannian.soul.subject_maturity import refresh_subject_matured

        return refresh_subject_matured(nn._home)

    @router.post("/backup")
    def post_memory_backup(
        body: BackupBody,
        _role: Annotated[str, Depends(require_admin_owner)],
    ) -> dict[str, Any]:
        from niannian.admin.memory_ops import create_memory_backup

        return create_memory_backup(nn._home, scope=body.scope)

    @router.post("/wipe")
    def post_memory_wipe(
        request: Request,
        body: WipeBody,
        _role: Annotated[str, Depends(require_admin_owner)],
    ) -> dict[str, Any]:
        from niannian.admin.memory_ops import MemoryOpsError, wipe_memory

        try:
            return wipe_memory(
                nn._home,
                scope=body.scope,
                confirm=body.confirm,
                username=_user_id(request),
                backup_id=body.backup_id,
            )
        except MemoryOpsError as exc:
            status = 403 if exc.code == "personality_locked" else 400
            raise HTTPException(status_code=status, detail={"code": exc.code, "message": exc.message}) from exc

    @router.post("/marginalize/preview")
    def post_marginalize_preview(
        body: MarginalizeBody,
        _role: Annotated[str, Depends(require_admin_owner)],
    ) -> dict[str, Any]:
        from niannian.admin.marginalize import preview_marginalize

        return preview_marginalize(nn._home, percent=body.percent)

    @router.post("/marginalize")
    def post_marginalize(
        body: MarginalizeBody,
        _role: Annotated[str, Depends(require_admin_owner)],
    ) -> dict[str, Any]:
        from niannian.admin.marginalize import apply_marginalize

        return apply_marginalize(nn._home, percent=body.percent)

    return router
