from pathlib import Path
import PyPDF2
from typing import Dict, List, Optional
from pydantic import BaseModel
from modules.pdf_utils import PDFUtils

class TestAnalysis(BaseModel):
    overall_score: float
    section_scores: Dict[str, float]
    feedback: str
    recommendations: List[str]
    detailed_analysis: Optional[Dict] = None

class TestAnalyzer:
    def __init__(self, api_key: str):
        self.api_key = api_key

    def extract_text_from_pdf(self, pdf_file: Path) -> str:
        """
        Extract text content from a PDF file
        """
        if not pdf_file.exists():
            raise FileNotFoundError(f"PDF file not found: {pdf_file}")

        text = ""
        with open(pdf_file, 'rb') as file:
            pdf_reader = PyPDF2.PdfReader(file)
            for page in pdf_reader.pages:
                text += page.extract_text() + "\n"

        return text

    def analyze_test(self, pdf_content: str, marks_data: Dict, mode: str = 'detailed') -> TestAnalysis:
        """
        Analyze a test and generate feedback based on marks data
        """
        # Calculate overall score
        total_marks = sum(marks_data.values())
        max_marks = len(marks_data) * 100  # Assuming each question is out of 100
        overall_score = (total_marks / max_marks) * 100

        # Calculate section scores (group by first part of question number)
        section_scores = {}
        for question, marks in marks_data.items():
            section = question.split('.')[0]
            if section not in section_scores:
                section_scores[section] = []
            section_scores[section].append(marks)

        # Calculate average for each section
        for section, marks in section_scores.items():
            section_scores[section] = sum(marks) / len(marks)

        # Generate feedback
        feedback = self._generate_feedback(overall_score, section_scores)
        
        # Generate recommendations
        recommendations = self._generate_recommendations(section_scores)

        # Create detailed analysis if requested
        detailed_analysis = None
        if mode == 'detailed':
            detailed_analysis = {
                'question_analysis': self._analyze_questions(pdf_content, marks_data),
                'strengths': self._identify_strengths(section_scores),
                'weaknesses': self._identify_weaknesses(section_scores)
            }

        return TestAnalysis(
            overall_score=overall_score,
            section_scores=section_scores,
            feedback=feedback,
            recommendations=recommendations,
            detailed_analysis=detailed_analysis
        )

    def _generate_feedback(self, overall_score: float, section_scores: Dict[str, float]) -> str:
        """
        Generate feedback based on overall score and section scores
        """
        if overall_score >= 90:
            return "Excellent performance! You have demonstrated a strong understanding of the material."
        elif overall_score >= 80:
            return "Very good performance. You have a solid grasp of most concepts."
        elif overall_score >= 70:
            return "Good performance. You understand the main concepts but could improve in some areas."
        elif overall_score >= 60:
            return "Satisfactory performance. You have a basic understanding but need to work on several areas."
        else:
            return "Needs improvement. Focus on understanding the fundamental concepts better."

    def _generate_recommendations(self, section_scores: Dict[str, float]) -> List[str]:
        """
        Generate recommendations based on section scores
        """
        recommendations = []
        for section, score in section_scores.items():
            if score < 70:
                recommendations.append(f"Focus on improving your understanding of Section {section}")
            elif score < 80:
                recommendations.append(f"Review Section {section} to strengthen your knowledge")
        
        if not recommendations:
            recommendations.append("Continue practicing to maintain your strong performance")
        
        return recommendations

    def _analyze_questions(self, pdf_content: str, marks_data: Dict) -> Dict:
        """
        Analyze individual questions
        """
        question_analysis = {}
        for question, marks in marks_data.items():
            question_analysis[question] = {
                'score': marks,
                'performance': 'excellent' if marks >= 90 else 'good' if marks >= 70 else 'needs_improvement'
            }
        return question_analysis

    def _identify_strengths(self, section_scores: Dict[str, float]) -> List[str]:
        """
        Identify strong sections
        """
        return [f"Section {section}" for section, score in section_scores.items() if score >= 80]

    def _identify_weaknesses(self, section_scores: Dict[str, float]) -> List[str]:
        """
        Identify weak sections
        """
        return [f"Section {section}" for section, score in section_scores.items() if score < 70] 