"""
Smart Wait Optimizer - World-Class Precision

Optimizes wait times by using intelligent detection:
1. Password tracker - if password was reset, skip reset modal check
2. Profile completion - if profile is 100%, skip incomplete modal check
3. Fast detection using robust locators (data-testid)
4. Animation-aware waits (150ms FAST, 300ms NORMAL, 500ms SLOW)
5. Tiny padding (50-100ms) for safety
"""
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from utils.password_tracker import password_tracker
from config.config import TEST_NEW_PASSWORD
import time


class SmartWaitOptimizer:
    """
    World-class wait optimizer that eliminates unnecessary waits.
    
    Uses intelligent detection to skip modal checks when not needed:
    - Password reset modal: Skip if password was already reset
    - Profile incomplete modal: Skip if profile is already complete
    """
    
    # Animation durations from UI source code
    ANIMATION_FAST = 0.15  # 150ms
    ANIMATION_NORMAL = 0.3  # 300ms
    ANIMATION_SLOW = 0.5  # 500ms
    SAFETY_PADDING = 0.05  # 50ms safety padding
    
    # Total wait times (animation + padding)
    MODAL_DETECTION_TIMEOUT = ANIMATION_NORMAL + SAFETY_PADDING  # 350ms
    QUICK_CHECK_TIMEOUT = ANIMATION_FAST + SAFETY_PADDING  # 200ms
    
    @staticmethod
    def should_check_password_reset(cpid: str, password_used: str) -> bool:
        """
        Determine if password reset modal check is needed.
        
        Logic:
        - If TEST_NEW_PASSWORD was used to login, reset modal won't appear
        - If password tracker shows password was reset, skip check
        
        Args:
            cpid: Student CPID
            password_used: Password that was used for login
            
        Returns:
            bool: True if should check for reset modal, False to skip
        """
        # If TEST_NEW_PASSWORD was used, reset modal won't appear
        if password_used == TEST_NEW_PASSWORD:
            return False
        
        # Check password tracker - if password was reset, skip check
        tracked_password = password_tracker._passwords.get(cpid)
        if tracked_password == TEST_NEW_PASSWORD:
            return False
        
        # Otherwise, need to check
        return True
    
    @staticmethod
    def should_check_profile_incomplete(driver) -> bool:
        """
        Determine if profile incomplete modal check is needed.
        
        Logic:
        - Check if profile completion is already 100%
        - If 100%, skip modal check
        
        Args:
            driver: WebDriver instance
            
        Returns:
            bool: True if should check for incomplete modal, False to skip
        """
        try:
            # Quick check for profile completion indicator
            # Look for progress value in dashboard or profile editor
            from selenium.webdriver.common.by import By
            
            # Strategy 1: Check for 100% completion indicator
            completion_indicators = [
                "100%",
                "Complete",
                "Profile Complete",
                "profile-complete"
            ]
            
            page_text = driver.page_source.lower()
            for indicator in completion_indicators:
                if indicator.lower() in page_text:
                    # Found completion indicator - profile might be complete
                    # But we need to verify it's actually 100%
                    # This is a quick check, not definitive
                    pass
            
            # Strategy 2: Check for profile incomplete modal data-testid
            # If modal is already visible, we need to handle it
            try:
                incomplete_modal = driver.find_elements(
                    By.CSS_SELECTOR, 
                    "[data-testid='profile_incomplete__modal']"
                )
                if incomplete_modal and any(m.is_displayed() for m in incomplete_modal):
                    return True  # Modal is visible, need to handle
            except:
                pass
            
            # Strategy 3: Check for profile editor page
            # If we're on profile editor, profile might be incomplete
            current_url = driver.current_url.lower()
            if "/profile-builder" in current_url or "/profile" in current_url:
                # On profile page - might be incomplete
                # But if we're here, modal might have already been handled
                return False  # Skip check, we're already on profile page
            
            # Default: Check for modal (safe approach)
            return True
            
        except Exception as e:
            # On error, default to checking (safe approach)
            print(f"⚠️  Error checking profile completion: {e}, will check modal")
            return True
    
    @staticmethod
    def quick_check_modal_present(driver, modal_locator, timeout=None) -> bool:
        """
        Quick check if modal is present using fast detection.
        
        Uses:
        - Fast animation timeout (200ms)
        - Robust locator (data-testid)
        - No unnecessary waits
        
        Args:
            driver: WebDriver instance
            modal_locator: Locator tuple (By, selector)
            timeout: Custom timeout (default: QUICK_CHECK_TIMEOUT)
            
        Returns:
            bool: True if modal is present and visible
        """
        if timeout is None:
            timeout = SmartWaitOptimizer.QUICK_CHECK_TIMEOUT
        
        try:
            # Fast check - wait only for animation + padding
            element = WebDriverWait(driver, timeout).until(
                EC.presence_of_element_located(modal_locator)
            )
            # Verify it's visible
            return element.is_displayed()
        except:
            return False
    
    @staticmethod
    def wait_for_modal_animation(driver, modal_locator, timeout=None) -> bool:
        """
        Wait for modal animation to complete.
        
        Uses:
        - Normal animation timeout (350ms)
        - Waits for modal to be fully visible
        - Includes safety padding
        
        Args:
            driver: WebDriver instance
            modal_locator: Locator tuple (By, selector)
            timeout: Custom timeout (default: MODAL_DETECTION_TIMEOUT)
            
        Returns:
            bool: True if modal is present and visible after animation
        """
        if timeout is None:
            timeout = SmartWaitOptimizer.MODAL_DETECTION_TIMEOUT
        
        try:
            # Wait for modal to appear and be visible
            element = WebDriverWait(driver, timeout).until(
                EC.visibility_of_element_located(modal_locator)
            )
            return element.is_displayed()
        except:
            return False
    
    @staticmethod
    def smart_wait_for_dashboard(driver, cpid: str, password_used: str, max_wait: float = 5.0):
        """
        Smart wait for dashboard to load, with intelligent modal detection.
        
        Optimizations:
        1. Skip password reset check if password was already reset
        2. Skip profile incomplete check if profile is complete
        3. Use fast detection for modals
        4. Minimal waits with animation-aware timing
        
        Args:
            driver: WebDriver instance
            cpid: Student CPID
            password_used: Password that was used for login
            max_wait: Maximum wait time in seconds (default: 5.0)
        """
        start_time = time.time()
        
        # Wait for dashboard to load (navigation)
        try:
            WebDriverWait(driver, max_wait).until(
                lambda d: "/dashboard" in d.current_url or "/student" in d.current_url
            )
        except:
            pass  # Continue even if timeout
        
        # Quick check: Should we check for password reset modal?
        if SmartWaitOptimizer.should_check_password_reset(cpid, password_used):
            # Need to check - use fast detection
            from pages.mandatory_reset_page import MandatoryResetPage
            reset_page = MandatoryResetPage(driver)
            # Quick check (200ms)
            if SmartWaitOptimizer.quick_check_modal_present(
                driver, 
                reset_page.MODAL, 
                timeout=SmartWaitOptimizer.QUICK_CHECK_TIMEOUT
            ):
                # Modal is present - wait for animation to complete
                time.sleep(SmartWaitOptimizer.ANIMATION_NORMAL + SmartWaitOptimizer.SAFETY_PADDING)
        else:
            # Skip check - password was already reset
            print(f"⚡ Skipping password reset check (password already reset for {cpid})")
        
        # Quick check: Should we check for profile incomplete modal?
        if SmartWaitOptimizer.should_check_profile_incomplete(driver):
            # Need to check - use fast detection
            from pages.profile_incomplete_page import ProfileIncompletePage
            profile_incomplete = ProfileIncompletePage(driver)
            # Quick check (200ms)
            if SmartWaitOptimizer.quick_check_modal_present(
                driver,
                profile_incomplete.MODAL,
                timeout=SmartWaitOptimizer.QUICK_CHECK_TIMEOUT
            ):
                # Modal is present - wait for animation to complete
                time.sleep(SmartWaitOptimizer.ANIMATION_NORMAL + SmartWaitOptimizer.SAFETY_PADDING)
        else:
            # Skip check - profile is complete
            print(f"⚡ Skipping profile incomplete check (profile already complete)")
        
        elapsed = time.time() - start_time
        print(f"⚡ Smart dashboard wait completed in {elapsed:.3f}s")


