"""Manage role-to-feature permissions."""

from __future__ import annotations

from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from backend.api.users import get_current_admin_user
from backend.constants.role_features import ROLE_FEATURES, ROLE_FEATURE_KEYS
from backend.constants.roles import ROLE_VALUES
from backend.db.session import get_db
from backend.schemas.role_permissions import (
    RoleFeatureSchema,
    RolePermissionsResponse,
    RolePermissionsUpdateRequest,
)
from backend.services.role_permissions import (
    ensure_role_permissions_initialized,
    fetch_role_permissions_map,
    set_role_permissions,
)

router = APIRouter(prefix="/role-permissions", tags=["role-permissions"])


@router.get("", response_model=RolePermissionsResponse)
def list_role_permissions(
    current_admin: Annotated[dict, Depends(get_current_admin_user)],
    db: Session = Depends(get_db),
) -> RolePermissionsResponse:
    """Return the current role/feature permission matrix."""

    ensure_role_permissions_initialized(db)
    permissions = fetch_role_permissions_map(db)
    features = [RoleFeatureSchema(**feature) for feature in ROLE_FEATURES]
    return RolePermissionsResponse(features=features, permissions=permissions)


@router.put("", response_model=RolePermissionsResponse)
def update_role_permissions(
    current_admin: Annotated[dict, Depends(get_current_admin_user)],
    request: RolePermissionsUpdateRequest,
    db: Session = Depends(get_db),
) -> RolePermissionsResponse:
    """Update permissions for the provided matrix."""

    invalid_roles = set(request.permissions.keys()) - set(ROLE_VALUES)
    if invalid_roles:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Invalid role(s): {', '.join(sorted(invalid_roles))}",
        )

    for feature_map in request.permissions.values():
        invalid_features = set(feature_map.keys()) - set(ROLE_FEATURE_KEYS)
        if invalid_features:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"Invalid feature(s): {', '.join(sorted(invalid_features))}",
            )

    set_role_permissions(db, request.permissions)
    permissions = fetch_role_permissions_map(db)
    features = [RoleFeatureSchema(**feature) for feature in ROLE_FEATURES]
    return RolePermissionsResponse(features=features, permissions=permissions)







