"""Tests for industrial AVM rent estimation endpoint."""

from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)

# ── Minimal valid request payload ───────────────────────────────

_PREDICT_PAYLOAD = {
    "province": "Bình Dương",
    "region": "south",
    "park_occupancy_rate": 0.85,
    "park_area_ha": 500,
    "park_age_years": 10,
    "distance_to_port_km": 60,
    "distance_to_airport_km": 30,
    "distance_to_highway_km": 5,
    "property_type": "factory",
    "area_m2": 5000,
    "ceiling_height_m": 10,
    "floor_load_ton_m2": 3.0,
    "power_capacity_kva": 1000,
}


def test_predict_industrial_heuristic():
    """Predict using heuristic fallback (no trained model)."""
    resp = client.post("/avm/industrial/predict", json=_PREDICT_PAYLOAD)
    assert resp.status_code == 200
    data = resp.json()

    assert data["estimated_rent_usd_m2"] > 0
    assert 0 <= data["confidence"] <= 1
    assert data["rent_range_low_usd_m2"] < data["estimated_rent_usd_m2"]
    assert data["rent_range_high_usd_m2"] > data["estimated_rent_usd_m2"]
    assert data["annual_rent_usd_m2"] > 0
    assert data["total_monthly_rent_usd"] > 0
    assert data["model_version"] == "heuristic-v1"


def test_predict_industrial_returns_comparables():
    """Heuristic should return comparable industrial properties."""
    resp = client.post("/avm/industrial/predict", json=_PREDICT_PAYLOAD)
    data = resp.json()

    comps = data["comparables"]
    assert len(comps) > 0
    for c in comps:
        assert c["park_name"]
        assert c["rent_usd_m2"] > 0
        assert 0 <= c["similarity_score"] <= 1


def test_predict_industrial_returns_drivers():
    """Heuristic should return feature importance drivers."""
    resp = client.post("/avm/industrial/predict", json=_PREDICT_PAYLOAD)
    data = resp.json()

    drivers = data["drivers"]
    assert len(drivers) > 0
    assert all(0 <= d["importance"] <= 1 for d in drivers)


def test_predict_industrial_ready_built_premium():
    """Ready-built factories should be priced higher than standard."""
    standard = client.post("/avm/industrial/predict", json=_PREDICT_PAYLOAD).json()
    rbf_payload = {**_PREDICT_PAYLOAD, "property_type": "ready_built_factory"}
    ready_built = client.post("/avm/industrial/predict", json=rbf_payload).json()

    assert ready_built["estimated_rent_usd_m2"] > standard["estimated_rent_usd_m2"]


def test_predict_industrial_open_yard_discount():
    """Open yards should be cheaper than factories."""
    factory = client.post("/avm/industrial/predict", json=_PREDICT_PAYLOAD).json()
    yard_payload = {**_PREDICT_PAYLOAD, "property_type": "open_yard"}
    yard = client.post("/avm/industrial/predict", json=yard_payload).json()

    assert yard["estimated_rent_usd_m2"] < factory["estimated_rent_usd_m2"]


def test_predict_industrial_high_occupancy_premium():
    """Higher park occupancy should increase rent."""
    low = client.post(
        "/avm/industrial/predict",
        json={**_PREDICT_PAYLOAD, "park_occupancy_rate": 0.50},
    ).json()
    high = client.post(
        "/avm/industrial/predict",
        json={**_PREDICT_PAYLOAD, "park_occupancy_rate": 0.95},
    ).json()

    assert high["estimated_rent_usd_m2"] > low["estimated_rent_usd_m2"]


def test_predict_industrial_annual_rent():
    """Annual rent should be 12x monthly rent."""
    resp = client.post("/avm/industrial/predict", json=_PREDICT_PAYLOAD).json()
    expected_annual = round(resp["estimated_rent_usd_m2"] * 12, 2)
    assert resp["annual_rent_usd_m2"] == expected_annual


def test_predict_industrial_total_rent():
    """Total monthly rent should be rent/m² × area."""
    resp = client.post("/avm/industrial/predict", json=_PREDICT_PAYLOAD).json()
    expected_total = resp["estimated_rent_usd_m2"] * _PREDICT_PAYLOAD["area_m2"]
    assert abs(resp["total_monthly_rent_usd"] - expected_total) < 1.0


def test_predict_industrial_validation_error():
    """Missing required fields should return 422."""
    resp = client.post("/avm/industrial/predict", json={"area_m2": 5000})
    assert resp.status_code == 422


def test_predict_industrial_invalid_occupancy():
    """Occupancy rate outside 0-1 should be rejected."""
    resp = client.post(
        "/avm/industrial/predict",
        json={**_PREDICT_PAYLOAD, "park_occupancy_rate": 1.5},
    )
    assert resp.status_code == 422
