import random
from typing import Optional
from fastapi import HTTPException
from sqlmodel import Session
from app.crud import quiz as crud_quiz
from app.crud import history as crud_history
from app.crud import study_plan as crud_sp


def shuffle_question_options(question) -> dict:
    """Shuffle the options of a question and adjust the answer index if allowed."""
    options = list(question.options)
    correct_answer_text = options[question.answer]

    if getattr(question, 'is_shufflable', True):
        random.shuffle(options)
        new_answer_idx = options.index(correct_answer_text)
    else:
        new_answer_idx = question.answer

    return {
        "id": question.id,
        "content": question.content,
        "options": options,
        "answer": new_answer_idx,
        "difficulty": question.difficulty,
        "sub_topic": question.sub_topic,
    }


def start_quiz(
    session: Session,
    quiz_id: str,
    mode: str,
    limit: int,
    exclude_practiced: bool = False,
    user_id: Optional[int] = None
) -> dict:
    """Select random questions, shuffle their options, and return a quiz payload."""
    quiz = crud_quiz.get_quiz_by_id(session, quiz_id)
    if not quiz:
        raise HTTPException(status_code=404, detail="Quiz not found")

    all_questions = crud_quiz.get_questions_by_quiz(session, quiz_id)
    if not all_questions:
        raise HTTPException(status_code=404, detail="No questions available for this quiz")

    if exclude_practiced and user_id:
        history = crud_history.get_history_by_user_and_quiz(session, user_id, quiz_id)
        if history and history.passed_questions:
            passed_set = set(history.passed_questions)
            all_questions = [q for q in all_questions if q.id not in passed_set]
        try:
            done_qids = crud_sp.get_done_question_ids_by_user_and_quiz(session, user_id, quiz_id)
            if done_qids:
                done_set = set(done_qids)
                all_questions = [q for q in all_questions if q.id not in done_set]
        except Exception:
            pass

    total_available = len(all_questions)

    if mode == "test":
        count = min(50, total_available)
    else:
        count = min(max(1, limit), total_available)

    selected = random.sample(all_questions, count) if total_available > 0 else []

    topic = None
    if getattr(quiz, 'topic_id', None):
        topic = crud_quiz.get_topic_by_id(session, quiz.topic_id)

    return {
        "quiz_id": quiz.id,
        "quiz_name": quiz.name,
        "mode": mode,
        "topic_id": topic.id if topic else None,
        "topic_name": topic.name if topic else None,
        "topic_icon": topic.icon if topic else None,
        "total_available": total_available,
        "questions": [shuffle_question_options(q) for q in selected],
    }
