from __future__ import annotations

from fastapi import APIRouter, Depends, Query, status

from src.core.deps import get_usuarios_service, require_api_key
from src.modules.usuarios.schemas import UsuarioCreate, UsuarioOut, UsuarioUpdate
from src.modules.usuarios.service import UsuariosService

router = APIRouter(prefix="/api/v1/usuarios", tags=["Usuarios"])

_ALLOWED_SORT_FIELDS = {"identificador", "$createdAt"}


@router.get(
    "",
    summary="List usuarios",
    description="Return a paginated list of usuarios with optional filtering, sorting, and search.",
    response_model=dict,
    responses={
        status.HTTP_200_OK: {
            "description": "Successful response",
            "content": {
                "application/json": {
                    "example": {
                        "page": 1,
                        "limit": 20,
                        "total": 2,
                        "items": [
                            {
                                "id": "user_1",
                                "identificador": "admin@saveinmed.com",
                                "ativo": True,
                                "superadmin": True,
                                "telefone": "11987654321",
                                "createdAt": "2025-09-29T12:00:00.000Z",
                                "updatedAt": "2025-09-29T12:00:00.000Z",
                            },
                            {
                                "id": "user_2",
                                "identificador": "suporte@saveinmed.com",
                                "ativo": True,
                                "superadmin": False,
                                "telefone": "11991234567",
                                "createdAt": "2025-09-29T12:10:00.000Z",
                                "updatedAt": "2025-09-29T12:10:00.000Z",
                            },
                        ],
                    }
                }
            },
        },
        status.HTTP_400_BAD_REQUEST: {
            "description": "Invalid request parameters",
            "content": {
                "application/json": {
                    "example": {"detail": "Invalid sort field."}
                }
            },
        },
    },
)
async def list_usuarios(
    page: int = Query(1, ge=1),
    limit: int | None = Query(None, ge=1, le=100),
    q: str | None = Query(None, min_length=1),
    sort: str | None = Query(None),
    order: str | None = Query(None, pattern="^(?i)(asc|desc)$"),
    empresas_dados_id: str | None = Query(None, min_length=1),
    ativo: bool | None = Query(None),
    _: None = Depends(require_api_key),
    service: UsuariosService = Depends(get_usuarios_service),
) -> dict:
    normalized_order = order.lower() if order else None
    normalized_sort = sort if sort in _ALLOWED_SORT_FIELDS else sort
    return await service.list(
        page=page,
        limit=limit,
        q=q,
        sort=normalized_sort,
        order=normalized_order,
        empresas_dados_id=empresas_dados_id,
        ativo=ativo,
    )


@router.get(
    "/{usuario_id}",
    summary="Retrieve usuario",
    description="Fetch a single usuario by its identifier, including audit metadata.",
    response_model=UsuarioOut,
    responses={
        status.HTTP_200_OK: {
            "description": "Usuario details",
            "content": {
                "application/json": {
                    "example": {
                        "id": "user_1",
                        "identificador": "admin@saveinmed.com",
                        "ativo": True,
                        "superadmin": True,
                        "telefone": "11987654321",
                        "createdAt": "2025-09-29T12:00:00.000Z",
                        "updatedAt": "2025-09-29T12:00:00.000Z",
                    }
                }
            },
        },
        status.HTTP_404_NOT_FOUND: {
            "description": "Usuario not found",
            "content": {"application/json": {"example": {"detail": "Usuario not found."}}},
        },
    },
)
async def get_usuario(
    usuario_id: str,
    _: None = Depends(require_api_key),
    service: UsuariosService = Depends(get_usuarios_service),
) -> UsuarioOut:
    return await service.get(usuario_id)


@router.post(
    "",
    summary="Create usuario",
    description="Create a new usuario with identifier and password management handled externally.",
    response_model=UsuarioOut,
    status_code=status.HTTP_201_CREATED,
    responses={
        status.HTTP_201_CREATED: {
            "description": "Usuario created",
            "content": {
                "application/json": {
                    "example": {
                        "id": "user_3",
                        "identificador": "novo@saveinmed.com",
                        "ativo": True,
                        "superadmin": False,
                        "telefone": "11987654321",
                        "createdAt": "2025-09-29T12:20:00.000Z",
                        "updatedAt": "2025-09-29T12:20:00.000Z",
                    }
                }
            },
        },
        status.HTTP_409_CONFLICT: {
            "description": "Usuario already exists",
            "content": {
                "application/json": {
                    "example": {"detail": "Usuario already exists."}
                }
            },
        },
    },
)
async def create_usuario(
    payload: UsuarioCreate,
    _: None = Depends(require_api_key),
    service: UsuariosService = Depends(get_usuarios_service),
) -> UsuarioOut:
    return await service.create(payload)


@router.patch(
    "/{usuario_id}",
    summary="Update usuario",
    description="Update an existing usuario partially, allowing credential and flag adjustments.",
    response_model=UsuarioOut,
    responses={
        status.HTTP_200_OK: {
            "description": "Usuario updated",
            "content": {
                "application/json": {
                    "example": {
                        "id": "user_1",
                        "identificador": "admin@saveinmed.com",
                        "ativo": True,
                        "superadmin": True,
                        "auth-id-appwrite": "auth_user_1",
                        "nome": "Administrador",
                        "email": "admin@saveinmed.com",
                        "telefone": "11987654321",
                        "nivel": "admin",
                        "registro-completo": True,
                        "enderecos": ["endereco_01"],
                        "empresasDados": ["empresa_01"],
                        "nome-social": "Admin",
                        "cpf": "12345678901",
                        "createdAt": "2025-09-29T12:00:00.000Z",
                        "updatedAt": "2025-09-29T12:05:00.000Z",
                    }
                }
            },
        },
        status.HTTP_404_NOT_FOUND: {
            "description": "Usuario not found",
            "content": {"application/json": {"example": {"detail": "Usuario not found."}}},
        },
        status.HTTP_409_CONFLICT: {
            "description": "Usuario already exists",
            "content": {
                "application/json": {
                    "example": {"detail": "Usuario already exists."}
                }
            },
        },
    },
)
async def update_usuario(
    usuario_id: str,
    payload: UsuarioUpdate,
    _: None = Depends(require_api_key),
    service: UsuariosService = Depends(get_usuarios_service),
) -> UsuarioOut:
    return await service.update(usuario_id, payload)


@router.delete(
    "/{usuario_id}",
    summary="Delete usuario",
    description="Remove a usuario from the system.",
    status_code=status.HTTP_204_NO_CONTENT,
    responses={
        status.HTTP_204_NO_CONTENT: {"description": "Usuario removed"},
        status.HTTP_404_NOT_FOUND: {
            "description": "Usuario not found",
            "content": {"application/json": {"example": {"detail": "Usuario not found."}}},
        },
    },
)
async def delete_usuario(
    usuario_id: str,
    _: None = Depends(require_api_key),
    service: UsuariosService = Depends(get_usuarios_service),
) -> None:
    await service.delete(usuario_id)
