import json
import logging
import os
import re
from django.conf import settings

import requests
from pypdf import PdfReader

#logger = logging.getLogger(__name__)

COLORS = ["#FF6B6B", "#4ECDC4", "#FFD93D", "#6C5CE7",
          "#FF9F43", "#1DD1A1", "#54A0FF", "#F368E0"]

PROMPT = """You are an expert teaching assistant. Read the study content below and turn it into exactly 9 flashcards that help a student revise.

Rules:
- Return ONLY a valid JSON array. No markdown, no code fences, no text before or after the array.
- The array must contain exactly 9 items.
- Each item has exactly two keys: "title" and "content".
- "title": a short heading, maximum 6 words.
- "content": a detailed explanation of 5 to 8 sentences (about 80 to 120 words). Give the key definition, explain how it works or why it matters, and add a concrete example when the content provides one.
- Each card must cover a different important topic. Do not repeat the same point in two cards.
- Every card must make sense on its own, without the other cards.
- Use only information from the content. Do not invent facts.
- Write in the same language as the content.
- Inside the strings use plain text only: no bullet points, no line breaks, no markdown."""


class LLMError(Exception):
    """Raised when the model server could not produce any flashcards."""


def _endpoint():
      """Fetch the endpoint directly from Django settings."""
    # 👈 FIXED: Reading directly from settings.py config dictionary
      return settings.MODEL_API_CONFIG["ENDPOINT_URL"]


def extract_pdf_text(path):
    reader = PdfReader(path)
    return "\n".join((page.extract_text() or "") for page in reader.pages)


def chunk_text(text, size=6000):
    return [text[i:i + size] for i in range(0, len(text), size) if text[i:i + size].strip()]


def call_llm(prompt):
    response = requests.post(
        _endpoint(),
        json={
            "model": settings.MODEL_API_CONFIG["MODEL_NAME"],
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.2,
        },
        timeout=settings.MODEL_API_CONFIG["TIMEOUT"],
    )
    response.raise_for_status()
    return response.json()["choices"][0]["message"]["content"]

# ... keep parse_cards and generate_flashcards functions here ...

def parse_cards(raw):
    match = re.search(r"\[.*\]", raw, re.S)
    if not match:
        return []
    try:
        data = json.loads(match.group(0))
    except json.JSONDecodeError:
        return []
    return [c for c in data if isinstance(c, dict) and c.get("title") and c.get("content")]


def generate_flashcards(text):
    cards, seen, errors = [], set(), []

    for chunk in chunk_text(text):
        try:
            new_cards = parse_cards(call_llm(PROMPT + chunk))
        except (requests.RequestException, KeyError, ValueError) as exc:
            # One failed chunk should not lose the cards from the other chunks.
            #logger.warning("Flashcard generation failed for a chunk: %s", exc)
            errors.append(str(exc))
            continue

        for card in new_cards:
            key = card["title"].strip().lower()
            if key not in seen:
                seen.add(key)
                cards.append(card)

    if not cards and errors:
        raise LLMError(errors[0])

    return cards