from fastapi import Request, HTTPException
from .auth import get_user_from_token
from enum import Enum
from typing import Optional


class PermissionLevel(str, Enum):
    PUBLIC = "public"
    READ_ONLY = "read_only"
    LIMITED_WRITE = "limited_write"
    MANAGE = "manage"
    ADMIN = "admin"


ADMIN_ROLES = {"system_admin", "admin", "org_admin"}

ROLE_PERMISSIONS: dict[str, list[PermissionLevel]] = {
    "system_admin": [
        PermissionLevel.PUBLIC,
        PermissionLevel.READ_ONLY,
        PermissionLevel.LIMITED_WRITE,
        PermissionLevel.MANAGE,
        PermissionLevel.ADMIN,
    ],
    "org_admin": [
        PermissionLevel.PUBLIC,
        PermissionLevel.READ_ONLY,
        PermissionLevel.LIMITED_WRITE,
        PermissionLevel.MANAGE,
    ],
    "admin": [
        PermissionLevel.PUBLIC,
        PermissionLevel.READ_ONLY,
        PermissionLevel.LIMITED_WRITE,
        PermissionLevel.MANAGE,
        PermissionLevel.ADMIN,
    ],
    "case_manager": [
        PermissionLevel.PUBLIC,
        PermissionLevel.READ_ONLY,
        PermissionLevel.LIMITED_WRITE,
    ],
    "operator": [
        PermissionLevel.PUBLIC,
        PermissionLevel.READ_ONLY,
    ],
    "auditor": [
        PermissionLevel.PUBLIC,
        PermissionLevel.READ_ONLY,
    ],
    "user": [
        PermissionLevel.PUBLIC,
        PermissionLevel.READ_ONLY,
    ],
    "viewer": [
        PermissionLevel.PUBLIC,
    ],
}

ROLE_LEVEL_MAP: dict[str, int] = {
    "viewer": 1,
    "operator": 2,
    "case_manager": 3,
    "org_admin": 4,
    "system_admin": 5,
    "admin": 5,
    "auditor": 2,
    "user": 2,
}


def is_admin_role(role: str) -> bool:
    # 单机版：所有登录用户均拥有管理员权限
    return True


def get_role_level(role: str) -> int:
    return ROLE_LEVEL_MAP.get(role, 1)


def get_current_user(request: Request) -> Optional[dict]:
    authorization = request.headers.get("authorization")
    return get_user_from_token(authorization)


def require_permission(level: PermissionLevel):
    async def _check(request: Request):
        if level == PermissionLevel.PUBLIC:
            return None

        user = get_current_user(request)
        if not user:
            raise HTTPException(status_code=401, detail="未登录")

        user_perms = ROLE_PERMISSIONS.get(user["role"], [])
        if level not in user_perms:
            raise HTTPException(
                status_code=403, detail=f"无权限，需要{level.value}权限"
            )
        return user

    return _check


def require_level(min_level: int):
    async def _check(request: Request):
        if min_level <= 1:
            return None

        user = get_current_user(request)
        if not user:
            raise HTTPException(status_code=401, detail="未登录")

        user_level = get_role_level(user["role"])
        if user_level < min_level:
            level_names = {1: "viewer", 2: "operator", 3: "case_manager", 4: "org_admin", 5: "system_admin"}
            required = level_names.get(min_level, f"L{min_level}")
            raise HTTPException(
                status_code=403,
                detail=f"权限不足，需要{required}级别(L{min_level})以上权限",
            )
        return user

    return _check


async def require_admin(request: Request) -> dict:
    user = get_current_user(request)
    if not user:
        raise HTTPException(status_code=401, detail="未登录")
    if not is_admin_role(user["role"]):
        raise HTTPException(status_code=403, detail="无管理员权限")
    return user


async def require_login(request: Request) -> dict:
    user = get_current_user(request)
    if not user:
        raise HTTPException(status_code=401, detail="未登录")
    return user
