"""
DOM Verification Script - Verify data-testid Implementation

Purpose: Verify actual DOM implementation against UI team's claims
Method: Inspect actual DOM structure at runtime
Approach: World-class systematic verification with zero tolerance for assumptions
"""
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pages.login_page import LoginPage
from pages.mandatory_reset_page import MandatoryResetPage
from pages.profile_editor_page import ProfileEditorPage
from config.config import TEST_USERNAME, TEST_PASSWORD, BASE_URL
import time
import json
from collections import defaultdict


class DataTestIdVerifier:
    """World-Class DOM Verifier for data-testid Attributes"""
    
    def __init__(self, driver):
        self.driver = driver
        self.results = {
            'profile_editor': {
                'found': [],
                'missing': [],
                'expected': [],
                'unexpected': []
            },
            'mandatory_reset': {
                'found': [],
                'missing': [],
                'expected': [],
                'unexpected': []
            }
        }
    
    def verify_profile_editor_attributes(self):
        """Verify all Profile Editor data-testid attributes"""
        print("\n" + "="*80)
        print("🔍 VERIFYING: Profile Editor Attributes")
        print("="*80)
        
        # First, login to ensure we have access
        print("\n📋 Logging in first...")
        self.driver.get(BASE_URL + "/login")
        time.sleep(2)
        
        login_page = LoginPage(self.driver)
        login_page.login(identifier=TEST_USERNAME, password=TEST_PASSWORD)
        time.sleep(3)
        
        # Check for password reset modal and handle it
        reset_page = MandatoryResetPage(self.driver)
        if reset_page.is_modal_present():
            print("⚠️  Password reset modal detected - handling it...")
            try:
                reset_page.click_continue()
                time.sleep(2)
                # Use old password for reset
                reset_page.reset_password(
                    current_password=TEST_PASSWORD,
                    new_password=TEST_PASSWORD  # Keep same for now
                )
                time.sleep(3)
            except:
                print("  ⚠️  Could not handle password reset - continuing anyway")
        
        # Navigate to profile editor
        print("\n📋 Navigating to Profile Editor...")
        self.driver.get(BASE_URL + "/student/profile-builder")
        time.sleep(5)  # Give more time for page load
        
        # Check if we're actually on the profile editor page
        current_url = self.driver.current_url
        print(f"  Current URL: {current_url}")
        
        if "profile" not in current_url.lower():
            print("  ⚠️  May not be on profile editor page - checking page content...")
            page_source = self.driver.page_source
            if "profile" in page_source.lower() or "editor" in page_source.lower():
                print("  ✅ Profile editor content detected in page source")
            else:
                print("  ❌ Profile editor content NOT found - page may have redirected")
        
        # Wait for page to fully load
        print("\n⏳ Waiting for page to fully load...")
        try:
            WebDriverWait(self.driver, 10).until(
                lambda d: d.execute_script("return document.readyState") == "complete"
            )
            time.sleep(2)  # Additional wait for React to render
        except:
            print("  ⚠️  Page load timeout, continuing anyway...")
        
        # Try to find any profile_editor attributes to confirm page is loaded
        initial_check = self.driver.find_elements(By.CSS_SELECTOR, "[data-testid^='profile_editor__']")
        print(f"  Initial check: Found {len(initial_check)} profile_editor attributes")
        
        # Expected attributes from UI team's implementation status
        # Based on 10_FINAL_IMPLEMENTATION_STATUS.md
        expected_attributes = {
            # Page-level (3 according to UI team, not 4)
            'profile_editor__page': 'Page container',
            'profile_editor__progress_value': 'Progress value',
            'profile_editor__back_button': 'Back button',
            # Note: UI team doesn't mention missing_fields_toggle
            
            # Tab navigation
            'profile_editor__tabs_container': 'Tabs container',
            'profile_editor__tabs_scroll_left_button': 'Scroll left button',
            'profile_editor__tabs_scroll_right_button': 'Scroll right button',
            'profile_editor__tab_personal_information': 'Tab: Personal Information',
            'profile_editor__tab_contact_information': 'Tab: Contact Information',
            'profile_editor__tab_parent_guardian': 'Tab: Parent/Guardian',
            'profile_editor__tab_education_details': 'Tab: Education Details',
            'profile_editor__tab_focus_areas': 'Tab: Focus Areas',
            'profile_editor__tab_self_assessment': 'Tab: Self-Assessment',
            'profile_editor__tab_hobbies_clubs': 'Tab: Hobbies & Clubs',
            'profile_editor__tab_achievements': 'Tab: Achievements',
            'profile_editor__tab_expectations': 'Tab: Expectations',
            
            # Personal Information (11 according to UI team, includes age_input)
            'profile_editor__first_name_input': 'First Name input',
            'profile_editor__last_name_input': 'Last Name input',
            'profile_editor__gender_select': 'Gender select',
            'profile_editor__dob_input': 'DOB input',
            'profile_editor__age_input': 'Age input',  # UI team mentions this
            'profile_editor__nationality_input': 'Nationality input',
            'profile_editor__language_input': 'Language input',
            'profile_editor__student_id_input': 'Student ID input',
            'profile_editor__student_cpid_input': 'Student CPID input',
            'profile_editor__specially_abled_checkbox': 'Specially Abled checkbox',
            'profile_editor__specially_abled_details_textarea': 'Specially Abled details',
            
            # Contact Information
            'profile_editor__email_input': 'Email input',
            'profile_editor__phone_input': 'Phone input',
            'profile_editor__address_input': 'Address input',
            'profile_editor__city_input': 'City input',
            'profile_editor__state_input': 'State input',
            'profile_editor__zip_code_input': 'ZIP Code input',
            'profile_editor__native_state_input': 'Native State input',
            
            # Navigation buttons
            'profile_editor__prev_button': 'Previous button',
            'profile_editor__next_button': 'Next button',
            'profile_editor__cancel_button': 'Cancel button',
            'profile_editor__save_button': 'Save button',
        }
        
        # Find all profile_editor attributes in DOM
        print("\n🔍 Searching for profile_editor attributes in DOM...")
        all_elements = self.driver.find_elements(By.CSS_SELECTOR, "[data-testid^='profile_editor__']")
        found_attributes = set()
        
        for elem in all_elements:
            try:
                test_id = elem.get_attribute('data-testid')
                if test_id:
                    found_attributes.add(test_id)
                    self.results['profile_editor']['found'].append({
                        'attribute': test_id,
                        'tag': elem.tag_name,
                        'visible': elem.is_displayed()
                    })
            except:
                pass
        
        # Check for expected attributes
        print(f"\n📊 Found {len(found_attributes)} profile_editor attributes")
        
        for attr, description in expected_attributes.items():
            if attr in found_attributes:
                print(f"  ✅ {attr} - {description}")
                self.results['profile_editor']['expected'].append(attr)
            else:
                print(f"  ❌ {attr} - {description} - MISSING")
                self.results['profile_editor']['missing'].append({
                    'attribute': attr,
                    'description': description
                })
        
        # Check for unexpected attributes
        unexpected = found_attributes - set(expected_attributes.keys())
        for attr in unexpected:
            print(f"  ⚠️  {attr} - UNEXPECTED (not in requirements)")
            self.results['profile_editor']['unexpected'].append(attr)
        
        # Check for dynamic attributes (MultiSelectPicker)
        print("\n🔍 Checking for dynamic attributes (MultiSelectPicker)...")
        dynamic_patterns = [
            'profile_editor__short_term_focus__',
            'profile_editor__long_term_focus__',
            'profile_editor__strength__',
            'profile_editor__improvement__',
            'profile_editor__hobby__',
            'profile_editor__club_',
            'profile_editor__expectation__',
        ]
        
        dynamic_found = defaultdict(list)
        for attr in found_attributes:
            for pattern in dynamic_patterns:
                if attr.startswith(pattern):
                    dynamic_found[pattern].append(attr)
        
        for pattern, attrs in dynamic_found.items():
            print(f"  ✅ {pattern}: Found {len(attrs)} attributes")
            if len(attrs) > 0:
                print(f"     Examples: {attrs[:3]}")
        
        return found_attributes
    
    def verify_mandatory_reset_attributes(self):
        """Verify all Mandatory Password Reset Modal data-testid attributes"""
        print("\n" + "="*80)
        print("🔍 VERIFYING: Mandatory Password Reset Modal Attributes")
        print("="*80)
        
        # Navigate to login and trigger password reset modal
        print("\n📋 Navigating to login page...")
        self.driver.get(BASE_URL + "/login")
        time.sleep(2)
        
        # Login to trigger password reset modal
        print("🔑 Logging in to trigger password reset modal...")
        login_page = LoginPage(self.driver)
        login_page.login(identifier=TEST_USERNAME, password=TEST_PASSWORD)
        time.sleep(3)
        
        # Check if modal is present
        reset_page = MandatoryResetPage(self.driver)
        if not reset_page.is_modal_present():
            print("⚠️  Password reset modal not present - password may already be reset")
            print("   Skipping mandatory reset verification")
            return set()
        
        print("✅ Password reset modal detected")
        
        # Expected attributes
        expected_attributes = {
            'mandatory_reset__modal': 'Modal overlay',
            'mandatory_reset__modal_content': 'Modal content',
            'mandatory_reset__continue_button': 'Continue button',
            'mandatory_reset__form': 'Form container',
            'mandatory_reset__current_password_input': 'Current password input',
            'mandatory_reset__current_password_toggle': 'Current password toggle',
            'mandatory_reset__current_password_error': 'Current password error',
            'mandatory_reset__new_password_input': 'New password input',
            'mandatory_reset__new_password_toggle': 'New password toggle',
            'mandatory_reset__new_password_error': 'New password error',
            'mandatory_reset__confirm_password_input': 'Confirm password input',
            'mandatory_reset__confirm_password_toggle': 'Confirm password toggle',
            'mandatory_reset__confirm_password_error': 'Confirm password error',
            'mandatory_reset__back_button': 'Back button',
            'mandatory_reset__submit_button': 'Submit button',
        }
        
        # Find all mandatory_reset attributes in DOM
        print("\n🔍 Searching for mandatory_reset attributes in DOM...")
        all_elements = self.driver.find_elements(By.CSS_SELECTOR, "[data-testid^='mandatory_reset__']")
        found_attributes = set()
        
        for elem in all_elements:
            try:
                test_id = elem.get_attribute('data-testid')
                if test_id:
                    found_attributes.add(test_id)
                    self.results['mandatory_reset']['found'].append({
                        'attribute': test_id,
                        'tag': elem.tag_name,
                        'visible': elem.is_displayed()
                    })
            except:
                pass
        
        # Check for expected attributes
        print(f"\n📊 Found {len(found_attributes)} mandatory_reset attributes")
        
        for attr, description in expected_attributes.items():
            if attr in found_attributes:
                print(f"  ✅ {attr} - {description}")
                self.results['mandatory_reset']['expected'].append(attr)
            else:
                print(f"  ❌ {attr} - {description} - MISSING")
                self.results['mandatory_reset']['missing'].append({
                    'attribute': attr,
                    'description': description
                })
        
        # Check for unexpected attributes
        unexpected = found_attributes - set(expected_attributes.keys())
        for attr in unexpected:
            print(f"  ⚠️  {attr} - UNEXPECTED (not in requirements)")
            self.results['mandatory_reset']['unexpected'].append(attr)
        
        # Click Continue to see Step 2 (form)
        try:
            continue_btn = self.driver.find_element(By.CSS_SELECTOR, "[data-testid='mandatory_reset__continue_button']")
            if continue_btn.is_displayed():
                print("\n📋 Clicking Continue button to verify Step 2 attributes...")
                continue_btn.click()
                time.sleep(2)
                
                # Re-check for form attributes
                form_elements = self.driver.find_elements(By.CSS_SELECTOR, "[data-testid^='mandatory_reset__']")
                form_attributes = set()
                for elem in form_elements:
                    try:
                        test_id = elem.get_attribute('data-testid')
                        if test_id:
                            form_attributes.add(test_id)
                    except:
                        pass
                
                print(f"\n📊 After clicking Continue: Found {len(form_attributes)} attributes")
                new_attrs = form_attributes - found_attributes
                if new_attrs:
                    print(f"  ✅ New attributes found in Step 2: {new_attrs}")
                    found_attributes.update(new_attrs)
        except:
            print("  ⚠️  Could not click Continue button (may already be on Step 2)")
        
        return found_attributes
    
    def generate_verification_report(self):
        """Generate comprehensive verification report"""
        print("\n" + "="*80)
        print("📊 VERIFICATION REPORT SUMMARY")
        print("="*80)
        
        # Profile Editor
        profile_expected = len(self.results['profile_editor']['expected'])
        profile_missing = len(self.results['profile_editor']['missing'])
        profile_unexpected = len(self.results['profile_editor']['unexpected'])
        profile_total_found = len(self.results['profile_editor']['found'])
        
        print(f"\n📋 Profile Editor:")
        print(f"  ✅ Found: {profile_total_found} attributes")
        print(f"  ✅ Expected: {profile_expected} attributes")
        print(f"  ❌ Missing: {profile_missing} attributes")
        print(f"  ⚠️  Unexpected: {profile_unexpected} attributes")
        
        if profile_missing > 0:
            print(f"\n  ❌ Missing Attributes:")
            for item in self.results['profile_editor']['missing']:
                print(f"     - {item['attribute']}: {item['description']}")
        
        # Mandatory Reset
        reset_expected = len(self.results['mandatory_reset']['expected'])
        reset_missing = len(self.results['mandatory_reset']['missing'])
        reset_unexpected = len(self.results['mandatory_reset']['unexpected'])
        reset_total_found = len(self.results['mandatory_reset']['found'])
        
        print(f"\n📋 Mandatory Password Reset Modal:")
        print(f"  ✅ Found: {reset_total_found} attributes")
        print(f"  ✅ Expected: {reset_expected} attributes")
        print(f"  ❌ Missing: {reset_missing} attributes")
        print(f"  ⚠️  Unexpected: {reset_unexpected} attributes")
        
        if reset_missing > 0:
            print(f"\n  ❌ Missing Attributes:")
            for item in self.results['mandatory_reset']['missing']:
                print(f"     - {item['attribute']}: {item['description']}")
        
        # Overall Status
        total_expected = profile_expected + reset_expected
        total_missing = profile_missing + reset_missing
        total_found = profile_total_found + reset_total_found
        
        print(f"\n📊 OVERALL STATUS:")
        print(f"  ✅ Total Found: {total_found} attributes")
        print(f"  ✅ Total Expected: {total_expected} attributes")
        print(f"  ❌ Total Missing: {total_missing} attributes")
        
        if total_missing == 0:
            print(f"\n  🎉 SUCCESS: All required attributes are present!")
        else:
            print(f"\n  ⚠️  WARNING: {total_missing} attributes are still missing")
        
        return self.results


def verify_implementation():
    """Main verification function"""
    print("="*80)
    print("🔍 DATA-TESTID IMPLEMENTATION VERIFICATION")
    print("="*80)
    print("\n🎯 Purpose: Verify UI team's implementation against actual DOM")
    print("💡 Method: Systematic DOM inspection - Zero assumptions")
    print("📋 Approach: World-class verification with 100% accuracy\n")
    
    # Setup Chrome driver
    chrome_options = Options()
    chrome_options.add_argument("--start-maximized")
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    
    driver = webdriver.Chrome(options=chrome_options)
    verifier = DataTestIdVerifier(driver)
    
    try:
        # Step 1: Verify Profile Editor
        profile_attrs = verifier.verify_profile_editor_attributes()
        
        # Step 2: Verify Password Reset Modal
        reset_attrs = verifier.verify_mandatory_reset_attributes()
        
        # Step 3: Generate Report
        results = verifier.generate_verification_report()
        
        # Step 4: Save detailed report
        report_file = os.path.join(os.path.dirname(__file__), '..', 'documentation', 'verification-reports', 'DOM_VERIFICATION_REPORT.json')
        os.makedirs(os.path.dirname(report_file), exist_ok=True)
        
        with open(report_file, 'w') as f:
            json.dump(results, f, indent=2)
        
        print(f"\n💾 Detailed report saved to: {report_file}")
        
        print(f"\n⏸️  Browser will stay open for 30 seconds for manual inspection...")
        time.sleep(30)
        
    except Exception as e:
        print(f"\n❌ ERROR: {e}")
        import traceback
        traceback.print_exc()
        print(f"\n⏸️  Browser will stay open for 30 seconds for manual inspection...")
        time.sleep(30)
    finally:
        print(f"\n{'='*80}")
        print("CLEANUP")
        print(f"{'='*80}")
        driver.quit()
        print("✅ Driver closed")


if __name__ == "__main__":
    verify_implementation()

