import json


def add(client, name, score, headers, board="global"):
    client.post(
        f"/{board}/add",
        data=json.dumps({"name": name, "score": score}),
        headers=headers,
    )


class TestTopScores:
    def test_returns_200(self, client):
        resp = client.get("/global/top/10")
        assert resp.status_code == 200

    def test_empty_leaderboard_returns_empty_list(self, client):
        assert client.get("/global/top/10").get_json() == []

    def test_scores_sorted_descending(self, client, auth_headers):
        for name, score in [("Alice", 100), ("Bob", 300), ("Charlie", 200)]:
            add(client, name, score, auth_headers)

        data = client.get("/global/top/3").get_json()
        assert [e["score"] for e in data] == [300, 200, 100]

    def test_n_limits_results(self, client, auth_headers):
        for i in range(5):
            add(client, f"Player{i}", i * 10, auth_headers)

        data = client.get("/global/top/3").get_json()
        assert len(data) == 3

    def test_n_clamped_to_cap(self, client, auth_headers):
        # Requesting 9999 with only 5 entries should return 5, not error
        for i in range(5):
            add(client, f"Player{i}", i, auth_headers)

        data = client.get("/global/top/9999").get_json()
        assert len(data) == 5

    def test_response_has_expected_fields(self, client, auth_headers):
        add(client, "Alice", 100, auth_headers)
        entry = client.get("/global/top/1").get_json()[0]
        assert {"id", "name", "score", "created"} <= entry.keys()

    def test_invalid_leaderboard_returns_404(self, client):
        assert client.get("/nonexistent/top/10").status_code == 404

    def test_does_not_bleed_across_leaderboards(self, client, auth_headers):
        add(client, "Alice", 500, auth_headers, board="weekly")
        data = client.get("/global/top/10").get_json()
        assert data == []
