"""
Student Data Manager

Manages student data from Excel/CSV files to ensure correct data is used
for each student according to their creation records.

This prevents age verification modals by using the correct DOB that matches
the school records.
"""
import csv
import os
from pathlib import Path
from typing import Dict, Optional
from datetime import datetime, timedelta
from config.config import BASE_DIR


class StudentDataManager:
    """
    Manages student data from CSV/Excel files.
    
    Ensures correct data is used for each student according to their creation records,
    preventing age verification modals and other data mismatches.
    """
    
    _instance: Optional['StudentDataManager'] = None
    _students: Dict[str, Dict] = {}  # CPID -> student data
    _data_file: Optional[Path] = None
    
    def __new__(cls):
        """Singleton pattern"""
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def load_students_from_csv(self, csv_file_path: Optional[str] = None):
        """
        Load student data from CSV file.
        
        Args:
            csv_file_path: Path to CSV file. If None, searches for latest CSV in project root.
        """
        if csv_file_path is None:
            # Find latest CSV file in project root
            csv_files = list(BASE_DIR.glob("students_with_passwords_*.csv"))
            if not csv_files:
                raise FileNotFoundError("No student CSV file found. Expected: students_with_passwords_*.csv")
            csv_file_path = max(csv_files, key=lambda p: p.stat().st_mtime)
            print(f"📋 Using latest CSV file: {csv_file_path.name}")
        
        csv_path = Path(csv_file_path)
        if not csv_path.exists():
            raise FileNotFoundError(f"CSV file not found: {csv_path}")
        
        self._data_file = csv_path
        self._students.clear()
        
        with open(csv_path, 'r', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            for row in reader:
                cpid = row.get('Student CPID', '').strip()
                if not cpid:
                    continue
                
                # Extract all relevant data
                student_data = {
                    'cpid': cpid,
                    'password': row.get('Password', '').strip(),
                    'first_name': row.get('First Name', '').strip(),
                    'last_name': row.get('Last Name', '').strip(),
                    'gender': row.get('Gender', '').strip(),
                    'age': self._parse_age(row.get('Age', '').strip()),
                    'email': row.get('Email', '').strip(),
                    'phone': row.get('Phone Number', '').strip(),
                    'nationality': row.get('Nationality', '').strip(),
                    'native_state': row.get('Native', '').strip(),
                    'language': row.get('Language', '').strip(),
                    'address': row.get('Address line 1', '').strip(),
                    'city': row.get('City', '').strip(),
                    'state': row.get('State', '').strip(),
                    'pin_code': row.get('Pin code', '').strip(),
                    'father_name': row.get('Father Full Name', '').strip(),
                    'father_phone': row.get('Number', '').strip(),  # First Number column
                    'father_occupation': row.get('Occupation', '').strip(),  # First Occupation
                    'father_email': row.get('Email', '').strip(),  # First Email
                    'mother_name': row.get('Mother Full Name', '').strip(),
                    'current_grade': row.get('Current Grade', '').strip(),
                    'section': row.get('Section/ Course', '').strip(),
                    'roll_number': row.get('Roll Number', '').strip(),
                    'institution_name': row.get('Institution Name', '').strip(),
                    'board_stream': row.get('Affiliation', '').strip(),  # ICSE, CBSE, etc.
                }
                
                # Calculate DOB from age (to match school records)
                student_data['dob'] = self._calculate_dob_from_age(student_data['age'])
                
                self._students[cpid] = student_data
                print(f"✅ Loaded student data: {cpid} (Age: {student_data['age']}, DOB: {student_data['dob']})")
        
        print(f"✅ Loaded {len(self._students)} students from {csv_path.name}")
    
    def _parse_age(self, age_str: str) -> int:
        """Parse age string to integer"""
        try:
            return int(age_str.strip())
        except (ValueError, AttributeError):
            return 16  # Default age
    
    def _calculate_dob_from_age(self, age: int) -> str:
        """
        Calculate DOB from age to match school records.
        
        Uses current date minus age to get approximate DOB.
        This ensures the DOB matches the age in school records.
        
        Args:
            age: Student age from school records
            
        Returns:
            str: DOB in format YYYY-MM-DD
        """
        today = datetime.now()
        # Calculate birth year (approximately)
        birth_year = today.year - age
        # Use January 1st as default date (can be adjusted if needed)
        dob = datetime(birth_year, 1, 15)
        return dob.strftime("%Y-%m-%d")
    
    def get_student_data(self, cpid: str) -> Optional[Dict]:
        """
        Get student data by CPID.
        
        Args:
            cpid: Student CPID
            
        Returns:
            Dict with student data or None if not found
        """
        # Auto-load if not loaded yet
        if not self._students:
            try:
                self.load_students_from_csv()
            except FileNotFoundError:
                print(f"⚠️  No student data file found. Cannot get data for {cpid}")
                return None
        
        return self._students.get(cpid)
    
    def get_dob_for_student(self, cpid: str) -> Optional[str]:
        """
        Get correct DOB for student that matches school records.
        
        Args:
            cpid: Student CPID
            
        Returns:
            DOB string (YYYY-MM-DD) or None if not found
        """
        student_data = self.get_student_data(cpid)
        if student_data:
            return student_data.get('dob')
        return None
    
    def get_age_for_student(self, cpid: str) -> Optional[int]:
        """
        Get age for student from school records.
        
        Args:
            cpid: Student CPID
            
        Returns:
            Age as integer or None if not found
        """
        student_data = self.get_student_data(cpid)
        if student_data:
            return student_data.get('age')
        return None
    
    def get_all_student_data(self, cpid: str) -> Optional[Dict]:
        """
        Get all student data for a given CPID.
        
        Args:
            cpid: Student CPID
            
        Returns:
            Dict with all student data or None if not found
        """
        return self.get_student_data(cpid)


# Global instance
student_data_manager = StudentDataManager()


