"""Assessment generate / grade."""

from uuid import uuid4

from app.schemas.assessments import (AssessmentGenerateRequest,AssessmentGenerateResponse,AssessmentGradeRequest,AssessmentGradeResponse,)
from app.schemas.common import JobStatus
from app.schemas.questions import QuestionType
from app.services.ai_generate import generate_json
from app.services.questions import _local_questions, _parse_questions


class AssessmentsService:
    async def generate(
        self, payload: AssessmentGenerateRequest
    ) -> AssessmentGenerateResponse:
        system = (
            "Generate an assessment. Return JSON: {\"questions\":[...],\"rubric\":{}}"
        )
        user = (
            f"Role: {payload.role_title}\nKind: {payload.kind.value}\n"
            f"JD: {payload.job_description}\nDifficulty: {payload.difficulty.value}\n"
            f"Types: {[t.value for t in payload.question_types]}\nCount: {payload.count}\n"
            f"Skills: {payload.skills}\nTime limit: {payload.time_limit_minutes}"
        )
        primary = payload.question_types[0] if payload.question_types else QuestionType.MCQ

        def local() -> dict:
            return {
                "questions": _local_questions(
                    count=payload.count,
                    qtype=primary,
                    difficulty=payload.difficulty,
                    topic=f"{payload.kind.value} / {payload.role_title}",
                ),
                "rubric": {
                    "passing_score": 0.7,
                    "time_limit_minutes": payload.time_limit_minutes,
                    "kind": payload.kind.value,
                },
            }

        data, stub, provider = await generate_json(
            system=system, user=user, local_factory=local
        )
        questions = _parse_questions(
            data.get("questions", []), primary, payload.difficulty
        )
        if not questions:
            questions = _parse_questions(
                local()["questions"], primary, payload.difficulty
            )
            stub, provider = True, "local"

        return AssessmentGenerateResponse(
            correlation_id=payload.correlation_id,
            assessment_id=str(uuid4()),
            kind=payload.kind,
            role_title=payload.role_title,
            status=JobStatus.SUCCEEDED,
            stub=stub,
            message=f"Assessment generated via {provider}",
            questions=questions,
            rubric=data.get("rubric") or {},
        )

    async def grade(self, payload: AssessmentGradeRequest) -> AssessmentGradeResponse:
        system = (
            "Grade assessment submissions. Return JSON: "
            "{\"total_score\",\"max_total_score\",\"passed\",\"feedback_markdown\",\"item_results\":[]}"
        )
        user = (
            f"assessment_id={payload.assessment_id}\nkind={payload.kind.value}\n"
            f"rubric={payload.rubric}\nanswers={payload.answers}"
        )

        def local() -> dict:
            n = len(payload.answers)
            max_total = float(n)
            total = round(max_total * 0.7, 2)
            return {
                "total_score": total,
                "max_total_score": max_total,
                "passed": total >= max_total * 0.7,
                "feedback_markdown": "Solid attempt. Strengthen edge-case reasoning.",
                "item_results": [
                    {"index": i, "score": 0.7, "max_score": 1.0}
                    for i in range(n)
                ],
            }

        data, stub, provider = await generate_json(
            system=system, user=user, local_factory=local
        )
        return AssessmentGradeResponse(
            correlation_id=payload.correlation_id,
            assessment_id=payload.assessment_id,
            status=JobStatus.SUCCEEDED,
            stub=stub,
            message=f"Assessment graded via {provider}",
            total_score=float(data.get("total_score") or 0),
            max_total_score=float(data.get("max_total_score") or 0),
            passed=data.get("passed"),
            feedback_markdown=data.get("feedback_markdown"),
            item_results=list(data.get("item_results") or []),
        )
