"""Editing a submission from the form's Submissions page: every field can be
corrected — a Hidden field, and a field the form hides for these answers —
while required checks only cover what the form would show, computed values
stay the server's, and fields locked by a role's permissions keep their value."""

import uuid

FIELDS = [
    {"name": "kind", "type": "dropdown", "label": "Kind", "options": ["Bus", "Ferry"], "required": True},
    {"name": "route", "type": "text", "label": "Route", "required": True, "visible_when": "kind == 'Bus'"},
    {"name": "office_code", "type": "hidden", "label": "Office code"},
    {"name": "fare", "type": "number", "label": "Fare"},
    {"name": "total", "type": "formula", "label": "Total", "formula_expression": "{fare} * 2"},
    {"name": "ref", "type": "autonumber", "label": "Ref", "autonumber_format": "R-{SEQ:3}"},
]


async def test_every_field_can_be_corrected(client, auth_headers):
    created = await client.post("/forms", headers=auth_headers, json={"name": f"Pytest Edit {uuid.uuid4().hex[:6]}", "field_definitions": FIELDS})
    form = (await client.post(f"/forms/{created.json()['form_id']}/publish", headers=auth_headers)).json()
    sub = await client.post(
        "/form-submissions",
        headers=auth_headers,
        json={"form_id": form["form_id"], "form_version": form["version"], "field_values": {"kind": "Ferry", "office_code": "EKM", "fare": 10}},
    )
    assert sub.status_code == 201, sub.text
    sid, before = sub.json()["id"], sub.json()["field_values"]

    # "route" isn't shown for a ferry, so it isn't required — but it can still
    # be set; the hidden office code can be corrected; computed values stay the server's.
    edited = await client.patch(
        f"/form-submissions/{sid}",
        headers=auth_headers,
        json={"field_values": {"kind": "Ferry", "route": "Vypin – Fort Kochi", "office_code": "TVM", "fare": 12, "total": 999, "ref": "X"}},
    )
    assert edited.status_code == 200, edited.text
    values = edited.json()["field_values"]
    assert values["route"] == "Vypin – Fort Kochi" and values["office_code"] == "TVM"
    assert values["total"] == 24 and values["ref"] == before["ref"]

    # The value still has to fit the field, shown or not.
    bad = await client.patch(f"/form-submissions/{sid}", headers=auth_headers, json={"field_values": {"kind": "Ferry", "fare": "lots"}})
    assert bad.status_code == 422

    # Listing for the Submissions page carries who submitted it.
    listed = await client.get(f"/forms/{form['form_id']}/submissions", headers=auth_headers)
    assert listed.json()[0]["created_by_name"]
