from typing import List, Literal, Optional
from fastapi import APIRouter, Depends
from sqlmodel import Session
from cachetools import TTLCache
import random

from app.core.db import get_session
from app.api import deps
from app.models.models import User
from app.schemas.quiz import QuestionWithAnswerResponse, QuestionResponse, QuizStartResponse
from app.schemas.history import QuizHistoryCreate, QuizHistoryResponse
from app.crud import quiz as crud_quiz
from app.crud import history as crud_history
from app.api import deps
from app.services import quiz_service
from app.crud import study_plan as crud_sp
from datetime import datetime

router = APIRouter()
cache = TTLCache(maxsize=100, ttl=300)


@router.get("/quizzes/{quiz_id}/start", response_model=QuizStartResponse)
def start_quiz(
    quiz_id: str,
    mode: Literal["practice", "test"] = "practice",
    limit: int = 10,
    exclude_practiced: bool = False,
    current_user: User = Depends(deps.get_current_active_user),
    session: Session = Depends(get_session),
):
    return quiz_service.start_quiz(session, quiz_id, mode, limit, exclude_practiced, current_user.id)


@router.get("/quizzes/{quiz_id}/questions", response_model=List[QuestionWithAnswerResponse])
def read_questions(
    quiz_id: str,
    session: Session = Depends(get_session),
):
    cache_key = f"questions_{quiz_id}"
    if cache_key in cache:
        return cache[cache_key]

    questions = crud_quiz.get_questions_by_quiz(session, quiz_id)
    cache[cache_key] = questions
    return questions


@router.get("/questions/random", response_model=List[QuestionResponse])
def read_random_questions(
    limit: int = 10,
    session: Session = Depends(get_session),
):
    all_questions = crud_quiz.get_all_questions(session)
    if not all_questions:
        return []
    return random.sample(all_questions, min(len(all_questions), limit))


@router.get("/quizzes/{quiz_id}/history", response_model=QuizHistoryResponse)
def get_quiz_history(
    quiz_id: str,
    current_user: Optional[User] = Depends(deps.get_current_user_optional),
    session: Session = Depends(get_session),
):
    if not current_user:
        now = datetime.utcnow()
        return QuizHistoryResponse(
            id=0,
            user_id=0,
            quiz_id=quiz_id,
            passed_questions=[],
            failed_questions=[],
            score=0,
            created_at=now,
            updated_at=now,
            completion_percentage=0
        )

    history = crud_history.get_history_by_user_and_quiz(session, current_user.id, quiz_id)
    if not history:
        now = datetime.utcnow()
        return QuizHistoryResponse(
            id=0,
            user_id=current_user.id,
            quiz_id=quiz_id,
            passed_questions=[],
            failed_questions=[],
            score=0,
            created_at=now,
            updated_at=now,
            completion_percentage=0
        )

    quiz = crud_quiz.get_quiz_by_id(session, quiz_id)
    questions = crud_quiz.get_questions_by_quiz(session, quiz_id)
    total_q = len(questions) if questions else 0
    pct = round((len(history.passed_questions) / total_q) * 100) if total_q > 0 else 0

    response = QuizHistoryResponse.model_validate(history)
    response.completion_percentage = pct
    return response


@router.post("/quizzes/{quiz_id}/history", response_model=QuizHistoryResponse)
def submit_quiz_history(
    quiz_id: str,
    payload: QuizHistoryCreate,
    current_user: User = Depends(deps.get_current_active_user),
    session: Session = Depends(get_session),
):
    history = crud_history.upsert_quiz_history(
        session, current_user.id, quiz_id, payload.passed_questions, payload.failed_questions
    )
    if payload.passed_questions:
        for qid in payload.passed_questions:
            existing = crud_sp.find_existing(session, current_user.id, qid)
            if existing and existing.status != "done":
                crud_sp.update_item_status(session, existing.id, "done")

    questions = crud_quiz.get_questions_by_quiz(session, quiz_id)
    total_q = len(questions) if questions else 0
    pct = round((len(history.passed_questions) / total_q) * 100) if total_q > 0 else 0

    response = QuizHistoryResponse.model_validate(history)
    response.completion_percentage = pct
    return response

