#!/usr/bin/env python3
"""
Systematic Student Processing Script

This script processes multiple students from an Excel file:
1. Reads student credentials from Excel
2. For each student:
   - Logs in
   - Handles password reset (sets to Admin@123)
   - Completes profile to 100%
   - Generates synthetic data report
3. Tracks progress and generates summary report
"""
import sys
import time
import json
from pathlib import Path
from datetime import datetime
import pandas as pd

project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from selenium.webdriver.common.by import By
from pages.login_page import LoginPage
from pages.mandatory_reset_page import MandatoryResetPage
from pages.profile_incomplete_page import ProfileIncompletePage
from pages.profile_editor_page import ProfileEditorPage
from utils.driver_manager import DriverManager
from config.config import ENVIRONMENT, BASE_URL, TEST_NEW_PASSWORD


class StudentProcessor:
    """Process students systematically"""
    
    def __init__(self, excel_path, headless=False):
        """
        Initialize Student Processor
        
        Args:
            excel_path: Path to Excel file with student data
            headless: Run browser in headless mode
        """
        self.excel_path = Path(excel_path)
        self.headless = headless
        self.results = []
        self.driver = None
        
    def load_students(self):
        """Load students from Excel file"""
        try:
            df = pd.read_excel(self.excel_path)
            print(f"✅ Loaded {len(df)} students from {self.excel_path}")
            return df.to_dict('records')
        except Exception as e:
            print(f"❌ Error loading Excel file: {e}")
            return []
    
    def process_student(self, student_data):
        """
        Process a single student
        
        Args:
            student_data: Dictionary with student information
            
        Returns:
            dict: Processing result
        """
        cpid = student_data.get('Student CPID', '')
        password = student_data.get('Password', '')
        first_name = student_data.get('First Name', '')
        last_name = student_data.get('Last Name', '')
        
        result = {
            'cpid': cpid,
            'first_name': first_name,
            'last_name': last_name,
            'status': 'pending',
            'error': None,
            'steps_completed': [],
            'timestamp': datetime.now().isoformat()
        }
        
        try:
            print(f"\n{'='*80}")
            print(f"Processing: {first_name} {last_name} ({cpid})")
            print(f"{'='*80}")
            
            # Initialize driver
            driver_manager = DriverManager()
            self.driver = driver_manager.get_driver(headless=self.headless)
            
            # Step 1: Login
            print("\n[STEP 1] Logging in...")
            login_page = LoginPage(self.driver)
            login_page.login(identifier=cpid, password=password)
            time.sleep(2)
            result['steps_completed'].append('login')
            
            # Step 2: Handle Password Reset
            print("\n[STEP 2] Checking for Password Reset...")
            reset_page = MandatoryResetPage(self.driver)
            if reset_page.is_modal_present():
                print("  ✅ Password reset modal found")
                print("  Automatically handling password reset...")
                reset_page.reset_password(
                    current_password=password,
                    new_password=TEST_NEW_PASSWORD,
                    confirm_password=TEST_NEW_PASSWORD
                )
                print("  ✅ Password reset completed")
                result['steps_completed'].append('password_reset')
                # Update password for future use
                password = TEST_NEW_PASSWORD
            else:
                print("  ✅ No password reset required")
            
            # Step 3: Handle Profile Incomplete Modal
            print("\n[STEP 3] Checking for Profile Incomplete Modal...")
            profile_incomplete = ProfileIncompletePage(self.driver)
            if profile_incomplete.is_modal_present():
                progress = profile_incomplete.get_progress_value()
                print(f"  Profile incomplete - Current Progress: {progress}")
                print("  Clicking Complete Profile button...")
                profile_incomplete.click_complete()
                time.sleep(3)
                result['steps_completed'].append('profile_modal_handled')
            
            # Step 4: Complete Profile
            print("\n[STEP 4] Completing Profile...")
            profile_editor = ProfileEditorPage(self.driver)
            profile_editor.wait_for_page_load()
            
            # Fill profile with student data
            self._fill_profile(profile_editor, student_data)
            
            # Save profile
            print("  Saving profile...")
            profile_editor.click_save()
            time.sleep(3)
            
            # Verify completion
            progress = profile_editor.get_progress_value()
            print(f"  Profile completion: {progress}")
            
            if "100%" in progress:
                result['steps_completed'].append('profile_completed')
                result['status'] = 'success'
                print("  ✅ Profile completed successfully!")
            else:
                result['status'] = 'partial'
                result['error'] = f"Profile not 100% complete: {progress}"
                print(f"  ⚠️  Profile not fully complete: {progress}")
            
        except Exception as e:
            result['status'] = 'error'
            result['error'] = str(e)
            print(f"  ❌ Error: {e}")
        
        finally:
            if self.driver:
                self.driver.quit()
                self.driver = None
        
        return result
    
    def _fill_profile(self, profile_editor, student_data):
        """Fill profile with student data"""
        print("  Filling profile fields...")
        
        # Step 1: Personal Information
        profile_editor.fill_personal_information(
            first_name=student_data.get('First Name'),
            last_name=student_data.get('Last Name'),
            gender=student_data.get('Gender'),
            dob=student_data.get('Date of Birth'),
            roll_number=str(student_data.get('Roll Number', '')),
            nationality=student_data.get('Nationality')
        )
        
        # Fill additional personal info fields if available
        if student_data.get('Language'):
            profile_editor.send_keys(profile_editor.LANGUAGE_INPUT, student_data['Language'])
        if student_data.get('Student ID Number'):
            profile_editor.send_keys(profile_editor.STUDENT_ID_INPUT, str(student_data['Student ID Number']))
        if student_data.get('Student CPID'):
            profile_editor.send_keys(profile_editor.STUDENT_CPID_INPUT, student_data['Student CPID'])
        
        # Navigate to next step
        profile_editor.click_next()
        time.sleep(1)
        
        # Step 2: Contact Information
        profile_editor.fill_contact_information(
            email=student_data.get('Email'),
            phone=str(student_data.get('Phone', '')),
            address=student_data.get('Address'),
            city=student_data.get('City'),
            state=student_data.get('State'),
            zip_code=str(student_data.get('Pin code', '')),
            native_state=student_data.get('Native State')
        )
        
        profile_editor.click_next()
        time.sleep(1)
        
        # Step 3: Parent/Guardian
        profile_editor.fill_parent_guardian(
            father_name=student_data.get('Father Name'),
            mother_name=student_data.get('Mother Name'),
            guardian_name=student_data.get('Guardian Name'),
            guardian_phone=str(student_data.get('Guardian Phone', ''))
        )
        
        profile_editor.click_next()
        time.sleep(1)
        
        # Step 4: Education Details
        profile_editor.fill_education_details(
            full_name=student_data.get('Full Name'),
            current_grade=str(student_data.get('Class', '')),
            section=student_data.get('Section'),
            board_stream=student_data.get('Board/Stream', 'CBSE')
        )
        
        # Steps 5-9: Use synthetic data or defaults
        # For now, we'll navigate through and let user fill manually
        # Or use synthetic data generator
        
        print("  ✅ Profile fields filled")
    
    def process_all(self, start_index=0, end_index=None):
        """
        Process all students
        
        Args:
            start_index: Start processing from this index
            end_index: End processing at this index (None = all)
        """
        students = self.load_students()
        
        if not students:
            print("❌ No students to process")
            return
        
        if end_index is None:
            end_index = len(students)
        
        students_to_process = students[start_index:end_index]
        
        print(f"\n{'='*80}")
        print(f"PROCESSING {len(students_to_process)} STUDENTS")
        print(f"{'='*80}")
        print(f"Start Index: {start_index}")
        print(f"End Index: {end_index}")
        print(f"{'='*80}\n")
        
        for idx, student in enumerate(students_to_process, start=start_index):
            print(f"\n[{idx+1}/{len(students_to_process)}] Processing student...")
            result = self.process_student(student)
            self.results.append(result)
            
            # Save progress after each student
            self._save_progress()
            
            # Small delay between students
            time.sleep(2)
        
        # Generate final report
        self._generate_report()
    
    def _save_progress(self):
        """Save progress to JSON file"""
        report_dir = Path(__file__).parent.parent / "reports" / "student_processing"
        report_dir.mkdir(parents=True, exist_ok=True)
        
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        report_file = report_dir / f"progress_{timestamp}.json"
        
        with open(report_file, 'w') as f:
            json.dump(self.results, f, indent=2)
    
    def _generate_report(self):
        """Generate final processing report"""
        total = len(self.results)
        successful = len([r for r in self.results if r['status'] == 'success'])
        partial = len([r for r in self.results if r['status'] == 'partial'])
        errors = len([r for r in self.results if r['status'] == 'error'])
        
        print(f"\n{'='*80}")
        print("PROCESSING SUMMARY")
        print(f"{'='*80}")
        print(f"Total Students: {total}")
        print(f"✅ Successful: {successful}")
        print(f"⚠️  Partial: {partial}")
        print(f"❌ Errors: {errors}")
        print(f"{'='*80}")
        
        if errors > 0:
            print("\nErrors:")
            for result in self.results:
                if result['status'] == 'error':
                    print(f"  - {result['cpid']}: {result['error']}")


def main():
    """Main entry point"""
    import argparse
    
    parser = argparse.ArgumentParser(description='Process students from Excel file')
    parser.add_argument('--excel', type=str, required=True, help='Path to Excel file with student data')
    parser.add_argument('--headless', action='store_true', help='Run in headless mode')
    parser.add_argument('--start', type=int, default=0, help='Start index (default: 0)')
    parser.add_argument('--end', type=int, default=None, help='End index (default: all)')
    parser.add_argument('--single', type=str, default=None, help='Process single student by CPID')
    
    args = parser.parse_args()
    
    processor = StudentProcessor(args.excel, headless=args.headless)
    
    if args.single:
        # Process single student
        students = processor.load_students()
        student = next((s for s in students if s.get('Student CPID') == args.single), None)
        if student:
            result = processor.process_student(student)
            print(f"\nResult: {result}")
        else:
            print(f"❌ Student with CPID {args.single} not found")
    else:
        # Process all students
        processor.process_all(start_index=args.start, end_index=args.end)


if __name__ == "__main__":
    main()

