"""
Questionnaire generation module using LLM APIs.
"""

import re

# Handle imports for both running from src and from parent directory
try:
    from model_loader import get_llm_client
    from config import (
        LLM_MAX_TOKENS,
        LLM_TEMPERATURE,
        LLM_TOP_P,
        NUM_QUESTIONS,
        MCQ_PERCENTAGE,
        SUBJECTIVE_PERCENTAGE,
        EASY_PERCENTAGE,
        MEDIUM_PERCENTAGE,
        HARD_PERCENTAGE,
        SCENARIO_PERCENTAGE,
        THEORETICAL_PERCENTAGE
    )
except ImportError:
    from .model_loader import get_llm_client
    from .config import (
        LLM_MAX_TOKENS,
        LLM_TEMPERATURE,
        LLM_TOP_P,
        NUM_QUESTIONS,
        MCQ_PERCENTAGE,
        SUBJECTIVE_PERCENTAGE,
        EASY_PERCENTAGE,
        MEDIUM_PERCENTAGE,
        HARD_PERCENTAGE,
        SCENARIO_PERCENTAGE,
        THEORETICAL_PERCENTAGE
    )


def calculate_question_distribution():
    """
    Calculate the number of each type of question based on configuration.
    
    Returns:
        dict: Distribution of questions by type, difficulty, and style
    """
    # Calculate MCQ vs Subjective
    num_mcq = int(NUM_QUESTIONS * MCQ_PERCENTAGE / 100)
    num_subjective = NUM_QUESTIONS - num_mcq
    
    # Calculate difficulty distribution
    num_easy = int(NUM_QUESTIONS * EASY_PERCENTAGE / 100)
    num_medium = int(NUM_QUESTIONS * MEDIUM_PERCENTAGE / 100)
    num_hard = NUM_QUESTIONS - num_easy - num_medium
    
    # Calculate style distribution (for subjective questions mainly)
    num_scenario = int(num_subjective * SCENARIO_PERCENTAGE / 100)
    num_theoretical = num_subjective - num_scenario
    
    # Distribute MCQ across difficulties
    mcq_easy = int(num_mcq * EASY_PERCENTAGE / 100)
    mcq_medium = int(num_mcq * MEDIUM_PERCENTAGE / 100)
    mcq_hard = num_mcq - mcq_easy - mcq_medium
    
    # Distribute subjective across difficulties
    subj_easy = num_easy - mcq_easy
    subj_medium = num_medium - mcq_medium
    subj_hard = num_hard - mcq_hard
    
    return {
        'total': NUM_QUESTIONS,
        'mcq': {
            'total': num_mcq,
            'easy': max(0, mcq_easy),
            'medium': max(0, mcq_medium),
            'hard': max(0, mcq_hard)
        },
        'subjective': {
            'total': num_subjective,
            'easy': max(0, subj_easy),
            'medium': max(0, subj_medium),
            'hard': max(0, subj_hard),
            'scenario': num_scenario,
            'theoretical': num_theoretical
        }
    }


def build_questionnaire_prompt(summary):
    """
    Build a dynamic questionnaire generation prompt based on configuration.
    
    Args:
        summary (str): Summarized content
        
    Returns:
        tuple: (system_prompt, user_prompt)
    """
    dist = calculate_question_distribution()
    
    # Build system prompt with dynamic requirements
    system_prompt = f"""You are a professional educational content creator specialized in generating diverse, high-quality questionnaires.

Generate exactly {dist['total']} questions based on the provided content with the following distribution:

**MULTIPLE-CHOICE QUESTIONS ({dist['mcq']['total']} questions, {MCQ_PERCENTAGE}% of total):**

**SUBJECTIVE QUESTIONS ({dist['subjective']['total']} questions, {SUBJECTIVE_PERCENTAGE}% of total):**

**QUESTION STYLE REQUIREMENTS:**
- {SCENARIO_PERCENTAGE}% of subjective questions should be REAL-WORLD SCENARIO-BASED (practical application)
- {THEORETICAL_PERCENTAGE}% of subjective questions should be THEORETICAL/CONCEPT-BASED (pure theory)

**FORMATTING REQUIREMENTS:**
1. Start with "Multiple-Choice Questions" section
2. Number each question clearly (e.g., 1., 2., 3.)
3. For MCQs: Provide exactly 4 options labeled (a), (b), (c), (d)
4. Follow with "Subjective Questions" section

**TEXT FORMATTING RULES (CRITICAL):**
- Use ONLY plain ASCII text - absolutely NO special characters or symbols
- NO Unicode characters, NO LaTeX, NO fancy markdown formatting
- Use only letters (a-z, A-Z), numbers (0-9), and basic punctuation (.,!?;:)
- Do NOT make use of special characters like em-dashes (—), en-dashes (–), bullet points (•), or any other non-standard symbols
- Use straight quotes (") and apostrophes (') NOT curly/smart quotes (' " " ')
- Use three dots (...) NOT ellipsis character (…)
- Write everything in simple, plain English text
- Avoid any symbols that aren't on a standard US keyboard

**IMPORTANT:**
- Stick strictly to the provided content - no external information
- Ensure questions test different aspects of the content
- Make scenario questions realistic and practical
- Make theoretical questions probe deep understanding
- Questions should be clear, unambiguous, and grammatically correct
- Keep formatting simple and clean for PDF conversion"""

    user_prompt = f"""Generate a well-structured questionnaire with exactly {dist['total']} questions based on the following content:

Content:
"{summary}"

Remember to follow the exact distribution specified:
- {dist['mcq']['total']} Multiple-Choice Questions ({MCQ_PERCENTAGE}%)
- {dist['subjective']['total']} Subjective Questions ({SUBJECTIVE_PERCENTAGE}%)

Difficulty split: {EASY_PERCENTAGE}% Easy, {MEDIUM_PERCENTAGE}% Medium, {HARD_PERCENTAGE}% Hard
Style split (for subjective): {SCENARIO_PERCENTAGE}% Scenario-based, {THEORETICAL_PERCENTAGE}% Theoretical

CRITICAL: Use ONLY plain ASCII text with standard keyboard characters. 
- Use regular hyphens (-) NOT fancy dashes
- Use straight quotes (") NOT smart quotes
- Use three dots (...) NOT ellipsis
Keep it simple and clean."""

    return system_prompt, user_prompt


def generate_questionnaire(summary):
    """
    Generates a structured questionnaire based on the provided summary using API-based LLMs.
    
    Args:
        summary (str): Summarized content to generate questions from
        
    Returns:
        str: Generated and cleaned questionnaire
    """
    print(f"\nGenerating questionnaire with parameters:")
    print(f"  Total questions: {NUM_QUESTIONS}")
    print(f"  MCQ: {MCQ_PERCENTAGE}% | Subjective: {SUBJECTIVE_PERCENTAGE}%")
    print(f"  Difficulty: Easy {EASY_PERCENTAGE}% | Medium {MEDIUM_PERCENTAGE}% | Hard {HARD_PERCENTAGE}%")
    print(f"  Style: Scenario {SCENARIO_PERCENTAGE}% | Theoretical {THEORETICAL_PERCENTAGE}%")
    print()
    
    system_prompt, user_prompt = build_questionnaire_prompt(summary)
    client, model_name, provider = get_llm_client()
    print(f"DEBUG: Using provider={provider}, model={model_name}")
    print(f"DEBUG: System prompt length: {len(system_prompt)} chars")
    print(f"DEBUG: User prompt length: {len(user_prompt)} chars")

    try:
        if provider == "mistral":
            # Mistral API format
            print(f"DEBUG: Calling Mistral API...")
            response = client.chat.complete(
                model=model_name,
                messages=[
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": user_prompt}
                ],
                temperature=LLM_TEMPERATURE,
                top_p=LLM_TOP_P,
                max_tokens=LLM_MAX_TOKENS
            )
            print(f"DEBUG: Mistral response object: {response}")
            output_text = response.choices[0].message.content
        else:
            # OpenAI and Groq use the same format
            print(f"DEBUG: Calling {provider} API...")
            response = client.chat.completions.create(
                model=model_name,
                messages=[
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": user_prompt}
                ],
                temperature=LLM_TEMPERATURE,
                top_p=LLM_TOP_P,
                max_tokens=LLM_MAX_TOKENS
            )
            print(f"DEBUG: API response received")
            #print(f"DEBUG: Response object: {response}")
            output_text = response.choices[0].message.content
            #print(f"DEBUG: Extracted content length: {len(output_text) if output_text else 0}")
        
        # Debug: Check what we got from LLM
        print(f"DEBUG: LLM output length: {len(output_text) if output_text else 0}")
        if not output_text or len(output_text) == 0:
            print("WARNING: LLM returned empty response!")
            #print(f"DEBUG: Full response object: {response}")
            return ""
        
        print("Questionnaire generation completed.")
        return output_text
    
    except Exception as e:
        print(f"Error generating questionnaire: {e}")
        raise
