"""Saved views: each person's own named views of a page's Data List."""

import uuid

from tests.conftest import AsyncSessionLocal


async def _page(client, headers):
    resp = await client.post("/pages", headers=headers, json={"name": f"Replies {uuid.uuid4().hex[:6]}", "blocks": []})
    assert resp.status_code == 201, resp.text
    return resp.json()["id"]


async def test_saved_views_are_each_persons_own(client, auth_headers, test_tenant):
    page_id = await _page(client, auth_headers)
    base = {"page_id": page_id, "block_id": "list"}
    first = await client.post("/saved-views", headers=auth_headers, json={**base, "name": "Open ones", "state": {"sort": {"column": "created_at", "dir": "desc"}}, "is_default": True})
    assert first.status_code == 201, first.text
    second = await client.post("/saved-views", headers=auth_headers, json={**base, "name": "Mine", "state": {"bars": {"bar": {"me": True}}}, "is_default": True})
    views = (await client.get("/saved-views", headers=auth_headers, params=base)).json()
    assert [(v["name"], v["is_default"]) for v in views] == [("Mine", True), ("Open ones", False)]  # one default

    # Saving under a name already used replaces that view.
    again = await client.post("/saved-views", headers=auth_headers, json={**base, "name": "open ones", "state": {"view": "cards"}})
    assert again.json()["id"] == first.json()["id"] and again.json()["state"] == {"view": "cards"}
    assert len((await client.get("/saved-views", headers=auth_headers, params=base)).json()) == 2

    renamed = await client.patch(f"/saved-views/{second.json()['id']}", headers=auth_headers, json={"name": "Only mine", "is_default": False})
    assert renamed.json()["name"] == "Only mine" and renamed.json()["is_default"] is False

    # Another person sees none of them and can't touch them.
    from app.core.auth import create_access_token, hash_password
    from app.models.identity import User

    async with AsyncSessionLocal() as db:
        async with db.begin():
            other = User(tenant_id=test_tenant["tenant_id"], name="Other", email=f"other-{uuid.uuid4().hex[:6]}@example.com", password_hash=hash_password("pytest-password-123"), status="active")
            db.add(other)
            await db.flush()
            other_id = other.id
    other_headers = {**auth_headers, "Authorization": f"Bearer {create_access_token(tenant_id=test_tenant['tenant_id'], user_id=other_id, vendor_id=None)}"}
    assert (await client.get("/saved-views", headers=other_headers, params=base)).json() == []
    assert (await client.delete(f"/saved-views/{first.json()['id']}", headers=other_headers)).status_code == 404
    assert (await client.delete(f"/saved-views/{first.json()['id']}", headers=auth_headers)).status_code == 204


async def test_saved_view_limits(client, auth_headers):
    page_id = await _page(client, auth_headers)
    huge = {"x": "y" * 30_000}
    resp = await client.post("/saved-views", headers=auth_headers, json={"page_id": page_id, "block_id": "list", "name": "Huge", "state": huge})
    assert resp.status_code == 422
    resp = await client.post("/saved-views", headers=auth_headers, json={"page_id": str(uuid.uuid4()), "block_id": "list", "name": "Nowhere"})
    assert resp.status_code == 404
