"""
Login Page Object Model for Cognitive Prism (Local)

Uses data-testid locators as per local implementation standards.
Scope: student_login
"""
import time
from selenium.webdriver.common.by import By
from pages.base_page import BasePage
from config.config import LOGIN_URL, TEST_USERNAME, TEST_PASSWORD, BASE_URL


class LoginPage(BasePage):
    """Page Object for Login Page - Using data-testid locators"""
    
    # Locators using data-testid (scope: student_login) - IMPLEMENTED ✅
    LOGIN_FORM = (By.CSS_SELECTOR, "[data-testid='student_login__form']")
    IDENTIFIER_INPUT = (By.CSS_SELECTOR, "[data-testid='student_login__identifier_input']")
    PASSWORD_INPUT = (By.CSS_SELECTOR, "[data-testid='student_login__password_input']")
    REMEMBER_CHECKBOX = (By.CSS_SELECTOR, "[data-testid='student_login__remember_checkbox']")
    ERROR_BANNER = (By.CSS_SELECTOR, "[data-testid='student_login__error_banner']")
    SUBMIT_BUTTON = (By.CSS_SELECTOR, "[data-testid='student_login__submit_button']")
    
    # Toast notification error (appears after login failure)
    # Uses data-testid attribute (implemented by UI team via toastHelpers.js)
    ERROR_TOAST = (By.CSS_SELECTOR, "[data-testid='student_login__error_toast']")
    
    def __init__(self, driver):
        """Initialize Login Page"""
        super().__init__(driver)
        self.url = LOGIN_URL
    
    def navigate(self):
        """
        Navigate to login page - optimized for speed
        
        If already logged in, will logout first, then navigate to login page.
        For fresh login, navigates to login page.
        """
        # CRITICAL: Check if already logged in BEFORE navigating
        current_url = self.driver.current_url
        if "/dashboard" in current_url or "/student" in current_url:
            # Already logged in - need to logout first
            print("🔄 Already logged in - logging out first...")
            try:
                from pages.student_nav_page import StudentNavPage
                nav_page = StudentNavPage(self.driver)
                nav_page.logout()
                # Wait for redirect to login (with longer timeout)
                from selenium.webdriver.support.ui import WebDriverWait
                from selenium.webdriver.support import expected_conditions as EC
                from config.config import MEDIUM_WAIT
                WebDriverWait(self.driver, MEDIUM_WAIT).until(
                    lambda d: "/login" in d.current_url or d.current_url.rstrip("/") == BASE_URL.rstrip("/") or "/" == d.current_url.rstrip("/")
                )
                print("✅ Logged out successfully - now on login page")
                # Brief wait for session to clear
                import time
                time.sleep(0.5)
            except Exception as e:
                # Logout failed - try clearing session and navigating
                print(f"⚠️  Logout failed during navigate: {e}, clearing session...")
                try:
                    # Clear session storage
                    self.driver.execute_script("window.localStorage.clear();")
                    self.driver.execute_script("window.sessionStorage.clear();")
                    # Navigate to login
                    self.driver.get(self.url)
                except:
                    self.driver.get(self.url)
        else:
            # Not logged in - navigate directly
            self.driver.get(self.url)
    
    def enter_identifier(self, identifier=TEST_USERNAME):
        """
        Enter student CPID/identifier
        
        Args:
            identifier: Student CPID or email
        """
        element = self.wait.wait_for_element_visible(self.IDENTIFIER_INPUT)
        element.clear()
        element.send_keys(identifier)
    
    def enter_password(self, password=TEST_PASSWORD):
        """
        Enter password
        
        Args:
            password: Password to enter
        """
        element = self.wait.wait_for_element_visible(self.PASSWORD_INPUT)
        element.clear()
        element.send_keys(password)
    
    def check_remember_me(self):
        """Check 'Remember me' checkbox"""
        checkbox = self.wait.wait_for_element_visible(self.REMEMBER_CHECKBOX)
        if not checkbox.is_selected():
            checkbox.click()
    
    def uncheck_remember_me(self):
        """Uncheck 'Remember me' checkbox"""
        checkbox = self.find_element(self.REMEMBER_CHECKBOX)
        if checkbox.is_selected():
            checkbox.click()
    
    def click_submit(self):
        """Click Sign In/Submit button"""
        button = self.wait.wait_for_element_clickable(self.SUBMIT_BUTTON)
        button.click()
    
    def is_error_visible(self):
        """
        Check if error toast/banner is visible
        
        Returns:
            bool: True if error is visible
        """
        try:
            # Toast notification appears immediately after submit - check quickly
            return self.is_element_visible(self.ERROR_TOAST, timeout=2)
        except:
            try:
                # Fallback to error banner
                return self.is_element_visible(self.ERROR_BANNER, timeout=1)
            except:
                return False
    
    def get_error_message(self):
        """
        Get error message if present
        
        Returns:
            str: Error message text or empty string
        """
        try:
            # Toast notification - appears immediately
            toast = self.find_element(self.ERROR_TOAST)
            if toast.is_displayed():
                return toast.text
        except:
            pass
        
        try:
            # Fallback to error banner
            banner = self.find_element(self.ERROR_BANNER)
            if banner.is_displayed():
                return banner.text
        except:
            pass
        
        return ""
    
    def login(self, identifier=TEST_USERNAME, password=None, remember_me=False):
        """
        Complete login flow with SMART password handling
        
        SMART MECHANISM:
        1. If password is provided, use it directly
        2. If password is None, try Excel password (TEST_PASSWORD) first
        3. If Excel password fails, automatically try Admin@123 (TEST_NEW_PASSWORD)
        4. This handles both fresh students and students who already reset password
        
        Args:
            identifier: Student CPID or email
            password: Password (if None, tries Excel password then Admin@123)
            remember_me: Whether to check remember me
        """
        from config.config import TEST_PASSWORD, TEST_NEW_PASSWORD
        
        # SMART PASSWORD HANDLING: Always try Excel password first, then Admin@123
        if password is None:
            # Start with Excel password (default from config)
            password = TEST_PASSWORD
            print(f"🔑 Trying Excel password first for {identifier}")
        
        self.navigate()
        
        # Wait for login form using data-testid (implemented ✅)
        from selenium.webdriver.support.ui import WebDriverWait
        from selenium.webdriver.support import expected_conditions as EC
        from config.config import SHORT_WAIT
        try:
            WebDriverWait(self.driver, SHORT_WAIT).until(
                EC.visibility_of_element_located(self.IDENTIFIER_INPUT)
            )
        except Exception as e:
            current_url = self.driver.current_url
            page_title = self.driver.title
            raise Exception(f"Login form not found. URL: {current_url}, Title: {page_title}, Error: {e}")
        
        # Form is ready - fill immediately (no waits)
        self.enter_identifier(identifier)
        self.enter_password(password)
        if remember_me:
            self.check_remember_me()
        
        # Click submit
        self.click_submit()
        
        # Immediately wait for either success (navigation) or error (toast)
        from config.config import MEDIUM_WAIT
        
        # Wait for either navigation OR error toast (whichever appears first)
        try:
            WebDriverWait(self.driver, MEDIUM_WAIT).until(
                lambda d: "/dashboard" in d.current_url 
                or "/student" in d.current_url 
                or "mandatory_reset" in d.page_source.lower()
                or len(d.find_elements(By.CSS_SELECTOR, "[data-testid='student_login__error_toast']")) > 0
            )
        except:
            pass  # Check what happened
        
        # Check result
        current_url = self.driver.current_url
        # Check if still on login page (root URL or contains "login")
        is_on_login_page = (
            current_url.rstrip("/") == BASE_URL.rstrip("/") or 
            current_url.rstrip("/") == f"{BASE_URL}/" or
            "login" in current_url.lower()
        )
        
        if is_on_login_page:
            # Still on login page - check for error toast
            if self.is_error_visible():
                error_msg = self.get_error_message()
                
                # SMART FALLBACK: If login failed with Excel password, try Admin@123
                # This handles students who have already reset their password
                if password != TEST_NEW_PASSWORD:
                    print(f"🔄 Excel password failed, trying Admin@123 (reset password)...")
                    time.sleep(3)
                    # Clear form and retry with Admin@123
                    self.enter_identifier(identifier)
                    self.enter_password(TEST_NEW_PASSWORD)
                    if remember_me:
                        self.check_remember_me()
                    self.click_submit()
                    
                    # Wait for navigation or error
                    try:
                        WebDriverWait(self.driver, MEDIUM_WAIT).until(
                            lambda d: "/dashboard" in d.current_url 
                            or "/student" in d.current_url 
                            or "mandatory_reset" in d.page_source.lower()
                            or len(d.find_elements(By.CSS_SELECTOR, "[data-testid='student_login__error_toast']")) > 0
                        )
                    except:
                        pass
                    
                    # Check result again - minimal wait for navigation (animation-aware)
                    # Animation: 300ms + 50ms padding = 350ms
                    time.sleep(0.35)
                    current_url = self.driver.current_url
                    
                    # Check if we successfully navigated away from login page
                    is_on_login_page = (
                        current_url.rstrip("/") == BASE_URL.rstrip("/") or 
                        current_url.rstrip("/") == f"{BASE_URL}/" or
                        "login" in current_url.lower()
                    )
                    
                    if not is_on_login_page:
                        # Successfully navigated away - login successful!
                        print(f"✅ Login successful with Admin@123 (password was already reset)!")
                        # Update password tracker for future reference
                        from utils.password_tracker import password_tracker
                        password_tracker.update_password(identifier, TEST_NEW_PASSWORD)
                        
                        # Check if password reset modal appeared (shouldn't, but verify)
                        from pages.mandatory_reset_page import MandatoryResetPage
                        reset_page = MandatoryResetPage(self.driver)
                        if reset_page.is_modal_present():
                            print("⚠️  Password reset modal appeared after login - this shouldn't happen with Admin@123")
                        return  # Success!
                    else:
                        # Still on login page - check for error
                        if self.is_error_visible():
                            error_msg2 = self.get_error_message()
                            raise Exception(f"Login failed with both passwords. Excel password: {error_msg}, Admin@123: {error_msg2}. URL: {current_url}")
                        else:
                            raise Exception(f"Login failed with both passwords. Excel password error: {error_msg}. URL: {current_url}")
                else:
                    # Already tried Admin@123, no fallback
                    raise Exception(f"Login failed with Admin@123: {error_msg}. URL: {current_url}")
            
            # No error but still on login - might be slow navigation, wait a bit more
            try:
                WebDriverWait(self.driver, SHORT_WAIT).until(
                    lambda d: "/dashboard" in d.current_url or "/student" in d.current_url
                )
            except:
                raise Exception(f"Login failed - still on login page. URL: {current_url}")
        else:
            # Success - navigated away from login
            # Check if password reset modal appeared (for first-time login)
            from pages.mandatory_reset_page import MandatoryResetPage
            reset_page = MandatoryResetPage(self.driver)
            if reset_page.is_modal_present():
                print("✅ Password reset modal detected after login - this is expected for first-time login")
                # Note: The test should handle password reset, not the login method
                # This is just for logging/information
