from bs4 import BeautifulSoup
import requests
import re


class QuizParser:
    """
    Parser for extracting questions from HTML content
    """

    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        })

    def extract_questions(self, html_content):
        """Extract questions and options from HTML content"""
        soup = BeautifulSoup(html_content, 'html.parser')
        questions = []

        # Common patterns for quiz questions
        question_patterns = [
            # Multiple choice questions
            soup.find_all('div', class_=re.compile(r'question|quiz-item|mcq')),
            # Questions in list items
            soup.find_all('li', string=re.compile(r'.*\?.*')),
            # Direct question text
            soup.find_all(string=re.compile(r'.*\?.*'))
        ]

        for pattern in question_patterns:
            for element in pattern:
                question_data = self._parse_question_element(element)
                if question_data:
                    questions.append(question_data)

        return questions

    def _parse_question_element(self, element):
        """Parse individual question element"""
        try:
            question_text = self._extract_question_text(element)
            options = self._extract_options(element)

            if question_text:
                return {
                    'question': question_text,
                    'options': options,
                    'type': 'multiple_choice' if len(options) > 1 else 'open_ended'
                }
        except Exception as e:
            print(f"Error parsing question: {e}")
            return None

    def _extract_question_text(self, element):
        """Extract clean question text"""
        if hasattr(element, 'text'):
            text = element.text
        else:
            text = str(element)

        # Clean the text
        text = re.sub(r'\s+', ' ', text).strip()
        # Extract text before question mark
        match = re.search(r'([^.?]*\?)', text)
        if match:
            return match.group(1).strip()
        return text[:200]  # Return first 200 chars if no question mark

    def _extract_options(self, element):
        """Extract answer options - FIXED VERSION"""
        options = []

        if hasattr(element, 'text'):
            text = element.text

            # FIXED: Better regex patterns for options
            # Pattern for A) Option 1, B) Option 2 format
            option_patterns = [
                # Match A) Paris B) London etc. - improved pattern
                r'([A-D])\)\s*([^A-D)\n]+)(?=[A-D]\)|$)',
                # Match 1. Option 2. Option etc.
                r'(\d+)\.\s*([^\d.\n]+)(?=\d+\.|$)',
            ]

            for pattern in option_patterns:
                matches = re.findall(pattern, text)
                for match in matches:
                    if len(match) == 2:
                        option_text = match[1].strip()
                        # Only add if we have meaningful text
                        if len(option_text) > 1:
                            options.append(f"{match[0]}) {option_text}")

            # Alternative: Split by common option separators
            if not options:
                # Look for patterns like "A. Paris B. London" etc.
                alt_pattern = r'([A-D][.)]\s*[^A-D]+)'
                alt_matches = re.findall(alt_pattern, text)
                options.extend([match.strip() for match in alt_matches])

        return options[:10]  # Limit to 10 options

    def _extract_options_alternative(self, element):
        """Alternative method for extracting options - more robust"""
        options = []

        if hasattr(element, 'text'):
            text = element.text

            # Method 1: Split by common option patterns
            import re
            # Split text by option starters (A), B), 1., 2., etc.)
            parts = re.split(r'(?=[A-D]\)|\d+\.)', text)

            for part in parts[1:]:  # Skip first part (usually the question)
                part = part.strip()
                if part and len(part) > 2:  # Minimum meaningful option length
                    # Clean up the option
                    option = re.sub(r'^\s*([A-D]\)|\d+\.)\s*', r'\1 ', part)
                    options.append(option.strip())

        return options[:10]