"""
DOM Inspector - World-Class Debug Tool

Purpose: Inspect actual DOM structure at runtime to identify correct locators
Usage: Run this script to quickly identify element structures without running full tests

This saves time by:
1. Inspecting DOM directly without full test execution
2. Testing multiple locator strategies quickly
3. Identifying correct selectors before updating code
4. Verifying element presence and visibility
"""
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 config.config import TEST_USERNAME, TEST_PASSWORD, BASE_URL
import time
import json


class DOMInspector:
    """World-Class DOM Inspector for Quick Debugging"""
    
    def __init__(self, driver):
        self.driver = driver
    
    def find_elements_by_strategies(self, element_name, strategies):
        """
        Try multiple locator strategies and report results
        
        Args:
            element_name: Name of element for logging
            strategies: List of (strategy_name, locator) tuples
        """
        print(f"\n{'='*80}")
        print(f"🔍 INSPECTING: {element_name}")
        print(f"{'='*80}")
        
        results = []
        for strategy_name, locator in strategies:
            try:
                if isinstance(locator, tuple):
                    by_type, selector = locator
                else:
                    by_type, selector = locator[0], locator[1]
                
                print(f"\n📋 Strategy: {strategy_name}")
                print(f"   Locator: {by_type} = '{selector}'")
                
                # Try to find element
                elements = self.driver.find_elements(by_type, selector)
                
                if elements:
                    print(f"   ✅ Found {len(elements)} element(s)")
                    
                    for idx, elem in enumerate(elements):
                        try:
                            is_displayed = elem.is_displayed()
                            is_enabled = elem.is_enabled() if hasattr(elem, 'is_enabled') else 'N/A'
                            tag_name = elem.tag_name
                            text = elem.text[:100] if elem.text else 'No text'
                            
                            # Get attributes
                            attrs = {}
                            try:
                                attrs['id'] = elem.get_attribute('id')
                                attrs['class'] = elem.get_attribute('class')
                                attrs['data-testid'] = elem.get_attribute('data-testid')
                                attrs['name'] = elem.get_attribute('name')
                                attrs['type'] = elem.get_attribute('type')
                            except:
                                pass
                            
                            print(f"   Element {idx + 1}:")
                            print(f"     - Tag: {tag_name}")
                            print(f"     - Displayed: {is_displayed}")
                            print(f"     - Enabled: {is_enabled}")
                            print(f"     - Text: {text}")
                            print(f"     - Attributes: {json.dumps({k: v for k, v in attrs.items() if v}, indent=8)}")
                            
                            # Get outer HTML snippet
                            try:
                                outer_html = elem.get_attribute('outerHTML')
                                if outer_html:
                                    snippet = outer_html[:200] + '...' if len(outer_html) > 200 else outer_html
                                    print(f"     - HTML: {snippet}")
                            except:
                                pass
                            
                            results.append({
                                'strategy': strategy_name,
                                'locator': selector,
                                'found': True,
                                'displayed': is_displayed,
                                'element': elem,
                                'attributes': attrs
                            })
                        except Exception as e:
                            print(f"   ⚠️  Error inspecting element {idx + 1}: {e}")
                else:
                    print(f"   ❌ No elements found")
                    results.append({
                        'strategy': strategy_name,
                        'locator': selector,
                        'found': False
                    })
            except Exception as e:
                print(f"   ❌ Error with strategy: {e}")
                results.append({
                    'strategy': strategy_name,
                    'locator': selector,
                    'found': False,
                    'error': str(e)
                })
        
        return results
    
    def inspect_modal_structure(self):
        """Inspect password reset modal structure"""
        print(f"\n{'='*80}")
        print("🔍 INSPECTING: Password Reset Modal Structure")
        print(f"{'='*80}")
        
        # Check for modal overlay
        print("\n📋 Checking for modal overlay...")
        overlay_selectors = [
            ("CSS - Exact", (By.CSS_SELECTOR, "div.fixed.inset-0.bg-black\\/60.z-\\[99999\\]")),
            ("CSS - Partial", (By.CSS_SELECTOR, "div[class*='fixed'][class*='inset-0'][class*='bg-black'][class*='z-[99999]']")),
            ("CSS - Generic", (By.CSS_SELECTOR, "div.fixed.inset-0.bg-black")),
            ("XPath - Fixed inset", (By.XPATH, "//div[contains(@class, 'fixed') and contains(@class, 'inset-0')]")),
        ]
        
        overlay_results = self.find_elements_by_strategies("Modal Overlay", overlay_selectors)
        
        # Check for modal content
        print("\n📋 Checking for modal content...")
        content_selectors = [
            ("Text - Welcome", (By.XPATH, "//*[contains(text(), 'Welcome to Cognitive Prism')]")),
            ("Text - Reset Password", (By.XPATH, "//*[contains(text(), 'Password Reset Required')]")),
            ("Text - Secure Account", (By.XPATH, "//*[contains(text(), 'Secure Your Account')]")),
        ]
        
        content_results = self.find_elements_by_strategies("Modal Content", content_selectors)
        
        return overlay_results, content_results
    
    def inspect_continue_button(self):
        """Inspect Continue button structure"""
        print(f"\n{'='*80}")
        print("🔍 INSPECTING: Continue Button")
        print(f"{'='*80}")
        
        strategies = [
            ("data-testid", (By.CSS_SELECTOR, "[data-testid='mandatory_reset__continue_button']")),
            ("XPath - Span text", (By.XPATH, "//span[contains(text(), 'Continue to Reset Password')]")),
            ("XPath - Button with span", (By.XPATH, "//button[.//span[contains(text(), 'Continue')]]")),
            ("XPath - Button contains Continue", (By.XPATH, "//button[contains(., 'Continue')]")),
            ("XPath - Button with Reset", (By.XPATH, "//button[contains(., 'Reset Password')]")),
            ("XPath - Any button in modal", (By.XPATH, "//div[contains(@class, 'fixed')]//button")),
            ("XPath - Button with arrow icon", (By.XPATH, "//button[.//*[local-name()='svg']]")),
        ]
        
        return self.find_elements_by_strategies("Continue Button", strategies)
    
    def inspect_form_fields(self):
        """Inspect password reset form fields"""
        print(f"\n{'='*80}")
        print("🔍 INSPECTING: Password Reset Form Fields")
        print(f"{'='*80}")
        
        strategies = [
            ("Form container", (By.CSS_SELECTOR, "[data-testid='mandatory_reset__form']")),
            ("Current password input", (By.CSS_SELECTOR, "[data-testid='mandatory_reset__current_password_input']")),
            ("New password input", (By.CSS_SELECTOR, "[data-testid='mandatory_reset__new_password_input']")),
            ("Confirm password input", (By.CSS_SELECTOR, "[data-testid='mandatory_reset__confirm_password_input']")),
            ("Submit button", (By.CSS_SELECTOR, "[data-testid='mandatory_reset__submit_button']")),
            ("XPath - Input by name", (By.XPATH, "//input[@name='currentPassword' or @name='newPassword' or @name='confirmPassword']")),
            ("XPath - Input type password", (By.XPATH, "//input[@type='password']")),
        ]
        
        return self.find_elements_by_strategies("Form Fields", strategies)
    
    def get_page_source_snippet(self, search_text, context_lines=5):
        """Get snippet of page source around specific text"""
        try:
            page_source = self.driver.page_source
            if search_text.lower() in page_source.lower():
                index = page_source.lower().index(search_text.lower())
                start = max(0, index - 500)
                end = min(len(page_source), index + 500)
                snippet = page_source[start:end]
                return snippet
            return None
        except:
            return None
    
    def inspect_page_source(self):
        """Inspect page source for key indicators"""
        print(f"\n{'='*80}")
        print("🔍 INSPECTING: Page Source Indicators")
        print(f"{'='*80}")
        
        indicators = [
            "Welcome to Cognitive Prism",
            "Password Reset Required",
            "Continue to Reset Password",
            "mandatory_reset",
            "data-testid",
        ]
        
        page_source = self.driver.page_source.lower()
        
        for indicator in indicators:
            found = indicator.lower() in page_source
            status = "✅" if found else "❌"
            print(f"{status} '{indicator}': {'Found' if found else 'Not found'}")
            
            if found:
                snippet = self.get_page_source_snippet(indicator)
                if snippet:
                    print(f"   Context: {snippet[:300]}...")


def debug_password_reset_modal():
    """Main debug function for password reset modal"""
    print("=" * 80)
    print("🔍 DOM INSPECTOR - Password Reset Modal Debug")
    print("=" * 80)
    print("\n🎯 Purpose: Inspect actual DOM structure to identify correct locators")
    print("💡 This saves time by avoiding full test execution\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)
    inspector = DOMInspector(driver)
    
    try:
        # Step 1: Login
        print(f"\n{'='*80}")
        print("STEP 1: LOGIN")
        print(f"{'='*80}")
        login_page = LoginPage(driver)
        login_page.login(identifier=TEST_USERNAME, password=TEST_PASSWORD)
        print(f"✅ Login completed")
        print(f"   Current URL: {driver.current_url}")
        time.sleep(2)
        
        # Step 2: Inspect modal structure
        print(f"\n{'='*80}")
        print("STEP 2: INSPECT MODAL STRUCTURE")
        print(f"{'='*80}")
        overlay_results, content_results = inspector.inspect_modal_structure()
        
        # Step 3: Inspect Continue button
        print(f"\n{'='*80}")
        print("STEP 3: INSPECT CONTINUE BUTTON")
        print(f"{'='*80}")
        continue_results = inspector.inspect_continue_button()
        
        # Step 4: Inspect form fields (if form is visible)
        print(f"\n{'='*80}")
        print("STEP 4: INSPECT FORM FIELDS")
        print(f"{'='*80}")
        form_results = inspector.inspect_form_fields()
        
        # Step 5: Inspect page source
        inspector.inspect_page_source()
        
        # Step 6: Summary and recommendations
        print(f"\n{'='*80}")
        print("📊 SUMMARY & RECOMMENDATIONS")
        print(f"{'='*80}")
        
        # Find working strategies
        working_overlay = [r for r in overlay_results if r.get('found') and r.get('displayed')]
        working_continue = [r for r in continue_results if r.get('found') and r.get('displayed')]
        working_form = [r for r in form_results if r.get('found') and r.get('displayed')]
        
        print(f"\n✅ Working Strategies Found:")
        if working_overlay:
            print(f"   Modal Overlay: {working_overlay[0]['strategy']} - {working_overlay[0]['locator']}")
        if working_continue:
            print(f"   Continue Button: {working_continue[0]['strategy']} - {working_continue[0]['locator']}")
        if working_form:
            print(f"   Form Fields: {working_form[0]['strategy']} - {working_form[0]['locator']}")
        
        if not working_continue:
            print(f"\n⚠️  Continue Button Not Found!")
            print(f"   Recommendations:")
            print(f"   1. Check if button is inside a shadow DOM")
            print(f"   2. Check if button has animation delays")
            print(f"   3. Try JavaScript-based element finding")
            print(f"   4. Check if button is inside a specific container")
        
        print(f"\n⏸️  Browser will stay open for 30 seconds for manual inspection...")
        print(f"   You can inspect the DOM manually in browser DevTools")
        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__":
    debug_password_reset_modal()


