"""Phase 6 browser check: flow preview in the builder, switching a flow on, real runs driven by incoming WhatsApp
messages (typed answers, delays handled by the worker, handoff to a person), the inbox's running-flow card and
stop button, run history, and switching off. Run against a freshly seeded DB with WHATSAPP_PROVIDER=fake:
    python e2e/e2e_engine.py ./e2e-shots
"""
import os, re, sys, time
from playwright.sync_api import sync_playwright, expect

OUT = sys.argv[1] if len(sys.argv) > 1 else "./e2e-shots"
os.makedirs(OUT, exist_ok=True)
BASE = os.environ.get("E2E_BASE", "http://localhost:3000")
HDR = {"X-Requested-With": "devwebs"}
errors = []

def shot(page, name):
    page.screenshot(path=f"{OUT}/{name}.png")

with sync_playwright() as p:
    b = p.chromium.launch()
    ctx = b.new_context(viewport={"width": 1440, "height": 900})
    page = ctx.new_page()
    page.on("pageerror", lambda e: errors.append(f"pageerror: {e}"))
    page.on("console", lambda m: m.type == "error" and "Failed to load resource" not in m.text and errors.append(f"console: {m.text}"))
    page.goto(f"{BASE}/login")
    page.fill("#email", "owner@acme.test"); page.fill("#password", "ChangeMe!2026"); page.click("button[type=submit]")
    page.wait_for_url("**/dashboard")
    api = ctx.request
    acc = api.post(f"{BASE}/api/whatsapp/accounts", headers=HDR, data={"waba_id": "102290129340398", "phone_number_id": "106540352242922", "access_token": "EAAG" + "x" * 60 + "WXYZ", "app_secret": "a" * 32}).json()["data"]
    def customer_says(text, frm="919812345670"):
        r = api.post(f"{BASE}/api/whatsapp/accounts/{acc['id']}/simulate", headers=HDR, data={"kind": "message", "from": frm, "name": "Rohan Mehta", "text": text})
        assert r.ok, r.text()
        time.sleep(0.4)

    nav = page.get_by_role("navigation", name="Main")
    nav.get_by_role("link", name="Bot flows").click()
    page.get_by_role("button", name="Add example flow").first.click()
    page.wait_for_url(re.compile(r"/bot-flows/\d+$"))
    flow_id = int(page.url.rstrip("/").split("/")[-1])

    # ---- Preview: walk the billing branch without sending anything ----
    expect(page.get_by_role("switch", name="Flow on")).to_be_disabled()  # not published yet
    page.get_by_role("button", name="Preview").click()
    pv = page.get_by_label("Flow preview")
    expect(pv.get_by_text("Hi Asha, what is your inquiry about? Choose an option below.")).to_be_visible()
    expect(page.get_by_text("Preview is here")).to_be_visible()
    pv.get_by_role("button", name="Billing Issue").click()
    pv.get_by_role("button", name="Refund status").click()
    expect(pv.get_by_text("Did that solve your issue, Asha?")).to_be_visible()
    pv.get_by_role("button", name="Yes, solved").click()
    expect(pv.get_by_text("Waits 3 seconds (skipped in preview)")).to_be_visible()
    expect(pv.get_by_text(re.compile("^Visit again any time"))).to_be_visible()
    expect(pv.get_by_label("Reply as the customer")).to_be_disabled()
    shot(page, "f01-preview")
    pv.get_by_role("button", name="Restart").click()
    pv.get_by_label("Reply as the customer").fill("technical issue")
    pv.get_by_role("button", name="Send reply").click()
    expect(pv.get_by_text("Which device are you using? Reply Android, iPhone or Web.")).to_be_visible()
    page.get_by_role("button", name="Close preview").click()

    # ---- Publish and switch on ----
    page.get_by_role("button", name="Publish").click()
    page.locator("dialog[open]").get_by_role("button", name="Publish").click()
    expect(page.get_by_text("Published version 1")).to_be_visible()
    page.get_by_role("switch", name="Flow on").check()
    expect(page.get_by_text("“Account support” is on and answering customers")).to_be_visible()

    # ---- A real customer goes through it: billing branch with a delay ----
    customer_says("I have an account inquiry.")
    customer_says("Billing Issue")
    customer_says("Refund status")
    customer_says("Yes, solved")
    nav.get_by_role("link", name="Inbox").click()
    page.get_by_role("button", name=re.compile("Rohan Mehta")).first.click()
    chat = page.get_by_role("region", name="Conversation with Rohan Mehta")
    expect(chat.get_by_text("Hi Rohan, what is your inquiry about? Choose an option below.")).to_be_visible()
    expect(chat.get_by_text("Thank you for contacting us, Rohan!")).to_be_visible()
    # The 3-second delay is resumed by the worker.
    expect(chat.get_by_text(re.compile("^Visit again any time"))).to_be_visible(timeout=15000)
    expect(chat.get_by_text("Flow").first).to_be_visible()
    shot(page, "f02-inbox-flow")

    # ---- Second run: technical branch, unsolved → handoff ----
    customer_says("I have an account inquiry.")
    expect(page.get_by_text("In flow")).to_be_visible(timeout=10000)
    expect(page.get_by_text(", waiting for their reply")).to_be_visible()
    customer_says("Technical Issue")
    customer_says("It's my android phone")
    customer_says("No, talk to agent")
    expect(chat.get_by_text(re.compile("^Connecting you to a support agent")).first).to_be_visible(timeout=10000)
    expect(chat.get_by_text(re.compile("handed this chat to the team"))).to_be_visible()
    expect(page.get_by_text("Paused. Bot replies and flows stay quiet")).to_be_visible()
    expect(page.get_by_text("In flow")).to_have_count(0)
    shot(page, "f03-handoff")

    # ---- Agent turns automation back on; a third run is stopped from the inbox ----
    page.get_by_role("switch").filter(visible=True).first.check()
    expect(page.get_by_text("Automated replies back on")).to_be_visible()
    customer_says("I have an account inquiry.")
    expect(page.get_by_text("In flow")).to_be_visible(timeout=10000)
    page.get_by_role("button", name="Stop flow").click()
    expect(page.get_by_text("Flow stopped for this chat")).to_be_visible()
    expect(page.get_by_text("In flow")).to_have_count(0)

    # ---- Run history ----
    page.goto(f"{BASE}/bot-flows/{flow_id}")
    page.get_by_role("button", name="Runs").click()
    dlg = page.locator("dialog[open]")
    expect(dlg.locator("ul li").get_by_text("Completed", exact=True)).to_be_visible()
    expect(dlg.locator("ul li").get_by_text("Handed off", exact=True)).to_be_visible()
    expect(dlg.locator("ul li").get_by_text("Stopped", exact=True)).to_be_visible()
    dlg.get_by_role("button", name=re.compile("Handed off")).click()
    expect(dlg.get_by_text("Typed “Technical Issue”")).to_be_visible()
    expect(dlg.get_by_text("Answer matched “Android”")).to_be_visible()
    expect(dlg.get_by_text("Handed to the team").last).to_be_visible()
    shot(page, "f04-run-detail")
    page.keyboard.press("Escape")

    # ---- Flows list: counts and switching off ----
    nav.get_by_role("link", name="Bot flows").click()
    row = page.get_by_role("row", name=re.compile("Account support"))
    expect(row.get_by_text("3", exact=True)).to_be_visible()
    row.get_by_role("switch").uncheck()
    expect(page.get_by_text("Account support is off; conversations in progress were stopped")).to_be_visible()
    customer_says("I have an account inquiry.")
    runs = api.get(f"{BASE}/api/bot-flows/{flow_id}/runs").json()["meta"]["total"]
    assert runs == 3, runs
    shot(page, "f05-flows-list")

    # ---- Mobile preview ----
    m = b.new_context(viewport={"width": 390, "height": 844}, storage_state=ctx.storage_state())
    mp = m.new_page()
    mp.on("pageerror", lambda e: errors.append(f"mobile pageerror: {e}"))
    mp.goto(f"{BASE}/bot-flows/{flow_id}")
    mp.get_by_role("button", name="Preview").click()
    expect(mp.get_by_label("Flow preview").get_by_text("Hi Asha, what is your inquiry about? Choose an option below.")).to_be_visible()
    assert mp.evaluate("document.documentElement.scrollWidth <= window.innerWidth"), "builder overflows on mobile"
    shot(mp, "f06-mobile-preview")
    b.close()

if errors:
    print("\n".join(errors)); sys.exit(1)
print("engine e2e passed")
