"""A lookup column / filter can read the linked record's own system
columns — "application_id.created_by" is who submitted the linked
application — so a list of replies can show only the replies to the
viewer's own applications (filter value {{current_user.id}})."""

import uuid

from app.core.auth import create_access_token
from app.models.identity import Role, User, UserRole, Vendor
from tests.conftest import AsyncSessionLocal


async def _published(client, headers, name, fields):
    made = await client.post("/forms", headers=headers, json={"name": f"{name} {uuid.uuid4().hex[:6]}", "field_definitions": fields})
    assert made.status_code == 201, made.text
    return (await client.post(f"/forms/{made.json()['form_id']}/publish", headers=headers)).json()


async def test_replies_to_the_viewers_own_applications(client, auth_headers, test_tenant):
    tenant_id = test_tenant["tenant_id"]
    app_form = await _published(client, auth_headers, "RTI Application", [{"name": "subject", "type": "text", "label": "Subject"}])
    reply_form = await _published(
        client,
        auth_headers,
        "RTI Reply",
        [
            {"name": "reply_subject", "type": "text", "label": "Subject"},
            {"name": "application_id", "type": "hidden", "label": "Application", "link_source": f"form:{app_form['form_id']}"},
        ],
    )
    tag = uuid.uuid4().hex[:6]
    async with AsyncSessionLocal() as db:
        async with db.begin():
            org = Vendor(tenant_id=tenant_id, organization_name=f"KSRTC {tag}")
            db.add(org)
            await db.flush()
            role = Role(tenant_id=tenant_id, name=f"Public {tag}", scope="portal", action_matrix={"forms": [app_form["form_id"], reply_form["form_id"]]})
            db.add(role)
            await db.flush()
            users = {}
            for name in ("asha", "binu", "officer"):
                u = User(tenant_id=tenant_id, vendor_id=org.id, name=name, email=f"{name}-{tag}@example.com", status="active")
                db.add(u)
                await db.flush()
                db.add(UserRole(user_id=u.id, role_id=role.id))
                users[name] = u.id
    as_ = lambda n: {"Authorization": f"Bearer {create_access_token(tenant_id=tenant_id, user_id=users[n], vendor_id=org.id)}"}  # noqa: E731

    async def submit(who, form, values):
        r = await client.post("/form-submissions", headers=as_(who), json={"form_id": form["form_id"], "form_version": form["version"], "field_values": values})
        assert r.status_code == 201, r.text
        return r.json()["id"]

    asha_app = await submit("asha", app_form, {"subject": "Bus timings"})
    binu_app = await submit("binu", app_form, {"subject": "Fares"})
    await submit("officer", reply_form, {"reply_subject": "Re: timings", "application_id": asha_app})
    await submit("officer", reply_form, {"reply_subject": "Re: fares", "application_id": binu_app})

    query = {
        "source_type": "form",
        "source_id": reply_form["form_id"],
        "columns": ["reply_subject", "application_id.created_by", "application_id.subject"],
        "filters": [{"field": "application_id.created_by", "operator": "equals", "value": "{{current_user.id}}"}],
    }
    for who, subject in (("asha", "Re: timings"), ("binu", "Re: fares")):
        resp = await client.post("/datasets/query", headers=as_(who), json=query)
        assert resp.status_code == 200, resp.text
        rows = resp.json()["rows"]
        assert [r["reply_subject"] for r in rows] == [subject], (who, rows)
        assert rows[0]["application_id.created_by"] == str(users[who])
    # The officer submitted no application, so sees none here.
    assert (await client.post("/datasets/query", headers=as_("officer"), json=query)).json()["rows"] == []
