#!/usr/bin/env python3
"""
Complete Student Journey Test Script - OPTIMIZED

Systematic end-to-end test covering the entire student flow:
1. Login
2. Password Reset (if new student) → Admin@123
3. Profile Completion (if not 100%)
4. Start Assessment
5. Complete All Domains/Phases
6. Provide All Feedbacks
7. Complete Assessment

OPTIMIZED: Uses smart explicit waits instead of time.sleep()
"""
import sys
from pathlib import Path

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

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 pages.student_nav_page import StudentNavPage
from pages.assessments_page import AssessmentsPage
from pages.domains_page import DomainsPage
from pages.domain_assessment_page import DomainAssessmentPage
from pages.domain_feedback_page import DomainFeedbackPage
from pages.feedback_survey_page import FeedbackSurveyPage
from utils.driver_manager import DriverManager
from config.config import BASE_URL, TEST_NEW_PASSWORD
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from config.config import SHORT_WAIT, MEDIUM_WAIT


def smart_wait_for_url_change(driver, current_url, timeout=MEDIUM_WAIT):
    """Wait for URL to change from current URL"""
    wait = WebDriverWait(driver, timeout)
    wait.until(lambda d: d.current_url != current_url)


def complete_student_journey(student_cpid, student_password, headless=False):
    """
    Complete student journey test - OPTIMIZED with smart waits
    
    Args:
        student_cpid: Student CPID
        student_password: Student password
        headless: Run in headless mode
    """
    driver = None
    try:
        print(f"\n{'='*80}")
        print(f"COMPLETE STUDENT JOURNEY TEST (OPTIMIZED)")
        print(f"{'='*80}")
        print(f"Student: {student_cpid}")
        print(f"{'='*80}\n")
        
        # Initialize driver
        driver_manager = DriverManager()
        driver = driver_manager.get_driver(headless=headless)
        
        # STEP 1: LOGIN
        print("[STEP 1] LOGIN")
        print("-" * 80)
        login_page = LoginPage(driver)
        login_page.login(identifier=student_cpid, password=student_password)
        # Wait for navigation (handled by login method)
        print(f"✅ Login successful - URL: {driver.current_url}\n")
        
        # STEP 2: PASSWORD RESET (if new student)
        print("[STEP 2] PASSWORD RESET CHECK")
        print("-" * 80)
        reset_page = MandatoryResetPage(driver)
        if reset_page.is_modal_present():
            print("  ✅ Password reset modal found (new student)")
            print(f"  Resetting password to: {TEST_NEW_PASSWORD}")
            reset_page.reset_password(
                current_password=student_password,
                new_password=TEST_NEW_PASSWORD,
                confirm_password=TEST_NEW_PASSWORD
            )
            print("  ✅ Password reset completed")
            student_password = TEST_NEW_PASSWORD
        else:
            print("  ✅ No password reset required (existing student)")
        print()
        
        # STEP 3: PROFILE COMPLETION (if not 100%)
        print("[STEP 3] PROFILE COMPLETION CHECK")
        print("-" * 80)
        profile_incomplete = ProfileIncompletePage(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()
            # Wait for navigation (handled by click_complete)
            print(f"  Navigated to: {driver.current_url}")
            
            # Complete profile to 100%
            print("\n  [STEP 3.1] Completing Profile to 100%...")
            profile_editor = ProfileEditorPage(driver)
            profile_editor.wait_for_page_load()
            
            # Check progress
            progress = profile_editor.get_progress_value()
            print(f"  Current Profile Progress: {progress}")
            
            if "100%" in progress:
                print("  ✅ Profile is 100% complete!")
            else:
                print(f"  ⚠️  Profile is {progress} complete")
                print("  Note: Profile completion automation requires student data from Excel")
                print("  For now, profile can be completed manually or with process_students.py")
                # Navigate back to dashboard
                driver.get(f"{BASE_URL}/student/dashboard")
                WebDriverWait(driver, SHORT_WAIT).until(
                    EC.url_contains("/dashboard")
                )
        else:
            print("  ✅ Profile already complete or modal not present")
        print()
        
        # STEP 4: NAVIGATE TO ASSESSMENTS
        print("[STEP 4] NAVIGATE TO ASSESSMENTS")
        print("-" * 80)
        try:
            nav = StudentNavPage(driver)
            nav.click_assessments()
            # Wait for navigation (handled by click_assessments)
            print(f"✅ Navigated to Assessments via nav link - URL: {driver.current_url}\n")
        except Exception as e:
            print(f"  ⚠️  Could not click nav link: {e}")
            print("  Trying direct navigation to assessments...")
            # Fallback: Navigate directly
            from config.config import ASSESSMENTS_URL
            driver.get(ASSESSMENTS_URL)
            WebDriverWait(driver, SHORT_WAIT).until(
                EC.url_contains("/assessments")
            )
            print(f"✅ Navigated to Assessments directly - URL: {driver.current_url}\n")
        
        # STEP 5: START ASSESSMENT
        print("[STEP 5] START ASSESSMENT")
        print("-" * 80)
        assessments_page = AssessmentsPage(driver)
        assessments_page.wait_for_page_load()
        
        # Get available assessments
        try:
            assessment_ids = assessments_page.get_assessment_ids()
            print(f"  Found {len(assessment_ids)} assessment(s): {assessment_ids}")
        except Exception as e:
            print(f"  ⚠️  Could not get assessment IDs: {e}")
            print("  Trying to find assessment cards manually...")
            assessment_ids = []
            try:
                cards = assessments_page.get_all_assessment_cards()
                print(f"  Found {len(cards)} assessment card(s)")
                if cards:
                    import re
                    test_id = cards[0].get_attribute("data-testid")
                    if test_id:
                        match = re.search(r'assessment_card__(\d+)', test_id)
                        if match:
                            assessment_ids = [match.group(1)]
            except Exception as e2:
                print(f"  ⚠️  Error finding cards: {e2}")
        
        if not assessment_ids:
            print("  ⚠️  No assessments available")
            if not headless:
                print("  Keeping browser open for 30 seconds for inspection...")
                import time
                time.sleep(30)  # Only use sleep for final inspection delay
            return
        
        # Start first available assessment
        first_assessment_id = assessment_ids[0]
        print(f"  Starting assessment ID: {first_assessment_id}")
        try:
            current_url = driver.current_url
            assessments_page.click_begin_assessment(first_assessment_id)
            # Wait for URL change (handled by click_begin_assessment)
            print(f"✅ Assessment started - URL: {driver.current_url}\n")
        except Exception as e:
            print(f"  ⚠️  Error starting assessment: {e}")
            if not headless:
                print("  Keeping browser open for 30 seconds for inspection...")
                import time
                time.sleep(30)  # Only use sleep for final inspection delay
            return
        
        # STEP 6: COMPLETE ALL DOMAINS
        print("[STEP 6] COMPLETE ALL DOMAINS")
        print("-" * 80)
        domains_page = DomainsPage(driver)
        domains_page.wait_for_page_load()
        
        # Get all domains
        try:
            domain_ids = domains_page.get_all_domain_ids()
            print(f"  Found {len(domain_ids)} domain(s): {domain_ids}")
        except Exception as e:
            print(f"  ⚠️  Could not get domain IDs: {e}")
            if not headless:
                print("  Keeping browser open for 30 seconds for inspection...")
                import time
                time.sleep(30)  # Only use sleep for final inspection delay
            return
        
        if not domain_ids:
            print("  ⚠️  No domains available")
            return
        
        for idx, domain_id in enumerate(domain_ids, 1):
            print(f"\n  [DOMAIN {idx}/{len(domain_ids)}] Domain ID: {domain_id}")
            print("  " + "-" * 76)
            
            # Check if domain is unlocked
            try:
                if domains_page.is_domain_locked(domain_id):
                    print(f"  ⚠️  Domain {domain_id} is locked - skipping")
                    continue
            except:
                print(f"  ⚠️  Could not check lock status - trying to proceed...")
            
            # Start domain assessment
            print(f"  Starting domain assessment...")
            try:
                current_url = driver.current_url
                domains_page.click_domain_action(domain_id)
                # Wait for URL change (handled by click_domain_action)
                print(f"  ✅ Domain assessment started")
            except Exception as e:
                print(f"  ⚠️  Error starting domain: {e}")
                continue
            
            # STEP 6.1: COMPLETE DOMAIN ASSESSMENT
            print(f"  [STEP 6.1] Completing Domain Assessment...")
            domain_assessment = DomainAssessmentPage(driver)
            domain_assessment.wait_for_page_load()
            
            # Dismiss guidance modal if present (non-blocking)
            try:
                domain_assessment.dismiss_guidance()
                print(f"    Dismissed guidance modal if present")
            except:
                pass
            
            # Answer all questions in the domain
            questions_answered = 0
            max_questions = 50  # Safety limit
            question_attempts = 0
            
            while question_attempts < max_questions:
                question_attempts += 1
                print(f"    [Question {question_attempts}] Processing...")
                
                # Get current question ID
                current_question_id = domain_assessment.get_current_question_id()
                if not current_question_id:
                    # Try to find question on page
                    try:
                        questions = driver.find_elements(By.CSS_SELECTOR, "[data-testid^='domain_question__']")
                        if questions:
                            test_id = questions[0].get_attribute("data-testid")
                            if test_id:
                                import re
                                match = re.search(r'domain_question__(\d+)', test_id)
                                if match:
                                    current_question_id = match.group(1)
                    except:
                        pass
                
                if not current_question_id:
                    print(f"    ⚠️  No question found - may have completed all questions")
                    break
                
                print(f"      Question ID: {current_question_id}")
                
                # Try to answer the question (try different question types)
                answered = False
                try:
                    # Try multiple choice (option a)
                    try:
                        domain_assessment.answer_multiple_choice(current_question_id, "a")
                        print(f"      ✅ Answered: Multiple choice (option a)")
                        answered = True
                    except:
                        # Try true/false
                        try:
                            domain_assessment.answer_true_false(current_question_id, True)
                            print(f"      ✅ Answered: True/False (True)")
                            answered = True
                        except:
                            # Try rating
                            try:
                                domain_assessment.answer_rating(current_question_id, 3)
                                print(f"      ✅ Answered: Rating (3)")
                                answered = True
                            except:
                                # Try open ended
                                try:
                                    domain_assessment.answer_open_ended(current_question_id, "Automated test response for question.")
                                    print(f"      ✅ Answered: Open-ended")
                                    answered = True
                                except:
                                    # Try matrix (first cell)
                                    try:
                                        domain_assessment.answer_matrix(current_question_id, 0, 0)
                                        print(f"      ✅ Answered: Matrix (0,0)")
                                        answered = True
                                    except Exception as e:
                                        print(f"      ⚠️  Could not answer question: {e}")
                except Exception as e:
                    print(f"      ⚠️  Error answering question: {e}")
                
                if answered:
                    questions_answered += 1
                
                # Try to navigate to next question
                try:
                    # Check if next button is visible and clickable
                    next_button = driver.find_elements(By.CSS_SELECTOR, "[data-testid='domain_assessment__next_button']")
                    if next_button and next_button[0].is_displayed() and next_button[0].is_enabled():
                        domain_assessment.click_next()
                        # Wait for next question to load (handled by click_next)
                        print(f"      Navigated to next question")
                        continue
                    else:
                        # Check if submit button is visible
                        submit_button = driver.find_elements(By.CSS_SELECTOR, "[data-testid='domain_assessment__submit_button']")
                        if submit_button and submit_button[0].is_displayed() and submit_button[0].is_enabled():
                            print(f"    All questions answered. Submitting...")
                            domain_assessment.click_submit()
                            # Wait for submit modal (handled by click_submit)
                            break
                        else:
                            print(f"    ⚠️  No next or submit button found")
                            break
                except Exception as e:
                    print(f"      ⚠️  Error navigating: {e}")
                    break
            
            print(f"    ✅ Answered {questions_answered} question(s)")
            
            # Handle submit confirmation modal if present
            try:
                submit_modal = driver.find_elements(By.CSS_SELECTOR, "[data-testid='domain_assessment__submit_modal']")
                if submit_modal:
                    print(f"    Submit confirmation modal found - confirming...")
                    domain_assessment.confirm_submit()
                    # Wait for success modal (handled by confirm_submit)
            except Exception as e:
                print(f"    ⚠️  Error handling submit modal: {e}")
            
            # Wait for success modal (non-blocking, short wait)
            try:
                success_modal = WebDriverWait(driver, SHORT_WAIT).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, "[data-testid='domain_assessment__success_modal']"))
                )
                print(f"    ✅ Domain assessment submitted successfully")
                # Wait for modal to auto-close or redirect (short wait)
                WebDriverWait(driver, SHORT_WAIT).until(
                    EC.invisibility_of_element_located((By.CSS_SELECTOR, "[data-testid='domain_assessment__success_modal']"))
                )
            except:
                # Success modal might have already closed or not present
                pass
            
            # STEP 6.2: PROVIDE DOMAIN FEEDBACK
            print(f"  [STEP 6.2] Providing Domain Feedback...")
            domain_feedback = DomainFeedbackPage(driver)
            
            try:
                # Wait for feedback modal with short timeout
                if domain_feedback.is_modal_present():
                    print(f"    Domain feedback modal found")
                    
                    # Submit feedback with answers
                    try:
                        domain_feedback.submit_feedback(
                            question1_yes=True,
                            question1_text="Automated feedback response for testing.",
                            question2_text="This is automated feedback for testing purposes."
                        )
                        # Wait for modal close and redirect (handled by submit_feedback)
                        print(f"    ✅ Domain feedback submitted")
                    except Exception as e:
                        print(f"    ⚠️  Error submitting feedback: {e}")
                        # Try skip as fallback
                        try:
                            domain_feedback.skip_feedback()
                            print(f"    Skipped feedback")
                        except:
                            pass
                else:
                    print(f"    ⚠️  No domain feedback modal found - may have auto-closed")
            except Exception as e:
                print(f"    ⚠️  Error handling feedback: {e}")
            
            # Navigate back to domains page
            print(f"  Returning to domains page...")
            try:
                current_url = driver.current_url
                driver.back()
                # Wait for URL change
                WebDriverWait(driver, SHORT_WAIT).until(
                    lambda d: d.current_url != current_url
                )
                domains_page = DomainsPage(driver)
                domains_page.wait_for_page_load()
            except Exception as e:
                print(f"  ⚠️  Error returning to domains: {e}")
                # Try direct navigation
                try:
                    current_url = driver.current_url
                    base_url = current_url.split('/assessment/')[0]
                    assessment_id = current_url.split('/assessment/')[1].split('/')[0]
                    driver.get(f"{base_url}/assessment/{assessment_id}/domains")
                    domains_page = DomainsPage(driver)
                    domains_page.wait_for_page_load()
                except:
                    pass
        
        print(f"\n✅ All domains processed!\n")
        
        # STEP 7: FINAL FEEDBACK (from domains page)
        print("[STEP 7] FINAL FEEDBACK")
        print("-" * 80)
        
        # Check for final feedback modal on domains page
        try:
            if domains_page.is_final_feedback_modal_present():
                print("  Final feedback modal found (from domains page)")
                domains_page.fill_final_feedback(
                    question1_yes=True,
                    question1_reason="Automated final feedback response.",
                    question2_text="This is automated final feedback for testing purposes."
                )
                # Wait handled by fill_final_feedback
                print("  ✅ Final feedback submitted")
            else:
                print("  ⚠️  Final feedback modal not found on domains page")
        except Exception as e:
            print(f"  ⚠️  Error handling final feedback from domains page: {e}")
        
        # Also check for feedback survey modal
        print("\n[STEP 7.1] FEEDBACK SURVEY")
        print("-" * 80)
        
        try:
            feedback_survey = FeedbackSurveyPage(driver)
            
            # Check for overall modal
            if feedback_survey.is_overall_modal_present():
                print("  Final feedback modal (overall) found")
                
                try:
                    feedback_survey.set_overall_rating(4)
                    print("  Selected overall rating: 4")
                    feedback_survey.submit_feedback()
                    # Wait handled by submit_feedback
                    print("  ✅ Overall feedback submitted")
                except Exception as e:
                    print(f"  ⚠️  Error with overall feedback: {e}")
            
            # Check for per-question modal
            if feedback_survey.is_per_question_modal_present():
                print("  Final feedback modal (per-question) found")
                
                try:
                    question_ratings = driver.find_elements(By.CSS_SELECTOR, "[data-testid^='feedback_survey__question_']")
                    question_ids = set()
                    for element in question_ratings:
                        test_id = element.get_attribute("data-testid")
                        if test_id:
                            import re
                            match = re.search(r'question_(\d+)_rating', test_id)
                            if match:
                                question_ids.add(match.group(1))
                    
                    for q_id in question_ids:
                        try:
                            feedback_survey.set_question_rating(q_id, 4)
                            feedback_survey.set_question_comment(q_id, "Automated feedback comment")
                            print(f"  Provided feedback for question {q_id}")
                        except:
                            pass
                    
                    feedback_survey.submit_feedback()
                    # Wait handled by submit_feedback
                    print("  ✅ Per-question feedback submitted")
                except Exception as e:
                    print(f"  ⚠️  Error with per-question feedback: {e}")
            
            if not feedback_survey.is_overall_modal_present() and not feedback_survey.is_per_question_modal_present():
                print("  ⚠️  Final feedback modal not available")
        except Exception as e:
            print(f"  ⚠️  Error handling final feedback: {e}")
        
        print(f"\n{'='*80}")
        print("COMPLETE JOURNEY TEST FINISHED!")
        print(f"{'='*80}\n")
        
        # Keep browser open for inspection (only if not headless)
        if not headless:
            print("Keeping browser open for 60 seconds for inspection...")
            import time
            time.sleep(60)  # Only use sleep for final inspection delay
        
    except Exception as e:
        print(f"\n❌ ERROR: {e}")
        import traceback
        traceback.print_exc()
        if driver and not headless:
            print("\nKeeping browser open for 60 seconds for debugging...")
            import time
            time.sleep(60)  # Only use sleep for final inspection delay
    finally:
        if driver:
            driver.quit()


def main():
    """Main entry point"""
    import argparse
    
    parser = argparse.ArgumentParser(description='Complete student journey test (OPTIMIZED)')
    parser.add_argument('--cpid', type=str, required=True, help='Student CPID')
    parser.add_argument('--password', type=str, required=True, help='Student password')
    parser.add_argument('--headless', action='store_true', help='Run in headless mode')
    
    args = parser.parse_args()
    
    complete_student_journey(args.cpid, args.password, headless=args.headless)


if __name__ == "__main__":
    main()
