from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from src.models import Category, Difficulty, Pattern, Question, QuestionCategory, QuestionPattern
from src.schemas import CategoryCount, DifficultyCount, PatternCount, StatsResponse


class StatsService:
    def __init__(self, db: AsyncSession) -> None:
        self.db = db

    async def get_stats(self) -> StatsResponse:
        total_result = await self.db.execute(select(func.count(Question.id)))
        total_questions = total_result.scalar() or 0

        difficulty_query = select(
            Question.difficulty, func.count(Question.id).label("count")
        ).group_by(Question.difficulty)
        difficulty_result = await self.db.execute(difficulty_query)
        difficulty_counts = {row[0]: row[1] for row in difficulty_result.all()}

        by_difficulty = DifficultyCount(
            easy=difficulty_counts.get(Difficulty.EASY, 0),
            medium=difficulty_counts.get(Difficulty.MEDIUM, 0),
            hard=difficulty_counts.get(Difficulty.HARD, 0),
        )

        category_query = (
            select(Category.name, Category.slug, func.count(QuestionCategory.question_id))
            .join(QuestionCategory, Category.id == QuestionCategory.category_id)
            .group_by(Category.id)
            .order_by(func.count(QuestionCategory.question_id).desc())
        )
        category_result = await self.db.execute(category_query)
        by_category = [
            CategoryCount(name=row[0], slug=row[1], count=row[2]) for row in category_result.all()
        ]

        pattern_query = (
            select(Pattern.name, Pattern.slug, func.count(QuestionPattern.question_id))
            .join(QuestionPattern, Pattern.id == QuestionPattern.pattern_id)
            .group_by(Pattern.id)
            .order_by(func.count(QuestionPattern.question_id).desc())
        )
        pattern_result = await self.db.execute(pattern_query)
        by_pattern = [
            PatternCount(name=row[0], slug=row[1], count=row[2]) for row in pattern_result.all()
        ]

        return StatsResponse(
            total_questions=total_questions,
            by_difficulty=by_difficulty,
            by_category=by_category,
            by_pattern=by_pattern,
        )
