import json
import requests
from django.conf import settings
from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.http import require_POST

from .models import QuestionType, Difficulty, QuestionBatch, Question, Topic
from .prompts import BASE_SYSTEM_PROMPT, build_user_prompt


def index(request):
    return render(request, "questionbank.html", {
        "question_types": QuestionType.choices,
        "difficulties": Difficulty.choices,
    })


def call_llm(system_prompt, user_prompt):
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {settings.MODEL_API_KEY}",
    }
    payload = {
        "model": settings.MODEL_NAME,
        "messages": [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt},
        ],
        "temperature": 0.7,
        "max_tokens": 2048,
    }
    response = requests.post(settings.MODEL_API_ENDPOINT, headers=headers,
                              data=json.dumps(payload), timeout=settings.MODEL_API_TIMEOUT)
    response.raise_for_status()
    return response.json()["choices"][0]["message"]["content"]


def extract_json_array(text):
    import re
    text = text.strip()
    text = re.sub(r"^```(?:json)?", "", text).strip()
    text = re.sub(r"```$", "", text).strip()
    try:
        return json.loads(text)
    except json.JSONDecodeError:
        match = re.search(r"\[.*\]", text, re.DOTALL)
        if match:
            return json.loads(match.group(0))
        raise


@require_POST
def generate_view(request):
    body = json.loads(request.body)
    topic_name = body.get("topic", "").strip()
    question_type = body.get("question_type")
    count = int(body.get("count", 5))
    difficulty = body.get("difficulty", "medium")

    if not topic_name or question_type not in dict(QuestionType.choices):
        return JsonResponse({"error": "Invalid topic or question_type"}, status=400)

    topic, _ = Topic.objects.get_or_create(name=topic_name)
    batch = QuestionBatch.objects.create(
        topic=topic, question_type=question_type,
        difficulty=difficulty, requested_count=count,
    )

    try:
        user_prompt = build_user_prompt(question_type, topic_name, count, difficulty)
        raw = call_llm(BASE_SYSTEM_PROMPT, user_prompt)
        batch.raw_response = raw
        items = extract_json_array(raw)

        for item in items:
            Question.objects.create(
                batch=batch, question_type=question_type,
                question_text=item.get("question_text", ""),
                options=item.get("options"),
                correct_answer=item.get("correct_answer"),
                explanation=item.get("explanation", ""),
                difficulty=difficulty,
            )
        batch.status = QuestionBatch.STATUS_SUCCESS
        batch.save()

    except Exception as e:
        batch.status = QuestionBatch.STATUS_FAILED
        batch.error_message = str(e)
        batch.save()

    questions = [
        {"question_text": q.question_text, "options": q.options,
         "correct_answer": q.correct_answer, "explanation": q.explanation}
        for q in batch.questions.all()
    ]
    return JsonResponse({"status": batch.status, "error_message": batch.error_message, "questions": questions})