"""Phase 3 browser check: templates (sync, build, review, send) and the team inbox (live updates, replies,
attachments, assignment, notes, closing, 24h window). Run against a freshly seeded DB with WHATSAPP_PROVIDER=fake:
    python e2e/e2e_inbox.py ./e2e-shots e2e/import-sample.xlsx
"""
import base64, os, re, sys
from playwright.sync_api import sync_playwright, expect

OUT = sys.argv[1]
os.makedirs(OUT, exist_ok=True)
BASE = os.environ.get("E2E_BASE", "http://localhost:3000")
HDR = {"X-Requested-With": "devwebs"}
errors = []
PNG = base64.b64decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==")

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.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"]
    nav = page.get_by_role("navigation", name="Main")

    # ---- Templates: sync, build, review ----
    nav.get_by_role("link", name="Templates").click()
    expect(page.get_by_text("No templates yet")).to_be_visible()
    page.get_by_role("button", name="Sync from Meta").first.click()
    expect(page.get_by_role("button", name="hello_world")).to_be_visible()
    page.get_by_role("button", name="New template").click()
    dlg = page.locator("dialog[open]")
    dlg.locator("#tp-name").fill("Order Update")
    expect(dlg.locator("#tp-name")).to_have_value("order_update")
    dlg.get_by_text("Text", exact=True).click()
    dlg.locator("#tp-ht").fill("Your order is on its way")
    dlg.locator("#tp-body").fill("Hi ")
    dlg.get_by_role("button", name="Add variable").click()
    dlg.locator("#tp-body").press("End")
    dlg.locator("#tp-body").type(", your order ")
    dlg.get_by_role("button", name="Add variable").click()
    dlg.locator("#tp-body").press("End")
    dlg.locator("#tp-body").type(" will arrive tomorrow.")
    expect(dlg.locator("#tp-body")).to_have_value("Hi {{1}}, your order {{2}} will arrive tomorrow.")
    dlg.get_by_role("button", name="Submit for review").click()
    expect(dlg.get_by_text("Give a sample value for {{1}}")).to_be_visible()
    dlg.locator("#tp-ex-1").fill("Pablo"); dlg.locator("#tp-ex-2").fill("#1042")
    dlg.locator("#tp-foot").fill("Reply STOP to unsubscribe")
    dlg.get_by_role("button", name="Add button").click()
    dlg.get_by_label("Button type").select_option("URL")
    dlg.get_by_label("Button text").fill("Track order")
    dlg.locator("#tp-url-0").fill("https://shop.example.com/track/{{1}}")
    dlg.locator("#tp-urlx-0").fill("1042")
    expect(dlg.get_by_text("Hi Pablo, your order #1042 will arrive tomorrow.")).to_be_visible()
    shot(page, "i01-template-builder")
    dlg.get_by_role("button", name="Submit for review").click()
    expect(page.get_by_text("Template submitted to Meta for review")).to_be_visible()
    drawer = page.get_by_role("dialog", name="Template order_update")
    expect(drawer.get_by_text("In review")).to_be_visible()
    drawer.get_by_role("button", name="Approve").click()
    expect(drawer.get_by_text("Approved", exact=True)).to_be_visible()
    shot(page, "i02-template-drawer")
    page.keyboard.press("Escape")
    shot(page, "i03-templates")

    # ---- Send template from Contacts ----
    nav.get_by_role("link", name="Contacts", exact=True).click()
    page.get_by_role("button", name="Send template message to Rohan Mehta").click()
    dlg = page.locator("dialog[open]")
    dlg.locator("#st-template").select_option(label="order_update (en_US, utility)")
    dlg.get_by_label("{{2}} value").fill("#2201")
    dlg.get_by_label("“Track order” link ending value").fill("2201")
    expect(dlg.get_by_text("Hi Rohan, your order #2201 will arrive tomorrow.")).to_be_visible()
    shot(page, "i04-send-template")
    dlg.get_by_role("button", name="Send template").click()
    expect(page.get_by_text("Sent order_update to Rohan Mehta")).to_be_visible()

    # ---- Inbox ----
    nav.get_by_role("link", name="Inbox").click()
    expect(page.get_by_role("heading", name="Inbox")).to_be_visible()
    rohan = page.get_by_role("button", name=re.compile("Rohan Mehta"))
    expect(rohan).to_be_visible()
    # A customer message arrives while the page is open: appears live (event stream), no reload
    api.post(f"{BASE}/api/whatsapp/accounts/{acc['id']}/simulate", headers=HDR, data={"kind": "message", "from": "447700900123", "name": "Piper Reeves", "text": "Hi! Is the blue jacket back in stock?"})
    piper = page.get_by_role("button", name=re.compile("Piper Reeves"))
    expect(piper).to_be_visible(timeout=5000)
    expect(piper.get_by_text("Hi! Is the blue jacket back in stock?")).to_be_visible()
    expect(page.get_by_role("tab", name=re.compile("All"))).to_contain_text("1")
    piper.click()
    expect(page).to_have_url(re.compile(r"/inbox\?c=\d+"))
    chat = page.get_by_role("region", name="Conversation with Piper Reeves")
    expect(chat.get_by_text("Reply window open")).to_be_visible()
    box = chat.get_by_label("Message")
    box.fill("Yes! We restocked it this morning.")
    box.press("Enter")
    expect(chat.get_by_text("Yes! We restocked it this morning.")).to_be_visible()
    # Attachment
    chat.locator("input[type=file]").set_input_files({"name": "jacket.png", "mimeType": "image/png", "buffer": PNG})
    chat.get_by_label("Caption").fill("Here it is")
    chat.get_by_role("button", name="Send", exact=True).click()
    expect(chat.get_by_role("img", name="Here it is")).to_be_visible(timeout=15000)  # lazy image load after upload
    # Delivery status arrives live
    msgs = api.get(f"{BASE}/api/whatsapp/accounts/{acc['id']}/messages", headers=HDR).json()["data"]
    txt = next(m for m in msgs if m["body"] == "Yes! We restocked it this morning.")
    api.post(f"{BASE}/api/whatsapp/accounts/{acc['id']}/simulate", headers=HDR, data={"kind": "status", "message_id": txt["id"], "status": "read"})
    expect(chat.get_by_label("Read")).to_be_visible(timeout=5000)
    # Assign, note, close
    chat.get_by_label("Assigned to").select_option(label="Asha Verma (you)")
    expect(chat.get_by_text("Asha Verma took this conversation")).to_be_visible()
    panel = page.get_by_role("complementary", name="Contact details")
    panel.get_by_label("New note").fill("Wants the size L. Call back Friday.")
    panel.get_by_role("button", name="Add note").click()
    expect(panel.get_by_text("Wants the size L. Call back Friday.")).to_be_visible()
    shot(page, "i05-inbox-chat")
    page.get_by_role("tab", name=re.compile("Mine")).click()
    expect(page.get_by_role("button", name=re.compile("Piper Reeves"))).to_be_visible()
    expect(page.get_by_role("button", name=re.compile("Rohan Mehta"))).to_have_count(0)
    page.get_by_role("tab", name=re.compile("All")).click()

    # Rohan: window closed → template only
    page.get_by_role("button", name=re.compile("Rohan Mehta")).click()
    chat = page.get_by_role("region", name="Conversation with Rohan Mehta")
    expect(chat.get_by_text("Reply window closed")).to_be_visible()
    expect(chat.get_by_text("Hi Rohan, your order #2201 will arrive tomorrow.")).to_be_visible()
    expect(chat.get_by_label("Message")).to_have_count(0)
    shot(page, "i06-window-closed")
    chat.get_by_role("button", name="Close", exact=True).click()
    expect(page.get_by_role("button", name=re.compile("Rohan Mehta"))).to_have_count(0)
    page.get_by_label("Conversation status").select_option("closed")
    expect(page.get_by_role("button", name=re.compile("Rohan Mehta"))).to_be_visible()

    # Dashboard reflects inbox + templates
    nav.get_by_role("link", name="Dashboard").click()
    expect(page.get_by_text("Go to templates")).to_have_count(0)
    shot(page, "i07-dashboard")

    # Mobile: list → chat → back
    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}/inbox")
    mp.get_by_role("button", name=re.compile("Piper Reeves")).click()
    expect(mp.get_by_role("region", name="Conversation with Piper Reeves")).to_be_visible()
    mp.screenshot(path=f"{OUT}/i08-mobile-chat.png")
    mp.get_by_role("button", name="Back to conversations").click()
    expect(mp.get_by_role("heading", name="Inbox")).to_be_visible()
    for url in ["/inbox", "/templates"]:
        mp.goto(f"{BASE}{url}")
        # The inbox keeps an event stream open, so "network idle" never happens: wait for content.
        expect(mp.get_by_role("heading", name=re.compile("Inbox|Templates")).first).to_be_visible()
        mp.wait_for_timeout(800)
        if mp.evaluate("document.documentElement.scrollWidth > innerWidth"): errors.append(f"mobile overflow on {url}")
    mp.screenshot(path=f"{OUT}/i09-mobile-templates.png")
    b.close()

print("ERRORS:", errors if errors else "none")
