#!/usr/bin/env python3
"""
Comprehensive Playwright exploration script for the asset management system.
This script will login, navigate through all features, and document everything with screenshots.
"""

import asyncio
import os
from datetime import datetime
from playwright.async_api import async_playwright
import json

class AssetManagementExplorer:
    def __init__(self):
        self.base_url = "https://secure-suite-b60fbae0.base44.app/"
        self.email = "junsuwhy@gmail.com"
        self.password = "2!b*S5fWOVyu3v*"
        self.screenshots_dir = "/home/debian/Projects/isoAgent/screenshots"
        self.exploration_data = {}
        self.current_step = 0
        
    async def setup(self):
        """Setup directories and initial configuration"""
        os.makedirs(self.screenshots_dir, exist_ok=True)
        print(f"Screenshots will be saved to: {self.screenshots_dir}")
        
    async def take_screenshot(self, page, name, description=""):
        """Take a screenshot and save with timestamp"""
        self.current_step += 1
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"{self.current_step:02d}_{timestamp}_{name}.png"
        filepath = os.path.join(self.screenshots_dir, filename)
        
        await page.screenshot(path=filepath, full_page=True)
        print(f"Screenshot saved: {filename}")
        
        # Store exploration data
        self.exploration_data[name] = {
            "step": self.current_step,
            "screenshot": filename,
            "description": description,
            "url": page.url,
            "timestamp": timestamp
        }
        
        return filepath
    
    async def analyze_page_elements(self, page):
        """Analyze and document all interactive elements on the current page"""
        elements = {}
        
        # Get all buttons
        buttons = await page.locator('button, input[type="button"], input[type="submit"]').all()
        button_info = []
        for button in buttons:
            try:
                text = await button.text_content()
                is_visible = await button.is_visible()
                is_enabled = await button.is_enabled()
                button_info.append({
                    "text": text.strip() if text else "",
                    "visible": is_visible,
                    "enabled": is_enabled
                })
            except:
                pass
        elements["buttons"] = button_info
        
        # Get all links
        links = await page.locator('a').all()
        link_info = []
        for link in links:
            try:
                text = await link.text_content()
                href = await link.get_attribute('href')
                is_visible = await link.is_visible()
                if is_visible and text and text.strip():
                    link_info.append({
                        "text": text.strip(),
                        "href": href,
                        "visible": is_visible
                    })
            except:
                pass
        elements["links"] = link_info
        
        # Get all form inputs
        inputs = await page.locator('input, textarea, select').all()
        input_info = []
        for input_elem in inputs:
            try:
                input_type = await input_elem.get_attribute('type')
                name = await input_elem.get_attribute('name')
                placeholder = await input_elem.get_attribute('placeholder')
                required = await input_elem.get_attribute('required')
                is_visible = await input_elem.is_visible()
                
                if is_visible:
                    input_info.append({
                        "type": input_type,
                        "name": name,
                        "placeholder": placeholder,
                        "required": required is not None,
                        "visible": is_visible
                    })
            except:
                pass
        elements["inputs"] = input_info
        
        # Get navigation menus
        nav_elements = await page.locator('nav, .nav, .menu, .sidebar').all()
        nav_info = []
        for nav in nav_elements:
            try:
                text = await nav.text_content()
                is_visible = await nav.is_visible()
                if is_visible and text:
                    nav_info.append({
                        "text": text.strip()[:200],  # Limit text length
                        "visible": is_visible
                    })
            except:
                pass
        elements["navigation"] = nav_info
        
        return elements
    
    async def login(self, page):
        """Login to the system"""
        print("Navigating to login page...")
        await page.goto(self.base_url)
        await page.wait_for_load_state('networkidle')
        
        # Take initial screenshot
        await self.take_screenshot(page, "01_initial_page", "Initial page load")
        
        # Look for login form elements
        print("Looking for login form...")
        
        # Try common email field selectors
        email_selectors = [
            'input[type="email"]',
            'input[name="email"]',
            'input[name="username"]',
            'input[id="email"]',
            'input[id="username"]',
            'input[placeholder*="email" i]',
            'input[placeholder*="username" i]'
        ]
        
        email_field = None
        for selector in email_selectors:
            try:
                email_field = page.locator(selector).first
                if await email_field.is_visible():
                    break
            except:
                continue
        
        if not email_field or not await email_field.is_visible():
            print("Could not find email field, analyzing page structure...")
            elements = await self.analyze_page_elements(page)
            print("Available inputs:", elements.get("inputs", []))
            raise Exception("Email field not found")
        
        # Try common password field selectors
        password_selectors = [
            'input[type="password"]',
            'input[name="password"]',
            'input[id="password"]'
        ]
        
        password_field = None
        for selector in password_selectors:
            try:
                password_field = page.locator(selector).first
                if await password_field.is_visible():
                    break
            except:
                continue
        
        if not password_field or not await password_field.is_visible():
            print("Could not find password field")
            raise Exception("Password field not found")
        
        # Fill login form
        print("Filling login credentials...")
        await email_field.fill(self.email)
        await password_field.fill(self.password)
        
        await self.take_screenshot(page, "02_login_form_filled", "Login form with credentials filled")
        
        # Look for submit button
        submit_selectors = [
            'input[type="submit"]',
            'button[type="submit"]',
            'button:has-text("Login")',
            'button:has-text("Sign In")',
            'button:has-text("Log In")',
            '.login-button',
            '.submit-button'
        ]
        
        submit_button = None
        for selector in submit_selectors:
            try:
                submit_button = page.locator(selector).first
                if await submit_button.is_visible():
                    break
            except:
                continue
        
        if not submit_button or not await submit_button.is_visible():
            print("Submit button not found, trying Enter key...")
            await password_field.press('Enter')
        else:
            print("Clicking submit button...")
            await submit_button.click()
        
        # Wait for navigation after login
        try:
            await page.wait_for_load_state('networkidle', timeout=10000)
        except:
            pass
        
        await asyncio.sleep(2)  # Additional wait for any dynamic content
        
        print(f"After login attempt, current URL: {page.url}")
        await self.take_screenshot(page, "03_after_login", "Page after login attempt")
        
        return True
    
    async def explore_navigation_menu(self, page):
        """Explore all navigation menu items"""
        print("Analyzing navigation structure...")
        
        # Common selectors for navigation menus
        nav_selectors = [
            'nav a',
            '.nav a',
            '.menu a',
            '.navbar a',
            '.sidebar a',
            '[role="navigation"] a',
            '.navigation a'
        ]
        
        all_nav_links = []
        
        for selector in nav_selectors:
            try:
                links = await page.locator(selector).all()
                for link in links:
                    try:
                        text = await link.text_content()
                        href = await link.get_attribute('href')
                        is_visible = await link.is_visible()
                        
                        if is_visible and text and text.strip():
                            all_nav_links.append({
                                "text": text.strip(),
                                "href": href,
                                "element": link
                            })
                    except:
                        pass
            except:
                pass
        
        # Remove duplicates based on text
        unique_links = []
        seen_texts = set()
        for link in all_nav_links:
            if link["text"] not in seen_texts:
                unique_links.append(link)
                seen_texts.add(link["text"])
        
        print(f"Found {len(unique_links)} unique navigation links:")
        for link in unique_links:
            print(f"  - {link['text']} -> {link['href']}")
        
        return unique_links
    
    async def explore_menu_item(self, page, link_info, index):
        """Explore a specific menu item"""
        try:
            print(f"\n--- Exploring: {link_info['text']} ---")
            
            # Navigate to the link
            if link_info['href'] and link_info['href'].startswith('http'):
                await page.goto(link_info['href'])
            else:
                await link_info['element'].click()
            
            await page.wait_for_load_state('networkidle', timeout=10000)
            await asyncio.sleep(2)  # Wait for any dynamic content
            
            # Take screenshot
            screenshot_name = f"menu_{index:02d}_{link_info['text'].lower().replace(' ', '_').replace('/', '_')}"
            await self.take_screenshot(page, screenshot_name, f"Navigation to: {link_info['text']}")
            
            # Analyze page elements
            elements = await self.analyze_page_elements(page)
            
            # Store detailed analysis
            self.exploration_data[screenshot_name].update({
                "menu_item": link_info['text'],
                "navigation_path": link_info['text'],
                "page_elements": elements
            })
            
            # Look for sub-navigation or additional features
            await self.explore_sub_features(page, link_info['text'], index)
            
        except Exception as e:
            print(f"Error exploring {link_info['text']}: {str(e)}")
    
    async def explore_sub_features(self, page, parent_name, parent_index):
        """Explore sub-features within a page"""
        try:
            # Look for tabs, accordions, or other sub-navigation
            sub_nav_selectors = [
                '.tab a, .tabs a',
                '.accordion-header',
                '.dropdown-menu a',
                '.sub-menu a',
                '.category a',
                'button[data-toggle]',
                '[role="tab"]'
            ]
            
            sub_features = []
            for selector in sub_nav_selectors:
                try:
                    elements = await page.locator(selector).all()
                    for element in elements:
                        try:
                            text = await element.text_content()
                            is_visible = await element.is_visible()
                            if is_visible and text and text.strip():
                                sub_features.append({
                                    "text": text.strip(),
                                    "element": element
                                })
                        except:
                            pass
                except:
                    pass
            
            # Explore each sub-feature
            for i, sub_feature in enumerate(sub_features[:5]):  # Limit to 5 sub-features per page
                try:
                    print(f"  Exploring sub-feature: {sub_feature['text']}")
                    await sub_feature['element'].click()
                    await asyncio.sleep(1)
                    
                    screenshot_name = f"sub_{parent_index:02d}_{i:02d}_{sub_feature['text'].lower().replace(' ', '_')}"
                    await self.take_screenshot(page, screenshot_name, f"Sub-feature: {sub_feature['text']} in {parent_name}")
                    
                    # Analyze elements
                    elements = await self.analyze_page_elements(page)
                    self.exploration_data[screenshot_name].update({
                        "parent_menu": parent_name,
                        "sub_feature": sub_feature['text'],
                        "navigation_path": f"{parent_name} > {sub_feature['text']}",
                        "page_elements": elements
                    })
                    
                except Exception as e:
                    print(f"    Error with sub-feature {sub_feature['text']}: {str(e)}")
        
        except Exception as e:
            print(f"Error exploring sub-features: {str(e)}")
    
    async def explore_forms(self, page):
        """Specifically explore forms and their requirements"""
        print("\n--- Exploring Forms ---")
        
        # Look for forms
        forms = await page.locator('form').all()
        
        for i, form in enumerate(forms):
            try:
                # Get all inputs in this form
                inputs = await form.locator('input, textarea, select').all()
                
                form_data = []
                for input_elem in inputs:
                    try:
                        input_type = await input_elem.get_attribute('type')
                        name = await input_elem.get_attribute('name')
                        placeholder = await input_elem.get_attribute('placeholder')
                        required = await input_elem.get_attribute('required')
                        
                        form_data.append({
                            "type": input_type,
                            "name": name,
                            "placeholder": placeholder,
                            "required": required is not None
                        })
                    except:
                        pass
                
                if form_data:
                    await self.take_screenshot(page, f"form_{i:02d}", f"Form {i+1} with {len(form_data)} fields")
                    
                    self.exploration_data[f"form_{i:02d}"].update({
                        "form_fields": form_data,
                        "field_count": len(form_data)
                    })
            
            except Exception as e:
                print(f"Error analyzing form {i}: {str(e)}")
    
    async def run_exploration(self):
        """Main exploration method"""
        async with async_playwright() as p:
            # Launch browser
            browser = await p.chromium.launch(headless=False, args=['--no-sandbox'])
            context = await browser.new_context(
                viewport={'width': 1920, 'height': 1080}
            )
            page = await context.new_page()
            
            try:
                await self.setup()
                
                # Step 1: Login
                await self.login(page)
                
                # Step 2: Take dashboard screenshot
                await self.take_screenshot(page, "04_main_dashboard", "Main dashboard after login")
                
                # Step 3: Analyze dashboard elements
                dashboard_elements = await self.analyze_page_elements(page)
                self.exploration_data["04_main_dashboard"].update({
                    "page_elements": dashboard_elements
                })
                
                # Step 4: Explore navigation
                nav_links = await self.explore_navigation_menu(page)
                
                # Step 5: Explore each menu item
                for i, link in enumerate(nav_links):
                    await self.explore_menu_item(page, link, i + 1)
                    
                    # Return to main page for next navigation
                    try:
                        await page.goto(self.base_url)
                        await page.wait_for_load_state('networkidle', timeout=5000)
                        await asyncio.sleep(1)
                    except:
                        pass
                
                # Step 6: Explore forms
                await self.explore_forms(page)
                
                # Step 7: Generate final report
                await self.generate_report()
                
            except Exception as e:
                print(f"Exploration error: {str(e)}")
                await self.take_screenshot(page, "error_state", f"Error occurred: {str(e)}")
            
            finally:
                await browser.close()
    
    async def generate_report(self):
        """Generate a comprehensive exploration report"""
        report_path = "/home/debian/Projects/isoAgent/exploration_report.json"
        
        with open(report_path, 'w') as f:
            json.dump(self.exploration_data, f, indent=2)
        
        print(f"\nExploration completed!")
        print(f"Screenshots saved to: {self.screenshots_dir}")
        print(f"Detailed report saved to: {report_path}")
        print(f"Total steps documented: {self.current_step}")

async def main():
    explorer = AssetManagementExplorer()
    await explorer.run_exploration()

if __name__ == "__main__":
    asyncio.run(main())