"""
Randomized Wait Utility for Realistic Test Behavior

World-class utility to simulate realistic human behavior with randomized waits.
Instead of hardcoded waits, uses intelligent random delays based on context.
"""
import random
import time
from typing import Optional


class RandomizedWait:
    """Utility class for randomized, realistic waits"""
    
    # Wait ranges (in seconds) for different contexts
    WAIT_RANGES = {
        # Question answering - varies by question type
        'question_answer': {
            'rating_scale': (1, 4),      # Quick selection: 1-4 seconds
            'multiple_choice': (2, 6),    # Reading options: 2-6 seconds
            'true_false': (1, 3),         # Binary choice: 1-3 seconds
            'open_ended': (5, 15),       # Typing response: 5-15 seconds
            'matrix': (3, 8),            # Multiple selections: 3-8 seconds
            'default': (2, 5)            # Default: 2-5 seconds
        },
        
        # Navigation between questions
        'question_navigation': {
            'next': (1, 3),              # Clicking next: 1-3 seconds
            'previous': (1, 2),          # Going back: 1-2 seconds
            'default': (1, 2)            # Default navigation: 1-2 seconds
        },
        
        # Page/UI loading
        'page_load': {
            'initial': (2, 4),           # Initial page load: 2-4 seconds
            'navigation': (1, 3),        # Navigation load: 1-3 seconds
            'modal': (0.5, 1.5),         # Modal appearance: 0.5-1.5 seconds
            'default': (1, 2)            # Default load: 1-2 seconds
        },
        
        # Form interactions
        'form_interaction': {
            'input': (0.5, 1.5),        # Text input: 0.5-1.5 seconds
            'click': (0.3, 1),           # Button click: 0.3-1 second
            'select': (1, 2),            # Dropdown select: 1-2 seconds
            'default': (0.5, 1)          # Default: 0.5-1 second
        },
        
        # Submission and confirmation
        'submission': {
            'submit': (2, 4),            # Submit action: 2-4 seconds
            'confirm': (1, 2),           # Confirmation: 1-2 seconds
            'feedback': (3, 8),          # Writing feedback: 3-8 seconds
            'default': (1, 3)            # Default: 1-3 seconds
        },
        
        # Error recovery
        'error_recovery': {
            'retry': (1, 2),             # Retry after error: 1-2 seconds
            'wait': (2, 4),              # Wait for state change: 2-4 seconds
            'default': (1, 3)            # Default: 1-3 seconds
        }
    }
    
    @staticmethod
    def wait_for_question_answer(question_type: str = 'default') -> float:
        """
        Wait after answering a question (realistic thinking time)
        
        Args:
            question_type: Type of question (rating_scale, multiple_choice, etc.)
            
        Returns:
            float: Actual wait time used
        """
        ranges = RandomizedWait.WAIT_RANGES['question_answer']
        min_wait, max_wait = ranges.get(question_type, ranges['default'])
        wait_time = random.uniform(min_wait, max_wait)
        time.sleep(wait_time)
        return wait_time
    
    @staticmethod
    def wait_for_navigation(action: str = 'next') -> float:
        """
        Wait after navigation action (page load time)
        
        Args:
            action: Navigation action (next, previous, etc.)
            
        Returns:
            float: Actual wait time used
        """
        ranges = RandomizedWait.WAIT_RANGES['question_navigation']
        min_wait, max_wait = ranges.get(action, ranges['default'])
        wait_time = random.uniform(min_wait, max_wait)
        time.sleep(wait_time)
        return wait_time
    
    @staticmethod
    def wait_for_page_load(load_type: str = 'default') -> float:
        """
        Wait for page/UI to load
        
        Args:
            load_type: Type of load (initial, navigation, modal, etc.)
            
        Returns:
            float: Actual wait time used
        """
        ranges = RandomizedWait.WAIT_RANGES['page_load']
        min_wait, max_wait = ranges.get(load_type, ranges['default'])
        wait_time = random.uniform(min_wait, max_wait)
        time.sleep(wait_time)
        return wait_time
    
    @staticmethod
    def wait_for_form_interaction(interaction_type: str = 'default') -> float:
        """
        Wait for form interaction (click, input, select)
        
        Args:
            interaction_type: Type of interaction (input, click, select, etc.)
            
        Returns:
            float: Actual wait time used
        """
        ranges = RandomizedWait.WAIT_RANGES['form_interaction']
        min_wait, max_wait = ranges.get(interaction_type, ranges['default'])
        wait_time = random.uniform(min_wait, max_wait)
        time.sleep(wait_time)
        return wait_time
    
    @staticmethod
    def wait_for_submission(action: str = 'default') -> float:
        """
        Wait for submission-related actions
        
        Args:
            action: Submission action (submit, confirm, feedback, etc.)
            
        Returns:
            float: Actual wait time used
        """
        ranges = RandomizedWait.WAIT_RANGES['submission']
        min_wait, max_wait = ranges.get(action, ranges['default'])
        wait_time = random.uniform(min_wait, max_wait)
        time.sleep(wait_time)
        return wait_time
    
    @staticmethod
    def wait_for_error_recovery(recovery_type: str = 'default') -> float:
        """
        Wait for error recovery
        
        Args:
            recovery_type: Type of recovery (retry, wait, etc.)
            
        Returns:
            float: Actual wait time used
        """
        ranges = RandomizedWait.WAIT_RANGES['error_recovery']
        min_wait, max_wait = ranges.get(recovery_type, ranges['default'])
        wait_time = random.uniform(min_wait, max_wait)
        time.sleep(wait_time)
        return wait_time
    
    @staticmethod
    def random_wait(min_seconds: float, max_seconds: float) -> float:
        """
        Generic random wait between min and max seconds
        
        Args:
            min_seconds: Minimum wait time
            max_seconds: Maximum wait time
            
        Returns:
            float: Actual wait time used
        """
        wait_time = random.uniform(min_seconds, max_seconds)
        time.sleep(wait_time)
        return wait_time
    
    @staticmethod
    def smart_wait(context: str, sub_context: Optional[str] = None) -> float:
        """
        Smart wait that automatically selects appropriate wait range based on context
        
        Args:
            context: Main context (question_answer, navigation, page_load, etc.)
            sub_context: Sub-context (question_type, action_type, etc.)
            
        Returns:
            float: Actual wait time used
        """
        if context not in RandomizedWait.WAIT_RANGES:
            context = 'page_load'  # Default fallback
        
        ranges = RandomizedWait.WAIT_RANGES[context]
        
        if sub_context and sub_context in ranges:
            min_wait, max_wait = ranges[sub_context]
        else:
            min_wait, max_wait = ranges['default']
        
        wait_time = random.uniform(min_wait, max_wait)
        time.sleep(wait_time)
        return wait_time


