#!/usr/bin/env python3
"""v12: Open Process 7 → select step via ExtJS grid → Run Selected Step → capture AJAX."""
import asyncio, json
from playwright.async_api import async_playwright

IP = "66.175.238.112"
APP = "2610RTROGERSUAP1"
BASE = f"http://{IP}/{APP}"

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        context = await browser.new_context(viewport={"width":1920,"height":1080})
        page = await context.new_page()

        # Capture ALL requests/responses during execution
        all_requests = []
        async def on_req(req):
            all_requests.append({
                "method": req.method,
                "url": req.url,
                "path": req.url.split(APP)[-1][:150],
                "data": req.post_data[:1000] if req.post_data else None,
                "ts": asyncio.get_event_loop().time()
            })
        page.on("request", on_req)

        all_responses = []
        async def on_resp(resp):
            if "/api/" in resp.url or "/integration" in resp.url.lower():
                try:
                    body = await resp.text()
                    all_responses.append({
                        "method": resp.request.method,
                        "path": resp.url.split(APP)[-1][:150],
                        "status": resp.status,
                        "body": body[:500],
                        "ts": asyncio.get_event_loop().time()
                    })
                except: pass
        page.on("response", on_resp)

        # Login (working approach)
        for attempt in range(3):
            await page.goto(f"{BASE}/login", wait_until="domcontentloaded", timeout=15000)
            await asyncio.sleep(2)
            await page.fill('input[name="Email"]', 'irelyadmin')
            await page.fill('input[name="Password"]', 'i21By2015')
            await page.evaluate('''() => { const c = document.querySelector('input[name="Company"]'); if (c) c.value = '01'; }''')
            await asyncio.sleep(1)
            await page.evaluate('document.querySelector("form").submit()')
            await asyncio.sleep(12)
            try: await page.wait_for_load_state("networkidle", timeout=15000)
            except: pass
            if "login" not in page.url.lower() or "#home" in page.url: break
        else:
            print("Login failed"); await browser.close(); return
        print("✅ Login OK")

        # Open Process 7 directly via edit URL
        url = (f"{BASE}/#/IP/ProcessSetup?action=edit"
               "&filters%5B0%5D%5Bcolumn%5D=intProcessId"
               "&filters%5B0%5D%5Bvalue%5D=7%7C%5E%7C"
               "&totalRecords=8&searchTab=Process"
               "&menuId=810&moduleMenuId=806")
        await page.goto(url, wait_until="networkidle", timeout=20000)
        await asyncio.sleep(8)
        print(f"Process editor: {page.url}")

        # Wait for step grid to render
        await asyncio.sleep(3)

        # Take screenshot BEFORE
        await page.screenshot(path="/tmp/before_run.png")

        # Get step grid info
        grid_info = await page.evaluate('''() => {
            // Find the step grid
            const grids = document.querySelectorAll('.x-grid-view, .x-grid-body, .x-grid-table');
            const info = [];
            grids.forEach(grid => {
                const rows = grid.querySelectorAll('.x-grid-row, .x-grid-data-row, .x-grid-table-row, tr.x-grid-row');
                if (rows.length > 0) {
                    info.push({
                        gridId: grid.id || '',
                        gridCls: (grid.className||'').substring(0,50),
                        rowCount: rows.length,
                        rows: Array.from(rows).map(r => ({
                            id: r.id || '',
                            text: r.textContent.trim().substring(0, 80)
                        }))
                    });
                }
            });
            return info;
        }''')
        print(f"\nGrids with rows: {len(grid_info)}")
        for g in grid_info:
            print(f"  Grid #{g['gridId']} ({g['gridCls'][:30]}) — {g['rowCount']} rows")
            for r in g["rows"][:5]:
                print(f"    Row #{r['id']} {r['text'][:60]}")

        # Method 1: Try Playwright native click on step grid row
        print("\n=== Selecting step row ===")
        step_selected = False
        
        # Find step grid row (not process grid row)
        for g in grid_info:
            for r in g["rows"]:
                if "Send Mail" in r["text"] or "AP Account" in r["text"]:
                    print(f"  Found step row: {r['text'][:50]}")
                    if r["id"]:
                        try:
                            el = await page.query_selector(f"#{r['id']}")
                            if el:
                                await el.click(timeout=5000)
                                await asyncio.sleep(2)
                                print(f"  Clicked row #{r['id']}")
                                step_selected = True
                        except Exception as e:
                            print(f"  Click failed: {e}")
                    break
            if step_selected: break

        # Method 2: If no row found, try clicking any grid row
        if not step_selected and grid_info:
            first_grid = grid_info[0]
            if first_grid["rows"]:
                first_row = first_grid["rows"][0]
                if first_row["id"]:
                    try:
                        el = await page.query_selector(f"#{first_row['id']}")
                        if el:
                            await el.click(timeout=5000)
                            await asyncio.sleep(2)
                            print(f"  Clicked first row: {first_row['text'][:40]}")
                            step_selected = True
                    except: pass

        # Method 3: Use ExtJS internal API to select the first step
        if not step_selected:
            print("  Trying ExtJS internal selection...")
            result = await page.evaluate('''() => {
                // Find ExtJS grid panel for steps
                const grids = Ext.ComponentQuery.query('gridpanel');
                for (const grid of grids) {
                    const store = grid.getStore();
                    if (store && store.getCount() > 0 && store.getCount() < 20) {
                        // This might be the step grid
                        grid.getSelectionModel().select(0);
                        return 'selected in grid: ' + grid.id + ', count=' + store.getCount();
                    }
                }
                return 'no grid found';
            }''')
            print(f"  {result}")
            await asyncio.sleep(2)

        # Now click "Run Selected Step"
        print("\n=== Clicking 'Run Selected Step' ===")
        
        # Record timestamp to separate pre-run and post-run AJAX
        pre_run_count = len(all_requests)
        print(f"  Pre-run request count: {pre_run_count}")

        run_clicked = False
        for btn_id in ["#button-1346", "#button-1212"]:
            try:
                btn = await page.query_selector(btn_id)
                if btn:
                    is_visible = await btn.is_visible()
                    is_enabled = await btn.is_enabled()
                    print(f"  {btn_id}: visible={is_visible} enabled={is_enabled}")
                    if is_visible and is_enabled:
                        await btn.click(timeout=5000)
                        run_clicked = True
                        print(f"  ✅ Clicked {btn_id}")
                        break
            except: pass

        if not run_clicked:
            print("  Trying JS click...")
            result = await page.evaluate('''() => {
                const btn = document.getElementById('button-1346') || document.getElementById('button-1212');
                if (btn) { btn.click(); return 'clicked'; }
                return 'not found';
            }''')
            print(f"  JS: {result}")

        # Wait for execution
        print("  Waiting for execution...")
        await asyncio.sleep(15)
        try: await page.wait_for_load_state("networkidle", timeout=15000)
        except: pass

        # Take screenshot AFTER
        await page.screenshot(path="/tmp/after_run.png")

        # Check for result messages
        messages = await page.evaluate('''() => {
            const texts = [];
            document.querySelectorAll('.x-message-box, .x-window, .x-msgbox, .toast, .x-notification, .alert').forEach(el => {
                if (el.offsetParent !== null) {
                    texts.push(el.textContent.trim().substring(0, 200));
                }
            });
            // Also check for any newly visible elements
            const newElements = [];
            document.querySelectorAll('*').forEach(el => {
                if (el.children.length === 0 && el.textContent && el.offsetParent !== null) {
                    const t = el.textContent.trim();
                    if (t.length > 10 && t.length < 200 && 
                        (t.includes('success') || t.includes('error') || t.includes('fail') ||
                         t.includes('complete') || t.includes('executed') || t.includes('running') ||
                         t.includes('result') || t.includes('step'))) {
                        newElements.push(t);
                    }
                }
            });
            return {messages: texts, newElements: newElements};
        }''')
        if messages["messages"]:
            print(f"\n  Messages: {messages['messages'][:3]}")
        if messages["newElements"]:
            print(f"  New elements: {messages['newElements'][:5]}")

        # Analyze post-run AJAX requests
        post_run = all_requests[pre_run_count:]
        print(f"\n=== Post-run AJAX ({len(post_run)}) ===")
        for req in post_run:
            print(f"  {req['method']} {req['path']}")
            if req['data']:
                print(f"    data: {req['data'][:200]}")

        # Also check post-run responses
        post_run_resp = [r for r in all_responses if r["ts"] > pre_run_count * 0.1]  # rough filter
        print(f"\n=== Post-run responses ({len(post_run_resp)}) ===")
        for resp in post_run_resp[-10:]:
            print(f"  {resp['method']} {resp['path']} → {resp['status']}")
            if resp['body'] and len(resp['body']) > 2:
                print(f"    body: {resp['body'][:200]}")

        await browser.close()

asyncio.run(main())
