def add_student(df, new_student_data):
    """
    Add a new student to the master data
    
    new_student_data should be a dict with keys matching column names
    Example:
    {
        'Admission_No': '2024001',
        'Name': 'Rahul Kumar',
        'Father_Name': 'Ramesh Kumar',
        'Class': '10',
        'Gender': 'Male',
        ...
    }
    """
    df = df.append(new_student_data, ignore_index=True)
    return df


def update_student(df, admission_no, update_dict):
    """
    Update existing student record
    
    admission_no: The admission number of student to update
    update_dict: Dictionary of fields to update
    """
    mask = df['Admission_No'] == admission_no
    if mask.any():
        for key, value in update_dict.items():
            if key in df.columns:
                df.loc[mask, key] = value
        return df, True
    return df, False


def find_student(df, search_by, value):
    """
    Search for students by various fields
    
    search_by: column name (Name, Admission_No, Mobile_No, etc.)
    value: value to search
    """
    if search_by in df.columns:
        results = df[df[search_by].astype(str).str.contains(str(value), case=False, na=False)]
        return results
    return pd.DataFrame()


def merge_duplicates(df, key_columns=['Admission_No', 'Name']):
    """
    Find and merge duplicate student records
    """
    duplicates = df[df.duplicated(subset=key_columns, keep=False)]
    if not duplicates.empty:
        print(f"Found {len(duplicates)} potential duplicate records")
        # Show duplicates for manual review
        return duplicates.sort_values(by=key_columns)
    return pd.DataFrame()


def validate_data(df):
    """
    Check for common data issues
    Returns a report dict
    """
    report = {
        'missing_names': df[df['Name'].isna()].shape[0],
        'missing_admission': df[df['Admission_No'].isna()].shape[0],
        'duplicate_admission': df[df.duplicated('Admission_No')].shape[0],
        'invalid_dobs': 0,  # Add validation logic
        'total_records': len(df)
    }
    return report


def export_to_csv(df, folder_path):
    """Export to CSV with timestamp"""
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    csv_path = os.path.join(folder_path, f'student_data_{timestamp}.csv')
    df.to_csv(csv_path, index=False, encoding='utf-8')
    return csv_path


def export_to_excel_multi(df, folder_path):
    """Export to Excel with multiple analysis sheets"""
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    excel_path = os.path.join(folder_path, f'analysis_{timestamp}.xlsx')

    with pd.ExcelWriter(excel_path, engine='openpyxl') as writer:
        # All data
        df.to_excel(writer, sheet_name='All_Students', index=False)

        # Class-wise summary
        if 'Class' in df.columns:
            class_summary = df.groupby('Class').agg({
                'Name': 'count',
                'Admission_No': 'nunique'
            }).rename(columns={'Name': 'Total_Students', 'Admission_No': 'Unique_Admissions'})
            class_summary.to_excel(writer, sheet_name='Class_Summary')

        # Gender-wise distribution
        if 'Gender' in df.columns:
            gender_summary = df['Gender'].value_counts().to_frame()
            gender_summary.to_excel(writer, sheet_name='Gender_Summary')

        # Issues/Problems sheet
        issues = []
        if df['Name'].isna().any():
            issues.append("Missing names found")
        if df['Admission_No'].isna().any():
            issues.append("Missing admission numbers")
        if df.duplicated('Admission_No').any():
            issues.append("Duplicate admission numbers")
        
        issues_df = pd.DataFrame({'Issues': issues})
        issues_df.to_excel(writer, sheet_name='Issues_Found', index=False)

    return excel_path


def backup_excel(filepath):
    """Create backup of Excel file"""
    backup_path = filepath.replace('.xlsx', f'_backup_{datetime.now().strftime("%Y%m%d")}.xlsx')
    import shutil
    shutil.copy2(filepath, backup_path)
    return backup_path


def undo_last_change(log_file='changes_log.csv'):
    """
    Undo last change using action log
    (Requires logging all changes in a separate file)
    """
    # Implementation: Read last action from log and reverse it
    pass


def generate_student_id(df, prefix="STU"):
    """Generate unique student IDs for records without Admission_No"""
    existing_ids = set(df['Admission_No'].dropna().astype(str))
    new_ids = []
    counter = 1
    for idx in df[df['Admission_No'].isna()].index:
        while f"{prefix}{counter:04d}" in existing_ids:
            counter += 1
        new_id = f"{prefix}{counter:04d}"
        new_ids.append((idx, new_id))
        existing_ids.add(new_id)
        counter += 1
    return new_ids


def split_by_class(df, class_column='Class'):
    """Split master data into separate files by class"""
    class_files = {}
    if class_column in df.columns:
        for class_val in df[class_column].unique():
            class_df = df[df[class_column] == class_val]
            safe_name = str(class_val).replace('/', '_').replace('\\', '_')
            filename = f'Class_{safe_name}.xlsx'
            class_df.to_excel(os.path.join(DEFAULT_DOWNLOAD_DIR, filename), index=False)
            class_files[class_val] = filename
    return class_files
