# app/modules/tenancy/routes/api/admin_store_roles.py
"""
Admin store role management endpoints.

Allows super admins and platform admins to manage roles for any store
they have access to. Platform admins are scoped to stores within their
assigned platforms.

Endpoints:
    GET    /admin/store-roles                    — List roles for a store
    GET    /admin/store-roles/permissions/catalog — Permission catalog
    POST   /admin/store-roles                    — Create a role
    PUT    /admin/store-roles/{role_id}          — Update a role
    DELETE /admin/store-roles/{role_id}          — Delete a role
"""

import logging

from fastapi import APIRouter, Depends, Query, Request
from sqlalchemy.orm import Session

from app.api.deps import get_current_admin_api
from app.core.database import get_db
from app.modules.tenancy.schemas.auth import UserContext
from app.modules.tenancy.schemas.team import (
    PermissionCatalogResponse,
    RoleCreate,
    RoleListResponse,
    RoleResponse,
    RoleUpdate,
)
from app.modules.tenancy.services.permission_discovery_service import (
    permission_discovery_service,
)
from app.modules.tenancy.services.store_team_service import store_team_service
from app.utils.i18n import translate

admin_store_roles_router = APIRouter(prefix="/store-roles")
logger = logging.getLogger(__name__)


@admin_store_roles_router.get(
    "/permissions/catalog", response_model=PermissionCatalogResponse
)
def admin_get_permission_catalog(
    request: Request,
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Get the full permission catalog grouped by category.

    Available to all admin users. Returns all permission definitions
    with labels and descriptions for the role editor UI.
    """
    categories = permission_discovery_service.get_permissions_by_category()
    lang = current_admin.preferred_language or getattr(
        request.state, "language", "en"
    )

    def _t(key: str) -> str:
        """Translate key, falling back to readable version."""
        translated = translate(key, language=lang)
        if translated == key:
            parts = key.split(".")
            return parts[-1].replace("_", " ").title()
        return translated

    return PermissionCatalogResponse(
        categories=[
            {
                "id": cat.id,
                "label": _t(cat.label_key),
                "permissions": [
                    {
                        "id": p.id,
                        "label": _t(p.label_key),
                        "description": _t(p.description_key),
                        "is_owner_only": p.is_owner_only,
                    }
                    for p in cat.permissions
                ],
            }
            for cat in categories
        ]
    )


@admin_store_roles_router.get("", response_model=RoleListResponse)
def admin_list_store_roles(
    store_id: int = Query(..., description="Store ID to list roles for"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    List all roles for a store.

    Platform admins can only access stores within their assigned platforms.
    Super admins can access any store.
    """
    store_team_service.validate_admin_store_access(db, current_admin, store_id)

    roles = store_team_service.get_store_roles(db=db, store_id=store_id)
    db.commit()  # Commit in case default roles were created

    return RoleListResponse(roles=roles, total=len(roles))


@admin_store_roles_router.post("", response_model=RoleResponse, status_code=201)
def admin_create_store_role(
    role_data: RoleCreate,
    store_id: int = Query(..., description="Store ID to create role for"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Create a custom role for a store.

    Platform admins can only manage stores within their assigned platforms.
    """
    store_team_service.validate_admin_store_access(db, current_admin, store_id)

    role = store_team_service.create_custom_role(
        db=db,
        store_id=store_id,
        name=role_data.name,
        permissions=role_data.permissions,
        actor_user_id=current_admin.id,
    )
    db.commit()
    return role


@admin_store_roles_router.put("/{role_id}", response_model=RoleResponse)
def admin_update_store_role(
    role_id: int,
    role_data: RoleUpdate,
    store_id: int = Query(..., description="Store ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Update a role's name and/or permissions.

    Platform admins can only manage stores within their assigned platforms.
    """
    store_team_service.validate_admin_store_access(db, current_admin, store_id)

    role = store_team_service.update_role(
        db=db,
        store_id=store_id,
        role_id=role_id,
        name=role_data.name,
        permissions=role_data.permissions,
        actor_user_id=current_admin.id,
    )
    db.commit()
    return role


@admin_store_roles_router.delete("/{role_id}", status_code=204)
def admin_delete_store_role(
    role_id: int,
    store_id: int = Query(..., description="Store ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Delete a custom role.

    Preset roles cannot be deleted. Platform admins can only manage
    stores within their assigned platforms.
    """
    store_team_service.validate_admin_store_access(db, current_admin, store_id)

    store_team_service.delete_role(
        db=db,
        store_id=store_id,
        role_id=role_id,
        actor_user_id=current_admin.id,
    )
    db.commit()
