"""What has changed since this person was last here.

The engagement guarantees a second visit — the homepage is decided, then the
remaining pages are designed against it — so "what is new?" is the first
question a returning client has, and nothing answered it.
"""

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


def _detail(client, iid):
    return client.get(f"/api/projects/{iid}").json()


def test_a_first_visit_marks_nothing_new(client, kit):
    """Arriving to find every single thing flagged tells you nothing. Newness
    only starts counting once there is a previous visit to be new since."""
    iid = make_project(client, kit)
    add_screen_option(client, iid)
    as_user(client, "cleo")
    d = _detail(client, iid)
    assert d["last_seen"] is None
    assert d["new_count"] == 0
    assert d["screens"][0]["is_new"] is False
    assert d["screens"][0]["options"][0]["since_last"] == ""


def test_an_option_added_after_your_visit_is_new(client, kit):
    iid = make_project(client, kit)
    sid, _oid = add_screen_option(client, iid)

    as_user(client, "cleo")
    assert client.post(f"/api/projects/{iid}/seen").status_code == 200

    as_user(client, "mara")
    added = client.post(f"/api/screens/{sid}/options",
                        json={"title": "Option 2", "concept_tag": "b"}).json()["id"]
    client.post(f"/api/options/{added}/files",
                files=[("files", ("index.html", MOCKUP, "text/html"))])

    as_user(client, "cleo")
    d = _detail(client, iid)
    states = {o["id"]: o["since_last"] for o in d["screens"][0]["options"]}
    assert states[added] == "new"
    assert d["new_count"] >= 1


def test_an_option_you_already_read_reports_CHANGED_not_new(client, kit):
    """Different messages: "there is another design" versus "the one you read
    has moved on"."""
    iid = make_project(client, kit)
    _sid, oid = add_screen_option(client, iid)

    as_user(client, "cleo")
    client.post(f"/api/projects/{iid}/seen")

    as_user(client, "mara")
    client.post(f"/api/options/{oid}/walkthrough", json={
        "title": "A new beat", "body_md": "…", "target_selector": ".x",
        "requires_approval": False})

    as_user(client, "cleo")
    option = _detail(client, iid)["screens"][0]["options"][0]
    assert option["since_last"] == "changed"


def test_a_whole_new_screen_is_flagged(client, kit):
    iid = make_project(client, kit)
    add_screen_option(client, iid, "Homepage")
    as_user(client, "cleo")
    client.post(f"/api/projects/{iid}/seen")

    as_user(client, "mara")
    add_screen_option(client, iid, "Your Team")

    as_user(client, "cleo")
    screens = {s["title"]: s for s in _detail(client, iid)["screens"]}
    assert screens["Your Team"]["is_new"] is True
    assert screens["Homepage"]["is_new"] is False


def test_reading_the_board_does_not_clear_what_is_new(client, kit):
    """The load-bearing one. A GET that quietly moved the marker would clear the
    flags in the very request that returned them, so a client who glanced at the
    board would be told nothing had changed."""
    iid = make_project(client, kit)
    sid, _oid = add_screen_option(client, iid)
    as_user(client, "cleo")
    client.post(f"/api/projects/{iid}/seen")

    as_user(client, "mara")
    client.post(f"/api/screens/{sid}/options", json={"title": "Two", "concept_tag": ""})

    as_user(client, "cleo")
    assert _detail(client, iid)["new_count"] >= 1
    # Reading it again — still new, because nothing said they had seen it.
    assert _detail(client, iid)["new_count"] >= 1
    # Only the explicit call clears it.
    client.post(f"/api/projects/{iid}/seen")
    assert _detail(client, iid)["new_count"] == 0


def test_newness_is_per_person(client, kit):
    iid = make_project(client, kit)
    sid, _oid = add_screen_option(client, iid)
    as_user(client, "cleo")
    client.post(f"/api/projects/{iid}/seen")

    as_user(client, "mara")
    client.post(f"/api/screens/{sid}/options", json={"title": "Two", "concept_tag": ""})
    # mara has never marked the board seen, so nothing is new to her.
    assert _detail(client, iid)["new_count"] == 0
    as_user(client, "cleo")
    assert _detail(client, iid)["new_count"] >= 1


def test_an_outsider_cannot_mark_a_board_seen(client, kit):
    iid = make_project(client, kit)
    add_screen_option(client, iid)
    as_user(client, "nate")
    assert client.post(f"/api/projects/{iid}/seen").status_code == 404
