"""
Cognition Simulator v1.0 - World Class Expertise
Generates realistic aggregated metrics for cognition tests based on student profiles.
"""
import random
import pandas as pd
from typing import Dict, List, Any
 
class CognitionSimulator:
    def __init__(self):
        pass

    def simulate_student_test(self, student: Dict, test_name: str, age_group: str) -> Dict:
        """
        Simulates aggregated metrics for a specific student and test.
        """
        # Baseline performance from student profile (Cognitive Overall score if available, or random 6-9)
        # Using numeric scores from 3000-students.xlsx if possible, otherwise random high-quality baseline.
        # Note: 3000-students.xlsx has: Openness, Conscientiousness, etc.
        # We can derive baseline from Conscientiousness (diligence) and Openness (curiosity/speed).
        
        conscientiousness = student.get('Conscientiousness Score', 70) / 10.0
        openness = student.get('Openness Score', 70) / 10.0
        
        baseline_accuracy = (conscientiousness * 0.6 + openness * 0.4) / 10.0 # 0.0 to 1.0
        # Add random variation
        accuracy = min(max(baseline_accuracy + random.uniform(-0.1, 0.15), 0.6), 0.98)
        rt_baseline = 1500 - (accuracy * 500) # Faster accuracy usually means faster RT in these tests
        
        participant = f"{student.get('First Name', '')} {student.get('Last Name', '')}".strip()
        cpid = student.get('StudentCPID', 'UNKNOWN')
        
        # Test specific logic
        if 'Problem_Solving' in test_name or 'Reasoning' in test_name:
            total_rounds = 26 if age_group == '14-17' else 31
            correct = int(total_rounds * accuracy)
            incorrect = total_rounds - correct
            
            if 'SBDM' in test_name: # Special schema
                return {
                    "Participant": participant,
                    "Student CPID": cpid,
                    "Total Rounds Answered": total_rounds,
                    "Total Rounds not Answered": int(0),
                    "Overall C_score": int(correct * 2),
                    "Overall N_score": int(incorrect),
                    "Overall I_Score": int(random.randint(5, 15)),
                    "Average C_Score": float(round((correct * 2.0) / total_rounds, 2)),
                    "Average N_Score": float(round(float(incorrect) / total_rounds, 2)),
                    "Average I_Score": float(round(random.uniform(0.5, 1.5), 2)),
                    "Average Reaction Time for the task": float(round(float(rt_baseline) + random.uniform(-100, 200), 2))
                }
            
            return {
                "Participant": participant,
                "Student CPID": cpid,
                "Total Rounds Answered": total_rounds,
                "Total Rounds not Answered": 0,
                "No. of Correct Responses": correct,
                "No. of Incorrect Responses": incorrect,
                "Total Score of the Task": correct,
                "Average Reaction Time": float(round(float(rt_baseline + random.uniform(-100, 300)), 2))
            }

        elif 'Cognitive_Flexibility' in test_name:
            total_rounds = 72
            correct = int(total_rounds * accuracy)
            incorrect = total_rounds - correct
            return {
                "Participant": participant,
                "Student CPID": cpid,
                "Total Rounds Answered": total_rounds,
                "Total Rounds not Answered": 0,
                "No. of Correct Responses": correct,
                "No. of Incorrect Responses": incorrect,
                "Total Score of the Task": correct,
                "Average Reaction Time": float(round(float(rt_baseline * 0.8), 2)),
                "No. of Reversal Errors": int(random.randint(2, 8)),
                "No. of Perseveratory errors": int(random.randint(1, 5)),
                "No.of Final Reversal Errors": int(random.randint(1, 3)),
                "Win-Shift rate": float(round(float(random.uniform(0.7, 0.95)), 2)),
                "Lose-Shift Rate": float(round(float(random.uniform(0.1, 0.3)), 2)),
                "Overall Accuracy": float(round(float(accuracy * 100.0), 2))
            }

        elif 'Color_Stroop' in test_name:
            total_rounds = 80
            congruent_acc = accuracy + 0.05
            incongruent_acc = accuracy - 0.1
            return {
                "Participant": participant,
                "Student CPID": cpid,
                "Total Rounds Answered": total_rounds,
                "Total Rounds not Answered": 0,
                "No. of Correct Responses": int(total_rounds * accuracy),
                "No. of Correct Responses in Congruent Rounds": int(40 * congruent_acc),
                "No. of Correct Responses in Incongruent Rounds": int(40 * incongruent_acc),
                "No. of Incorrect Responses": int(total_rounds * (1-accuracy)),
                "No. of Incorrect Responses in Congruent Rounds": int(40 * (1-congruent_acc)),
                "No. of Incorrect Responses in Incongruent Rounds": int(40 * (1-incongruent_acc)),
                "Total Score of the Task": int(total_rounds * accuracy),
                "Congruent Rounds Average Reaction Time": float(round(float(rt_baseline * 0.7), 2)),
                "Incongruent Rounds Average Reaction Time": float(round(float(rt_baseline * 1.2), 2)),
                "Average Reaction Time of the task": float(round(float(rt_baseline), 2)),
                "Congruent Rounds Accuracy": float(round(float(congruent_acc * 100.0), 2)),
                "Incongruent Rounds Accuracy": float(round(float(incongruent_acc * 100.0), 2)),
                "Overall Task Accuracy": float(round(float(accuracy * 100.0), 2)),
                "Interference Effect": float(round(float(rt_baseline * 0.5), 2))
            }

        elif 'Sternberg' in test_name:
            total_rounds = 120
            correct = int(total_rounds * accuracy)
            return {
                "Participant": participant,
                "Student CPID": cpid,
                "Total Rounds Answered": total_rounds,
                "Total Rounds not Answered": 0,
                "No. of Correct Responses": correct,
                "No. of Incorrect Responses": total_rounds - correct,
                "Total Score of the Task": correct,
                "Average Reaction Time for Positive Probes": float(round(float(rt_baseline * 1.1), 2)),
                "Average Reaction Time for Negative Probes": float(round(float(rt_baseline * 1.15), 2)),
                "Average Reaction Time": float(round(float(rt_baseline * 1.12), 2)),
                "Overall Accuracy": float(round(float(accuracy * 100.0), 2)),
                "Hit Rate": float(round(float(accuracy + 0.02), 2)),
                "False Alarm Rate": float(round(float(random.uniform(0.05, 0.15)), 2)),
                "Slope of RT vs Set Size": float(round(float(random.uniform(30.0, 60.0)), 2)),
                "Response Bias": float(round(float(random.uniform(-0.5, 0.5)), 2)),
                "Sensitivity (d')": float(round(float(random.uniform(1.5, 3.5)), 2))
            }

        elif 'Visual_Paired' in test_name:
            total_rounds = 45
            correct = int(total_rounds * accuracy)
            return {
                "Participant": participant,
                "Student CPID": cpid,
                "Total Rounds Answered": total_rounds,
                "Total Rounds not Answered": 0,
                "No. of Correct Responses": correct,
                "No. of Incorrect Responses": total_rounds - correct,
                "Total Score in Immediate Cued Recall test": int(random.randint(10, 15)),
                "Total Score in Delayed Cued Recall test": int(random.randint(8, 14)),
                "Total Score in Recognition test": int(random.randint(12, 15)),
                "Total Score of the Task": int(correct),
                "Immediate Cued Recall Average Reaction Time": float(round(float(rt_baseline * 1.5), 2)),
                "Delayed Cued Recall Average Reaction Time": float(round(float(rt_baseline * 1.6), 2)),
                "Recognition Phase Average Reaction time": float(round(float(rt_baseline * 1.2), 2)),
                "Average Reaction Time": float(round(float(rt_baseline * 1.4), 2)),
                "Immediate Cued Recall Accuracy Rate": float(round(float(accuracy * 100.0), 2)),
                "Delayed Cued Recall Accuracy Rate": float(round(float((accuracy - 0.05) * 100.0), 2)),
                "Recognition Phase Accuracy Rate": float(round(float((accuracy + 0.05) * 100.0), 2)),
                "Overall Accuracy Rate": float(round(float(accuracy * 100.0), 2)),
                "Consolidation Slope": float(round(float(random.uniform(-0.5, 0.1)), 2)),
                "Consolidation Slope (%)": float(round(float(random.uniform(-10.0, 5.0)), 2))
            }
            
        elif 'Response_Inhibition' in test_name:
            total_rounds = 60
            correct = int(total_rounds * accuracy)
            return {
                "Participant": participant,
                "Student CPID": cpid,
                "Total Rounds Answered": total_rounds,
                "Total Rounds not Answered": 0,
                "No. of Correct Responses": correct,
                "No. of Correct Responses in Go Rounds": int(40 * accuracy),
                "No. of Correct Responses in No-Go Rounds": int(20 * (accuracy - 0.1)),
                "No. of Incorrect Responses": total_rounds - correct,
                "No. of Incorrect Responses in Go Rounds": int(40 * (1-accuracy)),
                "No. of Incorrect Responses in No-Go Rounds": int(20 * (1-(accuracy-0.1))),
                "Total Score of the Task": correct,
                "Go Rounds Average Reaction Time": float(round(float(rt_baseline * 0.8), 2)),
                "No- Rounds Average Reaction Time": float(round(float(rt_baseline * 1.2), 2)),
                "Average Reaction Time of the task": float(round(float(rt_baseline), 2)),
                "Go Rounds Accuracy": float(round(float(accuracy * 100.0), 2)),
                "No-Go Rounds Accuracy": float(round(float((accuracy - 0.1) * 100.0), 2)),
                "Overall Task Accuracy": float(round(float(accuracy * 100.0), 2)),
                "No. of Commission Errors": int(random.randint(2, 10)),
                "No. of Omission Error": int(random.randint(1, 5)),
                "Omission Error Rate": float(round(float(random.uniform(0.01, 0.05)), 2)),
                "Hit Rate": float(round(float(accuracy), 2)),
                "False Alarm Rate": float(round(float(random.uniform(0.1, 0.3)), 2))
            }

        # Default fallback
        return {
            "Participant": participant,
            "Student CPID": cpid,
            "Total Rounds Answered": 0,
            "Total Score of the Task": 0
        }
