"""The round in one read.

The answer to a round is otherwise scattered across selections, approvals and
two kinds of thread; reading it means opening every option in turn.
"""

from tests.conftest import as_user
from tests.test_domain import add_screen_option, make_project


def test_a_decided_screen_reports_its_option_and_variants(client, kit):
    iid = make_project(client, kit)
    sid, oid = add_screen_option(client, iid)
    client.post(f"/api/options/{oid}/variants", json={
        "axis": "brand", "key": "hive", "label": "Full hive",
        "css_class": "v-brand-hive", "axis_label": "Brand"})
    client.post(f"/api/projects/{iid}/send")

    as_user(client, "cleo")
    client.post(f"/api/screens/{sid}/select",
                json={"option_id": oid, "variants": {"brand": "hive"}})

    s = client.get(f"/api/projects/{iid}/summary").json()
    assert s["decided"] == [{"screen": "Homepage", "option": "Option 1",
                             "variants": ["Full hive"]}]
    assert s["undecided"] == []


def test_an_undecided_screen_is_listed_with_what_there_is_to_choose(client, kit):
    iid = make_project(client, kit)
    add_screen_option(client, iid, "Homepage")
    add_screen_option(client, iid, "Your Team")
    s = client.get(f"/api/projects/{iid}/summary").json()
    assert {u["screen"] for u in s["undecided"]} == {"Homepage", "Your Team"}
    assert all(u["options"] == 1 for u in s["undecided"])


def test_outstanding_covers_BOTH_kinds_of_feedback(client, kit):
    """A pinned note and a conversation about a page are both things we owe an
    answer to; a summary that showed one and not the other would be a summary
    you could not trust."""
    iid = make_project(client, kit)
    sid, oid = add_screen_option(client, iid)
    client.post(f"/api/projects/{iid}/send")

    as_user(client, "cleo")
    client.post(f"/api/options/{oid}/pins", json={
        "x_percent": 40.0, "y_percent": 20.0,
        "body_md": "Can the phone number be bigger?"})
    client.post(f"/api/screens/{sid}/comments",
                json={"body_md": "The tone feels formal."})

    s = client.get(f"/api/projects/{iid}/summary").json()
    kinds = {o["kind"] for o in s["outstanding"]}
    assert kinds == {"note", "page"}
    assert any("phone number" in o["excerpt"] for o in s["outstanding"])
    assert any("tone feels formal" in o["excerpt"] for o in s["outstanding"])
    # Each one links to where it is.
    assert all(o["url"].startswith(f"/p/{iid}") for o in s["outstanding"])


def test_resolving_takes_it_off_the_list(client, kit):
    iid = make_project(client, kit)
    _sid, oid = add_screen_option(client, iid)
    as_user(client, "cleo")
    tid = client.post(f"/api/options/{oid}/pins", json={
        "x_percent": 5.0, "y_percent": 5.0, "body_md": "One."}).json()["pin"]["thread_id"]
    as_user(client, "mara")
    assert len(client.get(f"/api/projects/{iid}/summary").json()["outstanding"]) == 1
    client.post(f"/api/threads/{tid}/resolve")
    assert client.get(f"/api/projects/{iid}/summary").json()["outstanding"] == []


def test_waiting_on_names_the_side_whose_move_it_is(client, kit):
    """The contract's `actors_waiting` was an empty list since the rebuild.
    caddie's job is telling a client where their project stands, and "waiting"
    without "on whom" is the half that does not help."""
    iid = make_project(client, kit)
    _sid, oid = add_screen_option(client, iid)
    client.post(f"/api/projects/{iid}/send")

    # Sent, nothing open: the client's move.
    assert client.get(f"/api/projects/{iid}/summary").json()["waiting_on"] == ["cleo"]
    assert client.get(f"/api/projects/{iid}/status").json()  # smoke

    as_user(client, "cleo")
    client.post(f"/api/options/{oid}/pins",
                json={"x_percent": 5.0, "y_percent": 5.0, "body_md": "A question."})
    # Now it is ours — and "ours" is named.
    waiting = client.get(f"/api/projects/{iid}/summary").json()["waiting_on"]
    assert "mara" in waiting and "cleo" not in waiting


def test_a_finished_round_waits_on_nobody(client, kit):
    iid = make_project(client, kit)
    sid, oid = add_screen_option(client, iid)
    client.post(f"/api/projects/{iid}/send")
    as_user(client, "cleo")
    client.post(f"/api/screens/{sid}/select", json={"option_id": oid})
    s = client.get(f"/api/projects/{iid}/summary").json()
    assert (s["state"], s["waiting_on"]) == ("done", [])


def test_approvals_are_counted(client, kit):
    iid = make_project(client, kit)
    _sid, oid = add_screen_option(client, iid)
    step = client.post(f"/api/options/{oid}/walkthrough", json={
        "title": "Does this land?", "body_md": "…", "target_selector": ".x",
        "requires_approval": True}).json()["id"]
    s = client.get(f"/api/projects/{iid}/summary").json()
    assert (s["approvals_required"], s["approvals_done"]) == (1, 0)
    as_user(client, "cleo")
    client.post(f"/api/walkthrough/{step}/approve", json={})
    s = client.get(f"/api/projects/{iid}/summary").json()
    assert (s["approvals_required"], s["approvals_done"]) == (1, 1)


def test_the_client_can_read_it_too(client, kit):
    """The team needs "what do I owe"; the client needs "did what I said land".
    Same list of facts, worded from neither side."""
    iid = make_project(client, kit)
    add_screen_option(client, iid)
    as_user(client, "cleo")
    assert client.get(f"/api/projects/{iid}/summary").status_code == 200
    as_user(client, "nate")
    assert client.get(f"/api/projects/{iid}/summary").status_code == 404
