from typing import TypedDict, Dict, Any

from datetime import datetime

from repenseai.genai.benchmark.core.base_evaluator import BaseEvaluator

class EvaluationResult(TypedDict):
    question_number: int
    is_correct: bool
    given_answer: str
    correct_answer: str
    confidence: float

class OptionQuestionEvaluator(BaseEvaluator):
    def __init__(self, name: str):
        super().__init__(name)
        self.total_questions = 0
        self.correct_answers = 0

    async def evaluate(self, test_results: Dict[str, Any]) -> Dict[str, Any]:
        if test_results.get('test_type') != 'options_exam':
            raise ValueError("Invalid test type for OptionsEvaluator")
            
        evaluation = []

        self.total_questions = len(test_results['results'])
        self.correct_answers = 0

        for result in test_results['results']:
            try:
                evaluation_result = self._evaluate_single_answer(result)
                evaluation.append(evaluation_result)
                if evaluation_result['is_correct']:
                    self.correct_answers += 1
            except Exception as e:
                evaluation.append({
                    'question_number': result['question_number'],
                    'error': str(e),
                    'is_correct': False
                })

        return {
            'evaluation_details': evaluation,
            'total_questions': self.total_questions,
            'correct_answers': self.correct_answers,
            'accuracy': self.get_score(),
            'metadata': {
                'evaluator_name': self.name,
                'evaluation_timestamp': datetime.now().isoformat()
            }
        }

    def _evaluate_single_answer(self, result: Dict[str, Any]) -> EvaluationResult:

        agent_answer = result['agent_answer'].strip().upper()[0]
        correct_answer = result['correct_answer'].strip().upper()[0]
        
        return {
            'question_number': result['question_number'],
            'is_correct': agent_answer == correct_answer,
            'given_answer': agent_answer,
            'correct_answer': correct_answer,
            'confidence': 1.0
        }

    def get_score(self) -> float:
        return self.correct_answers / self.total_questions if self.total_questions > 0 else 0.0