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)

        print(total_user_quiz)

        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
