from __future__ import annotations

import os
import threading
from pathlib import Path

import pytest

if os.getenv("STACKCHAIN_RUN_RELEASE_E2E") != "1":
    pytest.skip("packaged Today summary journey runs only in its gated CI job", allow_module_level=True)
pytest.importorskip("playwright.sync_api")
from playwright.sync_api import expect, sync_playwright

from fake_gitea import FakeGiteaServer
from test_mobile_offline_issue_release import ACCESS_TOKEN, ROOT, release_server


@pytest.mark.parametrize(("width", "height"), [(320, 568), (390, 844)])
def test_release_artifact_reviews_and_shares_a_private_mobile_today_summary(
    tmp_path: Path, width: int, height: int
):
    archives = sorted((ROOT / "dist").glob("stackchain-dashboard-*.tar.gz"))
    assert len(archives) == 1, "browser job must download exactly one assembled release archive"

    fake = FakeGiteaServer(("127.0.0.1", 0))
    fake_thread = threading.Thread(target=fake.serve_forever, daemon=True)
    fake_thread.start()
    fake_url = f"http://127.0.0.1:{fake.server_port}"
    browser_errors: list[str] = []

    try:
        with release_server(archives[0], tmp_path, fake_url) as origin, sync_playwright() as playwright:
            browser = playwright.chromium.launch(args=["--ignore-certificate-errors"])
            context = browser.new_context(
                viewport={"width": width, "height": height}, ignore_https_errors=True
            )
            page = context.new_page()
            page.add_init_script(
                "Object.defineProperty(navigator, 'share', {configurable:true, value:async payload => { window.__sharedSummary = payload; }});"
            )
            page.on("pageerror", lambda error: browser_errors.append(error.stack or str(error)))
            page.on(
                "console",
                lambda message: browser_errors.append(message.text)
                if message.type == "error"
                else None,
            )
            page.goto(origin + "/", wait_until="networkidle")
            page.locator('input[name="device_label"]').fill("Today summary release phone")
            page.locator('input[name="access_token"]').fill(ACCESS_TOKEN)
            page.locator("#submit-sign-in").click()
            page.wait_for_url(origin + "/", wait_until="networkidle")

            page.evaluate(
                """
                () => {
                  const summary=createTodaySummary({
                    storage:localStorage,getLogin:()=> 'timmy',
                    share:payload=>navigator.share(payload),
                    copy:text=>navigator.clipboard.writeText(text),
                    createOperationId:()=> 'release-summary-op',
                    resolveTarget:async target=>({...target,kind:'issue',title:'Daily status',state:'open'}),
                    enqueueDurably:async message=>{ window.__queuedSummary=message; return {item:message,durability:'background'}; },
                  });
                  const view=createTodaySummaryView({summary,qs:selector=>document.querySelector(selector),escapeHtml:value=>String(value)});
                  window.__summaryTest={summary,view};
                  view.open(
                    [{identity:'issue:acme/mobile:41:',title:'Ship mobile capture',context:'acme/mobile#41',actual_minutes:42}],
                    [{identity:'issue:acme/mobile:42:',title:'Review release',context:'acme/mobile#42'}],
                  );
                }
                """
            )

            sheet = page.locator("#today-summary-sheet")
            expect(sheet).to_be_visible()
            expect(page.locator("#today-summary-preview")).to_have_text(
                "Today\n- Ship mobile capture\n\nTomorrow\n- Review release"
            )
            assert "42m" not in page.locator("#today-summary-preview").inner_text()
            for control in page.locator(".today-summary-actions button").all():
                bounds = control.bounding_box()
                assert bounds and bounds["height"] >= 44
            assert page.evaluate("document.documentElement.scrollWidth <= window.innerWidth")

            page.locator("#today-summary-destination").fill("acme/mobile#41")
            page.evaluate(
                """
                () => {
                  window.__summaryTest.summary.setDestination(document.querySelector('#today-summary-destination').value);
                  return window.__summaryTest.view.validateDestination(document.querySelector('#validate-today-summary-destination'));
                }
                """
            )
            expect(page.locator("#today-summary-target")).to_contain_text(
                "acme/mobile#41 · issue · Daily status"
            )
            expect(page.locator("#post-today-summary")).to_be_enabled()
            page.evaluate(
                "window.__summaryTest.view.postDraft(document.querySelector('#post-today-summary'))"
            )
            expect(sheet).to_be_hidden()
            assert page.evaluate("window.__queuedSummary") == {
                "kind": "search-reply",
                "repository": "acme/mobile",
                "number": 41,
                "targetKind": "issue",
                "body": "Today\n- Ship mobile capture\n\nTomorrow\n- Review release",
                "operationId": "release-summary-op",
            }

            page.evaluate(
                """
                window.__summaryTest.view.open(
                  [{identity:'issue:acme/mobile:41:',title:'Ship mobile capture',context:'acme/mobile#41',actual_minutes:42}],
                  [{identity:'issue:acme/mobile:42:',title:'Review release',context:'acme/mobile#42'}]
                )
                """
            )
            expect(sheet).to_be_visible()

            page.evaluate(
                """
                () => {
                  window.__summaryTest.summary.includeActuals(true);
                  window.__summaryTest.summary.setNote('Waiting on review');
                  window.__summaryTest.view.render();
                }
                """
            )
            expect(page.locator("#today-summary-preview")).to_contain_text(
                "Ship mobile capture (42m)"
            )
            page.evaluate(
                "window.__summaryTest.view.shareDraft(document.querySelector('#share-today-summary'))"
            )
            expect(sheet).to_be_hidden()
            assert page.evaluate("window.__sharedSummary") == {
                "title": "Today summary",
                "text": "Today\n- Ship mobile capture (42m)\n\nTomorrow\n- Review release\n\nNote\nWaiting on review",
            }
            assert page.evaluate(
                "localStorage.getItem('stackchain.today-summary-draft.v1.timmy')"
            ) is None
            assert browser_errors == []
            browser.close()
    finally:
        fake.shutdown()
        fake.server_close()
        fake_thread.join(timeout=5)
