"""
Domain Assessment Page Object Model

Handles in-progress domain test experience.
Scope: domain_assessment, domain_question
"""
import time
from selenium.webdriver.common.by import By
from pages.base_page import BasePage


class DomainAssessmentPage(BasePage):
    """Page Object for Domain Assessment Page"""
    
    # Locators using data-testid (scope: domain_assessment)
    PAGE = (By.CSS_SELECTOR, "[data-testid='domain_assessment__page']")
    BACK_BUTTON = (By.CSS_SELECTOR, "[data-testid='domain_assessment__back_button']")
    PROGRESS_VALUE = (By.CSS_SELECTOR, "[data-testid='domain_assessment__progress_value']")
    TIMER_VALUE = (By.CSS_SELECTOR, "[data-testid='domain_assessment__timer_value']")
    
    # Navigation buttons
    PREV_BUTTON = (By.CSS_SELECTOR, "[data-testid='domain_assessment__prev_button']")
    NEXT_BUTTON = (By.CSS_SELECTOR, "[data-testid='domain_assessment__next_button']")
    SUBMIT_BUTTON = (By.CSS_SELECTOR, "[data-testid='domain_assessment__submit_button']")
    
    # Modals
    INSTRUCTIONS_MODAL = (By.CSS_SELECTOR, "[data-testid='domain_assessment__instructions_modal']")
    INSTRUCTIONS_MODAL_CONTENT = (By.CSS_SELECTOR, "[data-testid='domain_assessment__instructions_modal__content']")
    INSTRUCTIONS_CONTINUE_BUTTON = (By.CSS_SELECTOR, "[data-testid='domain_assessment__instructions_modal__continue_button']")
    
    SUBMIT_MODAL = (By.CSS_SELECTOR, "[data-testid='domain_assessment__submit_modal']")
    SUBMIT_MODAL_CONTENT = (By.CSS_SELECTOR, "[data-testid='domain_assessment__submit_modal__content']")
    SUBMIT_MODAL_REVIEW_BUTTON = (By.CSS_SELECTOR, "[data-testid='domain_assessment__submit_modal__review_button']")
    SUBMIT_MODAL_CONFIRM_BUTTON = (By.CSS_SELECTOR, "[data-testid='domain_assessment__submit_modal__confirm_button']")
    SUBMIT_MODAL_CANCEL_BUTTON = (By.CSS_SELECTOR, "[data-testid='domain_assessment__submit_modal__cancel_button']")
    
    GUIDANCE_MODAL = (By.CSS_SELECTOR, "[data-testid='domain_assessment__guidance_modal']")
    GUIDANCE_MODAL_CONTENT = (By.CSS_SELECTOR, "[data-testid='domain_assessment__guidance_modal__content']")
    GUIDANCE_DISMISS_BUTTON = (By.CSS_SELECTOR, "[data-testid='domain_assessment__guidance_modal__dismiss_button']")
    
    SUCCESS_MODAL = (By.CSS_SELECTOR, "[data-testid='domain_assessment__success_modal']")
    SUCCESS_MODAL_CONTENT = (By.CSS_SELECTOR, "[data-testid='domain_assessment__success_modal__content']")
    SUCCESS_MODAL_MESSAGE = (By.CSS_SELECTOR, "[data-testid='domain_assessment__success_modal__message']")
    
    # Action bar
    ACTION_BAR = (By.CSS_SELECTOR, "[data-testid='domain_assessment__action_bar']")
    
    def __init__(self, driver):
        """Initialize Domain Assessment Page"""
        super().__init__(driver)
    
    def wait_for_page_load(self):
        """Wait for domain assessment page to load"""
        super().wait_for_page_load()  # Call parent method
        # Wait for either the page container OR instructions modal (both indicate page loaded)
        try:
            # First check if instructions modal is present (that's also a valid state)
            if self.is_instructions_modal_present():
                return  # Page loaded, instructions modal showing
            # Otherwise wait for the actual page
            self.wait.wait_for_element_visible(self.PAGE, timeout=15)
            return  # Page element found
        except:
            # If page not found, check if instructions modal is there
            try:
                if self.is_instructions_modal_present():
                    return  # Instructions modal is present, page is loaded
            except:
                pass
            
            # If neither found, try waiting for action bar or header as fallback
            try:
                self.wait.wait_for_element_visible(self.ACTION_BAR, timeout=5)
                return  # Action bar found, page is loaded
            except:
                pass
            
            # Try to find a question element (if questions are visible, page is loaded)
            try:
                from selenium.webdriver.common.by import By
                from selenium.webdriver.support.ui import WebDriverWait
                from selenium.webdriver.support import expected_conditions as EC
                WebDriverWait(self.driver, 5).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, "[data-testid^='domain_question__']"))
                )
                return  # Questions found, page is loaded
            except:
                pass
            
            # Last resort: try back button (but don't fail if not found)
            try:
                self.wait.wait_for_element_visible(self.BACK_BUTTON, timeout=3)
                return  # Back button found, page is loaded
            except:
                pass
            
            # Final check: if URL is correct, consider page loaded (even if elements not found yet)
            current_url = self.driver.current_url
            if "/assessment/" in current_url and "/domain/" in current_url:
                # URL indicates we're on the right page - give it a moment and return
                import time
                time.sleep(1)  # Brief wait for elements to appear
                return  # URL indicates we're on the right page
            
            # If we get here, page might still be loading - don't raise exception
            # Let the caller handle it or wait longer
            pass
    
    def click_back(self):
        """Click back button - returns to domains page"""
        self.click_element(self.BACK_BUTTON)
        self.wait.wait_for_url_contains("/domains")
    
    def get_progress(self):
        """Get current progress value"""
        try:
            return self.get_text(self.PROGRESS_VALUE)
        except:
            return "0"
    
    def get_timer_value(self):
        """Get timer value"""
        try:
            return self.get_text(self.TIMER_VALUE)
        except:
            return ""
    
    def get_current_question_id(self):
        """
        Get current question ID from URL or page
        
        Returns:
            str: Question ID or None
        """
        import re
        current_url = self.driver.current_url
        match = re.search(r'/question/(\d+)', current_url)
        if match:
            return match.group(1)
        return None
    
    def get_question_element(self, question_id):
        """
        Get question shell element
        
        Args:
            question_id: Question ID
            
        Returns:
            WebElement: Question element
        """
        question_locator = (By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}']")
        return self.find_element(question_locator)
    
    def get_question_text(self, question_id):
        """Get question text"""
        text_locator = (By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__text']")
        return self.get_text(text_locator)
    
    def answer_multiple_choice(self, question_id, option_label):
        """
        Answer multiple choice question
        
        Args:
            question_id: Question ID
            option_label: Option label (a, b, c, etc.)
        """
        option_locator = (By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__option_{option_label}']")
        self.click_element(option_locator)
    
    def answer_true_false(self, question_id, value):
        """
        Answer true/false question
        
        Args:
            question_id: Question ID
            value: True or False (boolean or string "True"/"False")
        """
        # Convert boolean to string if needed
        if isinstance(value, bool):
            value_str = "True" if value else "False"
        else:
            value_str = str(value)
            if value_str.lower() in ['true', 'yes']:
                value_str = "True"
            elif value_str.lower() in ['false', 'no']:
                value_str = "False"
        
        tf_locator = (By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__truefalse_{value_str}']")
        self.click_element(tf_locator)
    
    def answer_rating_scale(self, question_id, score):
        """
        Answer rating scale question
        
        Args:
            question_id: Question ID
            score: Rating score (1-5, etc.)
        """
        rating_locator = (By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__rating_{score}']")
        self.click_element(rating_locator)
    
    def answer_rating(self, question_id, score):
        """Alias for answer_rating_scale"""
        self.answer_rating_scale(question_id, score)
    
    def answer_open_ended(self, question_id, text):
        """
        Answer open-ended question
        
        Args:
            question_id: Question ID
            text: Answer text
        """
        textarea_locator = (By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__textarea']")
        self.send_keys(textarea_locator, text)
    
    def answer_matrix(self, question_id, row_index, column_index):
        """
        Answer matrix question
        
        Args:
            question_id: Question ID
            row_index: Row index
            column_index: Column index
        """
        matrix_locator = (By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__matrix_{row_index}_{column_index}']")
        self.click_element(matrix_locator)
    
    def click_previous(self):
        """Click Previous button"""
        self.click_element(self.PREV_BUTTON)
        # Wait for previous question to load
        self.wait_for_page_load()
    
    def click_next(self):
        """Click Next button"""
        self.click_element(self.NEXT_BUTTON)
        # Wait for next question to load
        self.wait_for_page_load()
    
    def click_submit(self):
        """Click Submit button - opens submit confirmation modal"""
        self.click_element(self.SUBMIT_BUTTON)
        # Wait for submit modal
        self.wait.wait_for_element_visible(self.SUBMIT_MODAL)
    
    def confirm_submit(self):
        """Confirm submission - clicks confirm in submit modal"""
        self.click_element(self.SUBMIT_MODAL_CONFIRM_BUTTON)
        # Wait for success modal
        self.wait.wait_for_element_visible(self.SUCCESS_MODAL)
    
    def review_before_submit(self):
        """Click review button in submit modal"""
        self.click_element(self.SUBMIT_MODAL_REVIEW_BUTTON)
        # Modal closes, back to questions
    
    def dismiss_guidance(self):
        """Dismiss guidance modal if present"""
        try:
            if self.is_element_visible(self.GUIDANCE_MODAL, timeout=2):
                self.click_element(self.GUIDANCE_DISMISS_BUTTON)
                # Wait for modal to close
                self.wait.wait_for_element_invisible(self.GUIDANCE_MODAL, timeout=5)
        except:
            pass
    
    def is_instructions_modal_present(self):
        """Check if instructions modal is present"""
        try:
            return self.is_element_visible(self.INSTRUCTIONS_MODAL, timeout=3)
        except:
            return False
    
    def dismiss_instructions_modal(self):
        """Dismiss instructions modal by clicking continue button"""
        try:
            if self.is_instructions_modal_present():
                self.click_element(self.INSTRUCTIONS_CONTINUE_BUTTON)
                # Wait for modal to close
                self.wait.wait_for_element_invisible(self.INSTRUCTIONS_MODAL, timeout=5)
        except:
            pass
    
    def wait_for_success_modal(self):
        """Wait for success modal after submission"""
        self.wait.wait_for_element_visible(self.SUCCESS_MODAL)
    
    def is_submit_modal_present(self):
        """Check if submit confirmation modal is present"""
        try:
            return self.is_element_visible(self.SUBMIT_MODAL, timeout=3)
        except:
            return False
    
    def is_success_modal_present(self):
        """Check if success modal is present"""
        try:
            return self.is_element_visible(self.SUCCESS_MODAL, timeout=5)
        except:
            return False
    
    def close_success_modal(self):
        """Close success modal if present"""
        try:
            # Success modal usually auto-closes or redirects
            # Wait for it to disappear (no fixed sleep needed)
            from selenium.webdriver.support.ui import WebDriverWait
            from selenium.webdriver.support import expected_conditions as EC
            from config.config import SHORT_WAIT
            WebDriverWait(self.driver, SHORT_WAIT).until(
                EC.invisibility_of_element_located(self.SUCCESS_MODAL)
            )
        except:
            # Modal might have already closed or redirected
            pass
    
    def is_next_button_visible(self):
        """Check if next button is visible and enabled"""
        try:
            next_btn = self.find_element(self.NEXT_BUTTON)
            return next_btn.is_displayed() and next_btn.is_enabled()
        except:
            return False
    
    def get_all_questions(self):
        """
        Get all question IDs on current page
        
        Returns:
            list: List of question IDs
        """
        import re
        questions = self.driver.find_elements(By.CSS_SELECTOR, "[data-testid^='domain_question__']")
        question_ids = []
        for question in questions:
            test_id = question.get_attribute("data-testid")
            if test_id:
                match = re.search(r'domain_question__(\d+)', test_id)
                if match:
                    q_id = match.group(1)
                    if q_id not in question_ids:
                        question_ids.append(q_id)
        return question_ids
    
    def get_question_type(self, question_id):
        """
        Determine question type by checking available answer options
        
        Args:
            question_id: Question ID
            
        Returns:
            str: Question type (multiple_choice, true_false, rating_scale, open_ended, matrix)
        """
        try:
            # Check for multiple choice options (A, B, C, D, E)
            if self.is_element_present((By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__option_A']"), timeout=1):
                return "multiple_choice"
            
            # Check for true/false
            if self.is_element_present((By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__truefalse_True']"), timeout=1):
                return "true_false"
            
            # Check for rating scale
            if self.is_element_present((By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__rating_1']"), timeout=1):
                return "rating_scale"
            
            # Check for open ended
            if self.is_element_present((By.CSS_SELECTOR, f"[data-testid='domain_question__{question_id}__textarea']"), timeout=1):
                return "open_ended"
            
            # Check for matrix
            if self.is_element_present((By.CSS_SELECTOR, f"[data-testid^='domain_question__{question_id}__matrix_']"), timeout=1):
                return "matrix"
            
            return "unknown"
        except:
            return "unknown"
    
    def get_question_options(self, question_id):
        """
        Get available options for multiple choice question
        
        Args:
            question_id: Question ID
            
        Returns:
            list: List of option labels (a, b, c, etc.)
        """
        import re
        options = self.driver.find_elements(By.CSS_SELECTOR, f"[data-testid^='domain_question__{question_id}__option_']")
        option_labels = []
        for option in options:
            test_id = option.get_attribute("data-testid")
            if test_id:
                match = re.search(r'option_([a-z0-9]+)', test_id)
                if match:
                    option_labels.append(match.group(1))
        return option_labels
    
    def select_option(self, question_id, option_label):
        """Select an option for multiple choice question"""
        self.answer_multiple_choice(question_id, option_label)
    
    def select_true_false(self, question_id, value):
        """Select true/false value"""
        self.answer_true_false(question_id, value)
    
    def select_rating(self, question_id, score):
        """Select rating score"""
        self.answer_rating(question_id, score)
    
    def enter_open_ended(self, question_id, text):
        """Enter text for open-ended question"""
        self.answer_open_ended(question_id, text)
    
    def select_matrix_cell(self, question_id, row_index, column_index, value=True):
        """Select matrix cell"""
        self.answer_matrix(question_id, row_index, column_index)
    
    def get_matrix_dimensions(self, question_id):
        """
        Get matrix dimensions
        
        Returns:
            tuple: (rows, cols)
        """
        import re
        matrix_cells = self.driver.find_elements(By.CSS_SELECTOR, f"[data-testid^='domain_question__{question_id}__matrix_']")
        rows = set()
        cols = set()
        for cell in matrix_cells:
            test_id = cell.get_attribute("data-testid")
            if test_id:
                match = re.search(r'matrix_(\d+)_(\d+)', test_id)
                if match:
                    rows.add(int(match.group(1)))
                    cols.add(int(match.group(2)))
        return (len(rows) if rows else 0, len(cols) if cols else 0)

