from __future__ import annotations

import asyncio


def _create_chat(client, agent_id: str, node_id: str, ref: str) -> str:
    r = client.post(
        "/api/chats",
        json={
            "agent_id": agent_id,
            "node_id": node_id,
            "source": "web",
            "external_chat_ref": ref,
        },
    )
    assert r.status_code == 200, r.text
    return r.json()["chat"]["chat_id"]


def test_chats_pagination_same_updated_at_no_duplicates(sofiia_client, sofiia_module, monkeypatch):
    async def _fake_infer(base_url, agent_id, text, **kwargs):
        return {"response": f"ok:{agent_id}:{text}", "backend": "fake", "model": "fake-model"}

    monkeypatch.setattr(sofiia_module, "infer", _fake_infer)

    created = []
    for idx in range(3):
        cid = _create_chat(sofiia_client, "sofiia", "NODA2", f"same-updated-{idx}")
        created.append(cid)

    async def _force_same_updated():
        db = await sofiia_module._app_db.get_db()
        for cid in created:
            await db.execute(
                "UPDATE sessions SET last_active=? WHERE session_id=?",
                ("2026-03-02T10:00:00Z", cid),
            )
        await db.commit()

    asyncio.run(_force_same_updated())

    p1 = sofiia_client.get("/api/chats?nodes=NODA2&limit=2")
    assert p1.status_code == 200, p1.text
    j1 = p1.json()
    assert j1["count"] == 2
    assert j1["has_more"] is True
    assert j1["next_cursor"]

    p2 = sofiia_client.get(f"/api/chats?nodes=NODA2&limit=2&cursor={j1['next_cursor']}")
    assert p2.status_code == 200, p2.text
    j2 = p2.json()
    assert j2["count"] >= 1

    ids = [x["chat_id"] for x in j1["items"]] + [x["chat_id"] for x in j2["items"]]
    assert len(set(ids)) == 3


def test_messages_pagination_same_ts_no_duplicates(sofiia_client, sofiia_module, monkeypatch):
    async def _fake_infer(base_url, agent_id, text, **kwargs):
        return {"response": f"ok:{agent_id}:{text}", "backend": "fake", "model": "fake-model"}

    monkeypatch.setattr(sofiia_module, "infer", _fake_infer)
    cid = _create_chat(sofiia_client, "sofiia", "NODA2", "same-ts")
    for idx in range(3):
        r = sofiia_client.post(
            f"/api/chats/{cid}/send",
            json={"text": f"msg-{idx}", "idempotency_key": f"same-ts-{idx}"},
        )
        assert r.status_code == 200, r.text

    async def _force_same_ts():
        db = await sofiia_module._app_db.get_db()
        await db.execute(
            "UPDATE messages SET ts=? WHERE session_id=?",
            ("2026-03-02T10:00:00Z", cid),
        )
        await db.commit()

    asyncio.run(_force_same_ts())

    p1 = sofiia_client.get(f"/api/chats/{cid}/messages?limit=2")
    assert p1.status_code == 200, p1.text
    j1 = p1.json()
    assert j1["count"] == 2
    assert j1["has_more"] is True
    assert j1["next_cursor"]

    p2 = sofiia_client.get(f"/api/chats/{cid}/messages?limit=2&cursor={j1['next_cursor']}")
    assert p2.status_code == 200, p2.text
    j2 = p2.json()
    assert j2["count"] >= 1

    ids = [x["message_id"] for x in j1["items"]] + [x["message_id"] for x in j2["items"]]
    # 3 sends => 6 total persisted messages (user + assistant each turn).
    assert len(set(ids)) == 4

