"""Toggle comment like use case. This module implements the use case for toggling likes on comments. If the user already liked the comment, the like is removed (unlike). If not, a new like is added. """ from uuid import UUID from app.application.dtos.comment import CommentResponseDTO from app.application.interfaces import TransactionManager from app.domain.entities.comment import Comment from app.domain.entities.comment_like import CommentLike from app.domain.exceptions import NotFoundException from app.domain.repositories import CommentRepository class ToggleCommentLikeUseCase: """Use case for toggling a like on a comment. Handles like/unlike toggle logic. If the user has already liked the comment, the like is removed. Otherwise, a new like is created. Attributes: _comment_repo: Repository for comment and like data access. _tx_manager: Transaction manager for commit control. """ def __init__( self, comment_repo: CommentRepository, tx_manager: TransactionManager, ) -> None: """Initialize use case with dependencies. Args: comment_repo: Repository for comment and like operations. tx_manager: Transaction manager instance. """ self._comment_repo = comment_repo self._tx_manager = tx_manager async def execute(self, comment_id: UUID, liked_by: str) -> CommentResponseDTO: """Toggle like on a comment. If the user already liked the comment, remove the like. Otherwise, add a new like. Args: comment_id: UUID of the comment to toggle like on. liked_by: User ID. Returns: CommentResponseDTO with updated like_count. Raises: NotFoundException: If comment with given ID does not exist. """ comment = await self._comment_repo.get_by_id(comment_id) if not comment: raise NotFoundException(f"Comment with id '{comment_id}' not found") existing_like = await self._comment_repo.get_like(comment_id, liked_by) if existing_like: await self._comment_repo.remove_like(comment_id, liked_by) comment.like_count = max(0, comment.like_count - 1) else: new_like = CommentLike(comment_id=comment_id, liked_by=liked_by) await self._comment_repo.add_like(new_like) comment.like_count += 1 await self._comment_repo.update(comment) await self._tx_manager.commit() return self._map_to_dto(comment) def _map_to_dto(self, comment: Comment) -> CommentResponseDTO: """Map domain entity to response DTO. Args: comment: Domain Comment entity. Returns: CommentResponseDTO with all comment attributes including like_count. """ return CommentResponseDTO( id=comment.id, post_id=comment.post_id, author_id=comment.author_id, content=comment.content.value, parent_id=comment.parent_id, like_count=comment.like_count, created_at=comment.created_at, updated_at=comment.updated_at, )