from __future__ import annotations from typing import Any from fastapi import APIRouter, Depends, HTTPException, Query, Response, Security, status from sqlalchemy.ext.asyncio import AsyncSession from app.database.crud.user_message import ( create_user_message, delete_user_message, get_all_user_messages, get_user_message_by_id, get_user_messages_count, toggle_user_message_status, update_user_message, ) from ..dependencies import get_db_session, require_api_token from ..schemas.user_messages import ( UserMessageCreateRequest, UserMessageListResponse, UserMessageResponse, UserMessageUpdateRequest, ) router = APIRouter() def _serialize(message) -> UserMessageResponse: return UserMessageResponse( id=message.id, message_text=message.message_text, is_active=message.is_active, sort_order=message.sort_order, created_by=message.created_by, created_at=message.created_at, updated_at=message.updated_at, ) @router.get("", response_model=UserMessageListResponse) async def list_user_messages( _: Any = Security(require_api_token), db: AsyncSession = Depends(get_db_session), limit: int = Query(50, ge=1, le=200), offset: int = Query(0, ge=0), include_inactive: bool = Query(True, description="Включать неактивные сообщения"), ) -> UserMessageListResponse: total = await get_user_messages_count(db, include_inactive=include_inactive) messages = await get_all_user_messages( db, offset=offset, limit=limit, include_inactive=include_inactive, ) return UserMessageListResponse( items=[_serialize(message) for message in messages], total=total, limit=limit, offset=offset, ) @router.post("", response_model=UserMessageResponse, status_code=status.HTTP_201_CREATED) async def create_user_message_endpoint( payload: UserMessageCreateRequest, token: Any = Security(require_api_token), db: AsyncSession = Depends(get_db_session), ) -> UserMessageResponse: created_by = getattr(token, "id", None) try: message = await create_user_message( db, message_text=payload.message_text, created_by=created_by, is_active=payload.is_active, sort_order=payload.sort_order, ) except ValueError as error: raise HTTPException(status.HTTP_400_BAD_REQUEST, str(error)) from error return _serialize(message) @router.patch("/{message_id}", response_model=UserMessageResponse) async def update_user_message_endpoint( message_id: int, payload: UserMessageUpdateRequest, _: Any = Security(require_api_token), db: AsyncSession = Depends(get_db_session), ) -> UserMessageResponse: update_payload = payload.dict(exclude_unset=True) try: message = await update_user_message(db, message_id, **update_payload) except ValueError as error: raise HTTPException(status.HTTP_400_BAD_REQUEST, str(error)) from error if not message: raise HTTPException(status.HTTP_404_NOT_FOUND, "User message not found") return _serialize(message) @router.post("/{message_id}/toggle", response_model=UserMessageResponse) async def toggle_user_message_endpoint( message_id: int, _: Any = Security(require_api_token), db: AsyncSession = Depends(get_db_session), ) -> UserMessageResponse: message = await toggle_user_message_status(db, message_id) if not message: raise HTTPException(status.HTTP_404_NOT_FOUND, "User message not found") return _serialize(message) @router.delete("/{message_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_user_message_endpoint( message_id: int, _: Any = Security(require_api_token), db: AsyncSession = Depends(get_db_session), ) -> Response: message = await get_user_message_by_id(db, message_id) if not message: raise HTTPException(status.HTTP_404_NOT_FOUND, "User message not found") await delete_user_message(db, message_id) return Response(status_code=status.HTTP_204_NO_CONTENT)