from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)


def test_zero_counts_yields_zero_score():
    resp = client.post(
        "/neighborhood/score",
        json={
            "district": "Quận 7",
            "city": "Hồ Chí Minh",
            "poi_counts": {
                "education": 0,
                "healthcare": 0,
                "transport": 0,
                "shopping": 0,
                "greenery": 0,
                "safety": 0,
            },
        },
    )
    assert resp.status_code == 200
    data = resp.json()
    assert data["total_score"] == 0
    assert data["education_score"] == 0
    assert data["algorithm_version"].startswith("neighborhood-heuristic")


def test_saturated_counts_yields_one_hundred():
    resp = client.post(
        "/neighborhood/score",
        json={
            "district": "Quận 1",
            "city": "Hồ Chí Minh",
            "poi_counts": {
                "education": 50,
                "healthcare": 50,
                "transport": 50,
                "shopping": 50,
                "greenery": 50,
                "safety": 50,
            },
        },
    )
    assert resp.status_code == 200
    data = resp.json()
    assert data["total_score"] == 100.0
    assert data["education_score"] == 10
    assert data["safety_score"] == 10


def test_partial_counts_apply_weighted_average():
    # Hit the linear cap on transport+greenery only; others 0.
    # transport weight 20 + greenery 15 = 35 → expect total 35.0.
    resp = client.post(
        "/neighborhood/score",
        json={
            "district": "Bình Thạnh",
            "city": "Hồ Chí Minh",
            "poi_counts": {
                "education": 0,
                "healthcare": 0,
                "transport": 12,
                "shopping": 0,
                "greenery": 6,
                "safety": 0,
            },
        },
    )
    assert resp.status_code == 200
    data = resp.json()
    assert data["transport_score"] == 10
    assert data["greenery_score"] == 10
    assert data["total_score"] == 35.0
    assert data["poi_counts"]["transport"] == 12


def test_below_max_uses_linear_scale():
    # education max=15, count=3 → 2.0; weight 20 → contributes 4.0
    resp = client.post(
        "/neighborhood/score",
        json={
            "district": "Quận 3",
            "city": "Hồ Chí Minh",
            "poi_counts": {
                "education": 3,
                "healthcare": 0,
                "transport": 0,
                "shopping": 0,
                "greenery": 0,
                "safety": 0,
            },
        },
    )
    assert resp.status_code == 200
    data = resp.json()
    assert data["education_score"] == 2.0
    assert data["total_score"] == 4.0


def test_validation_rejects_negative_count():
    resp = client.post(
        "/neighborhood/score",
        json={
            "district": "Quận 1",
            "city": "Hồ Chí Minh",
            "poi_counts": {
                "education": -1,
                "healthcare": 0,
                "transport": 0,
                "shopping": 0,
                "greenery": 0,
                "safety": 0,
            },
        },
    )
    assert resp.status_code == 422
