from typing import List, Optional
from sqlmodel import Session, select
from sqlalchemy.orm import selectinload
from app.models.models import StudyPlanItem, Question, Quiz


def get_items(
    session: Session, user_id: int, topic_id: Optional[str] = None
) -> List[StudyPlanItem]:
    """Get study plan items with questions eagerly loaded (fixes N+1)."""
    stmt = (
        select(StudyPlanItem)
        .options(selectinload(StudyPlanItem.question))
        .where(StudyPlanItem.user_id == user_id)
        .order_by(StudyPlanItem.created_at.desc())
    )
    if topic_id:
        stmt = stmt.where(StudyPlanItem.topic_id == topic_id)

    return session.exec(stmt).all()


def find_existing(
    session: Session, user_id: int, question_id: int
) -> Optional[StudyPlanItem]:
    stmt = select(StudyPlanItem).where(
        StudyPlanItem.user_id == user_id,
        StudyPlanItem.question_id == question_id,
    )
    return session.exec(stmt).one_or_none()


def add_item(
    session: Session,
    user_id: int,
    question_id: int,
    topic_id: str,
    sub_topic: str,
    source: str = "manual",
) -> StudyPlanItem:
    item = StudyPlanItem(
        user_id=user_id,
        question_id=question_id,
        topic_id=topic_id,
        sub_topic=sub_topic,
        source=source,
    )
    session.add(item)
    session.commit()
    session.refresh(item)
    return item


def remove_item(session: Session, item_id: int) -> None:
    item = session.get(StudyPlanItem, item_id)
    if item:
        session.delete(item)
        session.commit()


def get_item_by_id(session: Session, item_id: int) -> Optional[StudyPlanItem]:
    return session.get(StudyPlanItem, item_id)


def resolve_topic_id(session: Session, question_id: int) -> str:
    """Get the topic_id for a question by traversing question → quiz → topic."""
    question = session.get(Question, question_id)
    if not question:
        return "unknown"
    quiz = session.get(Quiz, question.quiz_id)
    return quiz.topic_id if quiz else "unknown"

def update_item_status(
    session: Session, item_id: int, status: str
) -> Optional[StudyPlanItem]:
    """Updates the status of a specific study plan item."""
    item = session.get(StudyPlanItem, item_id)
    if item:
        item.status = status
        session.commit()
        session.refresh(item)
    return item


def get_done_question_ids_by_user_and_quiz(
    session: Session, user_id: int, quiz_id: str
) -> List[int]:
    """Return list of question IDs that are marked 'done' in the user's study plan for a given quiz."""
    stmt = (
        select(StudyPlanItem.question_id)
        .join(Question, StudyPlanItem.question_id == Question.id)
        .where(
            StudyPlanItem.user_id == user_id,
            StudyPlanItem.status == "done",
            Question.quiz_id == quiz_id,
        )
    )
    return [row[0] for row in session.exec(stmt).all()]
