# -*- coding: utf-8 -*-
"""运营方管理端点（证明 RBAC 角色/权限/审计）。"""
from __future__ import annotations

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

from ..dependencies import get_db
from ..schemas.admin import SetUserRoleRequest, SetUserStatusRequest
from ..schemas.admin import UserCreateRequest, RolePermissionRequest, UpdateUserRequest
from ...rbac import require_permission, require_roles, write_audit
from ...infrastructure.repositories import Database

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


@router.post("/users", summary="新增账号（按类型/角色）")
async def create_user(
    req: UserCreateRequest,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_permission("action:user.assign_role")),
):
    from ...services.user_admin_service import UserAdminService

    user = await UserAdminService(db).create_user(req, actor)
    await write_audit(db, action="user.create", resource="user", resource_id=user["id"],
                detail=f"role={req.role}", user=actor, request=request)
    return await db.users.to_profile(user)


def _port_for_role(role: str) -> str:
    return {
        "opc_member": "opc", "carrier": "carrier", "enterprise": "enterprise",
        "provider": "provider", "government": "government", "operator": "operator",
        "investor": "investor", "developer": "developer",
    }.get(role, "opc")


@router.get("/users", summary="用户列表（运营方）")
async def list_users(
    request: Request,
    db: Database = Depends(get_db),
    _role: dict = Depends(require_roles("operator")),
    _perm: dict = Depends(require_permission("menu:admin_user_mgmt")),
):
    return await db.users.list()


@router.post("/users/{user_id}/role", summary="分配角色")
async def set_user_role(
    user_id: str,
    req: SetUserRoleRequest,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_permission("action:user.assign_role")),
):
    from ...services.user_admin_service import UserAdminService

    if await db.users.get_by_id(user_id) is None:
        raise HTTPException(status_code=404, detail="User not found")
    updated = await UserAdminService(db).set_user_role(
        actor, user_id, req.role, req.sub_role, req.org_id, req.region_id,
    )
    await write_audit(
        db, action="role.assign", resource="user", resource_id=user_id,
        detail=f"{actor['username']} -> role={req.role} sub={req.sub_role}",
        user=actor, request=request,
    )
    return {"ok": True, "user": await db.users.to_profile(updated)}


@router.post("/users/{user_id}/status", summary="禁用/启用用户")
async def set_user_status(
    user_id: str,
    req: SetUserStatusRequest,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_permission("action:user.disable")),
):
    if await db.users.get_by_id(user_id) is None:
        raise HTTPException(status_code=404, detail="User not found")
    updated = await db.users.set_status(user_id, req.status)
    await write_audit(
        db, action="user.disable", resource="user", resource_id=user_id,
        detail=f"{actor['username']} -> status={req.status}",
        user=actor, request=request,
    )
    return {"ok": True, "user": await db.users.to_profile(updated)}


@router.put("/users/{user_id}", summary="修改用户（资料/角色）")
async def update_user(
    user_id: str,
    req: UpdateUserRequest,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_permission("action:user.manage")),
):
    user = await db.users.get_by_id(user_id)
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    profile_fields = {k: v for k, v in req.model_dump(exclude_none=True).items() if k in ("nickname",)}
    if profile_fields:
        user = await db.users.update_profile(user_id, profile_fields) or user
    if req.role or req.sub_role is not None:
        user = await db.users.set_role(user_id, req.role or user.get("role"), req.sub_role,
                                       req.org_id or user.get("org_id"), req.region_id or user.get("region_id"))
    await write_audit(db, action="user.update", resource="user", resource_id=user_id,
                detail=str(req.model_dump(exclude_none=True)), user=actor, request=request)
    return {"ok": True, "user": await db.users.to_profile(user)}


@router.delete("/users/{user_id}", summary="删除用户")
async def delete_user(
    user_id: str,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_permission("action:user.manage")),
):
    ok = await db.users.delete(user_id)
    if not ok:
        raise HTTPException(status_code=404, detail="User not found")
    await write_audit(db, action="user.delete", resource="user", resource_id=user_id,
                detail="deleted", user=actor, request=request)
    return {"ok": True, "user_id": user_id}


@router.get("/roles", summary="角色列表")
async def list_roles(
    db: Database = Depends(get_db),
    _user: dict = Depends(require_permission("menu:admin_role_mgmt")),
):
    return await db.roles.list_roles()


@router.get("/permissions", summary="权限列表")
async def list_permissions(
    db: Database = Depends(get_db),
    _user: dict = Depends(require_permission("menu:admin_role_mgmt")),
):
    return await db.roles.list_permissions()


@router.post("/roles/{role_id}/permissions", summary="配置角色权限")
async def set_role_permissions(
    role_id: str,
    req: RolePermissionRequest,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_permission("action:role.grant_perm")),
):
    if not await db.roles.role_exists(role_id):
        raise HTTPException(status_code=404, detail="Role not found")
    perms = await db.roles.set_role_permissions(role_id, req.permissions)
    await write_audit(db, action="role.grant_perm", resource="role", resource_id=role_id,
                detail=f"permissions={len(req.permissions)}", user=actor, request=request)
    return {"ok": True, "role_id": role_id, "permissions": perms}


@router.get("/audit-logs", summary="审计日志")
async def list_audit_logs(
    limit: int = 100,
    offset: int = 0,
    db: Database = Depends(get_db),
    _user: dict = Depends(require_permission("action:audit.view")),
):
    return await db.audit.list(limit=min(limit, 500), offset=offset)
