from collections.abc import Callable
from fastapi import Depends, HTTPException, status
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.api.deps import get_current_user
from app.db.session import get_db
from app.models.platform_staff import PlatformRoleDefinition
from app.models.user import User

PLATFORM_PERMISSIONS = frozenset({"platform.view", "staff.read", "staff.manage", "audit.read", "security.manage"})
SYSTEM_ROLE_PERMISSIONS = {
    "CEO": PLATFORM_PERMISSIONS, "SUPER_ADMIN": PLATFORM_PERMISSIONS,
    "OPERATIONS": frozenset({"platform.view", "staff.read"}),
    "SUPPORT": frozenset({"platform.view", "staff.read"}),
    "FINANCE": frozenset({"platform.view"}), "MARKETING": frozenset({"platform.view"}),
    "READ_ONLY": frozenset({"platform.view", "staff.read", "audit.read"}),
}
ROLE_RANK = {"CEO": 100, "SUPER_ADMIN": 90, "OPERATIONS": 50, "SUPPORT": 40, "FINANCE": 40, "MARKETING": 40, "READ_ONLY": 10}

def effective_platform_permissions(db: Session, user: User) -> frozenset[str]:
    if not user.is_platform_admin or user.platform_staff_status != "ACTIVE":
        return frozenset()
    role = (user.platform_role or "").strip().upper()
    if role in {"CEO", "SUPER_ADMIN"}:
        return PLATFORM_PERMISSIONS
    definition = db.scalar(select(PlatformRoleDefinition).where(PlatformRoleDefinition.key == role, PlatformRoleDefinition.is_active.is_(True)))
    permissions = set(definition.permissions if definition else SYSTEM_ROLE_PERMISSIONS.get(role, ()))
    permissions.update(user.platform_permissions or [])
    return frozenset(permissions & PLATFORM_PERMISSIONS)

def require_platform_permission(permission: str) -> Callable:
    def dependency(current_user: User = Depends(get_current_user), db: Session = Depends(get_db)) -> User:
        effective = effective_platform_permissions(db, current_user)
        if "platform.view" not in effective or permission not in effective:
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You do not have permission to access this platform administration action.")
        return current_user
    return dependency

def is_super_admin(user: User) -> bool:
    return user.is_platform_admin and user.platform_staff_status == "ACTIVE" and (user.platform_role or "").upper() in {"CEO", "SUPER_ADMIN"}

def may_manage_target(actor: User, target: User) -> bool:
    actor_role, target_role = (actor.platform_role or "").upper(), (target.platform_role or "").upper()
    if actor_role == "CEO":
        return target_role != "CEO"
    if actor_role == "SUPER_ADMIN":
        return target_role not in {"CEO", "SUPER_ADMIN"}
    return ROLE_RANK.get(actor_role, 0) > ROLE_RANK.get(target_role, 0)
