from app.repositories import QuizRepository, UserRepository, SubjectRepository from app.schemas.requests import QuizCreateSchema from app.schemas.response import ( UserQuizListResponse, ListingQuizResponse, QuizGetSchema, ) from app.exception import DataNotFoundException, ValidationException from app.mapper import QuizMapper from app.helpers import DatetimeUtil class QuizService: def __init__( self, quiz_repository=QuizRepository, user_repository=UserRepository, subject_repository=SubjectRepository, ): self.quiz_repository = quiz_repository self.user_repostory = user_repository self.subject_repository = subject_repository def get_quiz(self, quiz_id) -> QuizGetSchema: data = self.quiz_repository.get_by_id(quiz_id) if data is None: raise DataNotFoundException("Quiz not found") quiz_subject = self.subject_repository.get_by_id(data.subject_id) return QuizMapper.map_quiz_entity_to_schema(data, quiz_subject) def search_quiz( self, keyword: str, subject_id: str, page: int = 1, page_size: int = 10 ) -> tuple[list[ListingQuizResponse], int]: quizzes = self.quiz_repository.search_by_title_or_category( keyword=keyword, page=page, page_size=page_size, subject_id=subject_id, ) total = self.quiz_repository.count_by_search(keyword) mapped_quizzes = [] for quiz in quizzes: author = self.user_repostory.get_user_by_id(user_id=quiz.author_id) if author is None: continue mapped_quizzes.append( QuizMapper.quiz_to_recomendation_mapper( quiz_entity=quiz, user_entity=author, ) ) return mapped_quizzes, total def get_user_quiz( self, user_id: str, page: int = 1, page_size: int = 10 ) -> UserQuizListResponse: quizzes = self.quiz_repository.get_by_user_id(user_id, page, page_size) if not quizzes: return UserQuizListResponse(total=0, quizzes=[]) total_user_quiz = self.quiz_repository.count_by_user_id(user_id) user = self.user_repostory.get_user_by_id(user_id) quiz_data = [ QuizMapper.quiz_to_recomendation_mapper(quiz, user) for quiz in quizzes ] return UserQuizListResponse(total=total_user_quiz, quizzes=quiz_data) def create_quiz(self, quiz_data: QuizCreateSchema): total_time = 0 for question in quiz_data.question_listings: if question.type == "option" and ( not question.options or len(question.options) != 4 ): raise ValidationException( "Option type questions must have exactly 4 options." ) total_time += question.duration datetime_now = DatetimeUtil.now_iso() data = QuizMapper.map_quiz_schema_to_entity( schema=quiz_data, datetime=datetime_now, total_duration=total_time, ) return self.quiz_repository.create(data) def update_quiz(self, quiz_id, quiz_data): return self.quiz_repository.update(quiz_id, quiz_data) def delete_quiz(self, quiz_id): return self.quiz_repository.delete(quiz_id) def get_quiz_recommendation(self, page: int, limit: int): data = self.quiz_repository.get_top_played_quizzes(page=page, limit=limit) if not data: raise DataNotFoundException("Quiz not found") result = [] for quiz in data: author = self.user_repostory.get_user_by_id(user_id=quiz.author_id) result.append( QuizMapper.quiz_to_recomendation_mapper( quiz_entity=quiz, user_entity=author, ) ) return result