"""SEQ('name', digits) in a formula field: a running number the server gives
out when a submission is submitted — not for a draft, and kept on later
edits (app/routers/form_submissions.py::_with_formulas)."""

import uuid


async def _form(client, headers, expression: str) -> dict:
    resp = await client.post(
        "/forms",
        headers=headers,
        json={
            "name": f"Pytest Numbered {uuid.uuid4().hex[:6]}",
            "settings": {"allow_drafts": True},
            "field_definitions": [
                {"name": "office", "type": "number", "label": "Office"},
                {"name": "subject", "type": "text", "label": "Subject"},
                {"name": "application_number", "type": "formula", "label": "Application Number", "formula_expression": expression},
            ],
        },
    )
    assert resp.status_code == 201, resp.text
    published = await client.post(f"/forms/{resp.json()['form_id']}/publish", headers=headers)
    assert published.status_code == 200
    return published.json()


async def test_submissions_get_running_numbers(client, auth_headers):
    seq = f"T{uuid.uuid4().hex[:8]}"
    form = await _form(client, auth_headers, f"'RTI/' + YEAR(TODAY()) + '/' + PAD({{office}}, 3) + '/' + SEQ('{seq}', 6) + '/DR'")

    async def submit(values: dict, draft: bool = False):
        resp = await client.post(
            "/form-submissions",
            headers=auth_headers,
            json={"form_id": form["form_id"], "form_version": form["version"], "field_values": values, "draft": draft},
        )
        assert resp.status_code == 201, resp.text
        return resp.json()

    first = await submit({"office": 7, "subject": "Bus timings"})
    second = await submit({"office": 12, "subject": "Fares"})
    assert first["field_values"]["application_number"].endswith("/007/000001/DR")
    assert first["field_values"]["application_number"].startswith("RTI/20")
    assert second["field_values"]["application_number"].endswith("/012/000002/DR")

    # Editing keeps the number, even when the inputs change.
    edited = await client.patch(f"/form-submissions/{first['id']}", headers=auth_headers, json={"field_values": {"office": 9, "subject": "Bus timings"}})
    assert edited.status_code == 200, edited.text
    assert edited.json()["field_values"]["application_number"] == first["field_values"]["application_number"]

    # A draft has no number yet; it gets the next one when it's submitted.
    draft = await submit({"office": 3}, draft=True)
    assert draft["field_values"]["application_number"] is None
    done = await client.patch(f"/form-submissions/{draft['id']}", headers=auth_headers, json={"field_values": {"office": 3}, "submit": True})
    assert done.status_code == 200, done.text
    assert done.json()["field_values"]["application_number"].endswith("/003/000003/DR")
