#!/usr/bin/env python3
"""v18: Fill SQL → call save handler directly → ExecuteStep with our SQL."""
import asyncio, json
from playwright.async_api import async_playwright

IP = "66.175.238.112"
APP = "2610RTROGERSUAP1"
BASE = f"http://{IP}/{APP}"
SQL_QUERY = "SELECT @@version AS version, DB_NAME() AS db, GETDATE() AS now"

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()

        all_ajax = []
        async def on_req(req):
            if "/api/" in req.url or "/integration" in req.url.lower():
                all_ajax.append({"m":req.method,"u":req.url.split(APP)[-1][:150],"d":req.post_data[:1000] if req.post_data else None})
        page.on("request", on_req)

        # Login
        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
        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)

        # Select step + Edit
        await page.evaluate('''() => {
            const grids = Ext.ComponentQuery.query('gridpanel');
            for (const grid of grids) {
                const store = grid.getStore();
                if (store && store.getCount() > 0 && store.getCount() < 20) {
                    grid.getSelectionModel().select(0);
                    break;
                }
            }
        }''')
        await asyncio.sleep(2)
        edit_btn = await page.query_selector('#button-1092')
        if edit_btn:
            await edit_btn.click(timeout=5000)
            await asyncio.sleep(5)
            try: await page.wait_for_load_state("networkidle", timeout=10000)
            except: pass
            print("✅ Step editor opened")

        # Change SQL Type to "SQL Statement" (3)
        await page.evaluate('''() => {
            const combo = Ext.getCmp('combo-1264');
            if (combo) { combo.setValue(3); combo.fireEvent('select', combo); }
        }''')
        await asyncio.sleep(3)
        print("✅ SQL Type = SQL Statement")

        # Fill SQL textarea
        await page.evaluate(f'''() => {{
            const field = Ext.getCmp('textarea-1265');
            if (field) {{
                field.setValue(`{SQL_QUERY}`);
                field.fireEvent('change', field);
            }}
        }}''')
        await asyncio.sleep(1)
        print("✅ SQL filled")

        # Step name
        await page.evaluate('''() => {
            const field = Ext.getCmp('textfield-1247');
            if (field) field.setValue('SQL Health Check');
        }''')
        print("✅ Step name set")

        # Save via various ExtJS methods
        print("\n=== Saving (trying multiple methods) ===")
        pre_save = len(all_ajax)

        # Method 1: Try btn.fireHandler()
        save_result = await page.evaluate('''() => {
            const btn = Ext.getCmp('button-1271');
            if (!btn) return 'button-1271 not found';
            
            // Try fireHandler (if exists)
            if (btn.fireHandler) {
                btn.fireHandler();
                return 'fireHandler called';
            }
            
            // Try handler directly
            if (btn.handler) {
                btn.handler.call(btn, btn, {});
                return 'handler called directly';
            }
            
            // Try fireEvent with all events
            const events = ['click', 'tap', 'mousedown'];
            for (const ev of events) {
                btn.fireEvent(ev, btn);
            }
            return 'fireEvent called for click/tap/mousedown';
        }''')
        print(f"  Method 1: {save_result}")
        await asyncio.sleep(3)
        
        post1 = all_ajax[pre_save:]
        print(f"  Post-save AJAX (1): {len(post1)}")
        for req in post1:
            print(f"    {req['m']} {req['u']}")
            if req['d']:
                print(f"      data: {req['d'][:300]}")

        # Method 2: Try calling the controller's save method
        print("\n  Method 2: Controller save")
        pre_save2 = len(all_ajax)
        save_result2 = await page.evaluate('''() => {
            // Find the step editor controller
            const controllers = Ext.ComponentQuery.query('controller');
            // Or find via app
            const app = Ext.getApplication ? Ext.getApplication() : null;
            
            // Try finding the window and calling its save
            const win = Ext.getCmp('sendmail-1241');
            if (win) {
                // Check if window has save method
                if (win.save) { win.save(); return 'window.save()'; }
                if (win.doSave) { win.doSave(); return 'window.doSave()'; }
                if (win.onSave) { win.onSave(); return 'window.onSave()'; }
            }
            
            // Try finding controller by type
            try {
                const ctrl = iRely.app.getController('Integration.controller.SendMail') ||
                             iRely.app.getController('SendMail');
                if (ctrl && ctrl.onSave) {
                    ctrl.onSave();
                    return 'controller.onSave()';
                }
            } catch(e) {}
            
            // Try: find save button and simulate full DOM click
            const btnEl = document.getElementById('button-1271-btnEl');
            if (btnEl) {
                btnEl.click();
                return 'DOM click on btnEl';
            }
            
            return 'no save method found';
        }''')
        print(f"  Method 2: {save_result2}")
        await asyncio.sleep(5)
        try: await page.wait_for_load_state("networkidle", timeout=10000)
        except: pass
        
        post2 = all_ajax[pre_save2:]
        print(f"  Post-save AJAX (2): {len(post2)}")
        for req in post2:
            print(f"    {req['m']} {req['u']}")
            if req['d']:
                print(f"      data: {req['d'][:300]}")

        # Method 3: Direct API call to save step (try all possible save endpoints)
        print("\n  Method 3: Direct API save")
        save_result3 = await page.evaluate(f'''async () => {{
            // Get current step data from the form
            const stepData = {{
                intStepId: 9,
                intProcessId: 7,
                strStepName: 'SQL Health Check',
                intStepTypeId: 9,
                intConnectionId: 1,
                intSQLTypeId: 3,
                strSQL: '{SQL_QUERY}',
                strTo: 'test@irely.com',
                strSubject: 'Test',
                strMessage: 'Test',
                strPayloadType: 'JSON',
                strAuthenticationType: 'JWT',
                intConcurrencyId: 1
            }};
            
            // Try various save endpoints
            const endpoints = [
                '/{app}/Integration/api/Step/Save',
                '/{app}/Integration/api/Step/Update',
                '/{app}/integration/api/step/save',
                '/{app}/integration/api/step/update',
                '/{app}/Integration/api/Step',
                '/{app}/integration/api/step',
            ];
            
            const results = [];
            for (const url of endpoints) {{
                try {{
                    const resp = await fetch(url, {{
                        method: 'POST',
                        headers: {{'Content-Type': 'application/json'}},
                        body: JSON.stringify(stepData),
                        credentials: 'include'
                    }});
                    if (resp.status !== 405 && resp.status !== 404) {{
                        const text = await resp.text();
                        results.push({{url: url, status: resp.status, body: text.substring(0, 200)}});
                    }}
                }} catch(e) {{
                    results.push({{url: url, error: e.message}});
                }}
            }}
            return results;
        }}'''.replace('{app}', APP))
        
        if save_result3:
            for r in save_result3:
                if isinstance(r, dict):
                    print(f"    {r.get('url','').split(APP)[-1][:60]}: status={r.get('status','err')} body={r.get('body',r.get('error',''))[:100]}")

        # Now try ExecuteStep regardless
        print("\n=== Execute Step ===")
        exec_result = await page.evaluate(f'''async () => {{
            const resp = await fetch('/{APP}/Integration/api/Execute/ExecuteStep', {{
                method: 'POST',
                headers: {{'Content-Type': 'application/json'}},
                body: JSON.stringify({{intStepId: 9}}),
                credentials: 'include'
            }});
            const text = await resp.text();
            return {{status: resp.status, body: text.substring(0, 800)}};
        }}''')
        print(f"  HTTP {exec_result['status']}")
        print(f"  Body: {exec_result['body'][:500]}")

        # Print ALL AJAX
        print(f"\n=== ALL AJAX ({len(all_ajax)}) ===")
        for req in all_ajax[-15:]:
            print(f"  {req['m']} {req['u']}")
            if req['d']:
                print(f"    data: {req['d'][:200]}")

        await browser.close()

asyncio.run(main())
