"""Admin 认证:账号密码登录 → admin JWT(独立 secret)。"""
from __future__ import annotations

import logging

from fastapi import APIRouter, Depends, HTTPException

from app.admin.deps import AdminDb, CurrentAdmin
from app.admin.permissions import CUSTOM_ROLE, sanitize_pages
from app.admin.repositories import admin_role as role_repo
from app.admin.repositories import admin_user as admin_repo
from app.admin.schemas.auth import AdminLoginRequest, AdminLoginResponse, AdminOut
from app.admin.security import create_admin_token
from app.core.ratelimit import rate_limit
from app.core.security import verify_password

logger = logging.getLogger("shagua.admin.auth")

router = APIRouter(prefix="/admin/api/auth", tags=["admin-auth"])


def _admin_out_with_pages(admin, db: AdminDb) -> AdminOut:  # noqa: ANN001
    """AdminOut + 有效可见页(前端左侧导航按此过滤)。
    role=="custom" → 用这个人的 pages_override(按人自定义,过滤悬空 key);其余走角色解析。"""
    out = AdminOut.model_validate(admin)
    if admin.role == CUSTOM_ROLE:
        out.pages = sanitize_pages(admin.pages_override)
    else:
        out.pages = role_repo.effective_pages_of(db, admin.role)
    return out


@router.post(
    "/login",
    response_model=AdminLoginResponse,
    summary="管理员登录",
    dependencies=[Depends(rate_limit(10, 60, "admin-login"))],  # 同 IP 每分钟≤10 次,防爆破
)
def login(req: AdminLoginRequest, db: AdminDb) -> AdminLoginResponse:
    admin = admin_repo.get_by_username(db, req.username)
    # 用户名不存在 / 密码错统一 401 同文案(防账号枚举)。
    # disabled 账号单独 403"账号已禁用":admin 是内部少数已知账号、无枚举价值,
    # 明确提示比防枚举更有运维价值(与 App 端 auth.py 对 disabled 用户的 403 一致)。
    if admin is None or not verify_password(req.password, admin.password_hash):
        raise HTTPException(status_code=401, detail="用户名或密码错误")
    if admin.status != "active":
        raise HTTPException(status_code=403, detail="账号已禁用")

    token, expires_in = create_admin_token(admin_id=admin.id, role=admin.role)
    admin_repo.update_last_login(db, admin)
    logger.info("admin login ok id=%d username=%s role=%s", admin.id, admin.username, admin.role)
    return AdminLoginResponse(
        access_token=token,
        expires_in=expires_in,
        admin=_admin_out_with_pages(admin, db),
    )


@router.get("/me", response_model=AdminOut, summary="当前管理员(含有效可见页)")
def me(admin: CurrentAdmin, db: AdminDb) -> AdminOut:
    return _admin_out_with_pages(admin, db)
