"""Tests for the cardiovascular response model."""

import pytest

from nephrosim.models.cardiovascular import CardiovascularModel


@pytest.fixture
def cv_model():
    return CardiovascularModel(
        baseline_sbp=140.0,
        baseline_dbp=80.0,
        baseline_hr=75.0,
        blood_volume=5000.0,
        plasma_refill_coeff=0.004,
    )


@pytest.fixture
def diabetic_cv_model():
    return CardiovascularModel(
        baseline_sbp=140.0,
        baseline_dbp=80.0,
        baseline_hr=75.0,
        blood_volume=5000.0,
        plasma_refill_coeff=0.002,
        is_diabetic=True,
    )


class TestCardiovascularModel:
    def test_reset_to_baseline(self, cv_model):
        state = cv_model.reset()
        assert state["systolic_bp"] == 140.0
        assert state["diastolic_bp"] == 80.0
        assert state["heart_rate"] == 75.0

    def test_bp_drops_with_uf(self, cv_model):
        cv_model.reset()
        for _ in range(60):
            state = cv_model.step(1000.0, dt=1.0)
        assert state["systolic_bp"] < 140.0

    def test_hr_increases_with_volume_loss(self, cv_model):
        cv_model.reset()
        for _ in range(60):
            state = cv_model.step(1500.0, dt=1.0)
        assert state["heart_rate"] > 75.0

    def test_no_uf_stable_bp(self, cv_model):
        cv_model.reset()
        for _ in range(60):
            state = cv_model.step(0.0, dt=1.0)
        assert abs(state["systolic_bp"] - 140.0) < 5.0

    def test_volume_tracked(self, cv_model):
        cv_model.reset()
        cv_model.step(600.0, dt=1.0)  # 10 mL/min for 1 min
        assert cv_model.total_uf_volume > 0

    def test_diabetic_more_bp_drop(self, cv_model, diabetic_cv_model):
        cv_model.reset()
        diabetic_cv_model.reset()
        for _ in range(120):
            s1 = cv_model.step(1000.0, dt=1.0)
            s2 = diabetic_cv_model.step(1000.0, dt=1.0)
        assert s2["systolic_bp"] < s1["systolic_bp"]

    def test_hypotension_detection(self, cv_model):
        cv_model.reset()
        cv_model.sbp = 89.0
        assert cv_model.is_hypotensive
        cv_model.sbp = 91.0
        assert not cv_model.is_hypotensive

    def test_bp_stays_in_bounds(self, cv_model):
        cv_model.reset()
        for _ in range(300):
            state = cv_model.step(2000.0, dt=1.0)
        assert state["systolic_bp"] >= 50
        assert state["systolic_bp"] <= 200

    def test_plasma_refill_positive_when_volume_deficit(self, cv_model):
        cv_model.reset()
        cv_model.blood_volume = 4500.0  # 500 mL deficit
        assert cv_model.plasma_refill_rate() > 0

    def test_plasma_refill_zero_at_baseline(self, cv_model):
        cv_model.reset()
        assert abs(cv_model.plasma_refill_rate()) < 0.01

    def test_blood_volume_minimum(self, cv_model):
        cv_model.reset()
        for _ in range(500):
            cv_model.step(2000.0, dt=1.0)
        assert cv_model.blood_volume >= cv_model.blood_volume_initial * 0.7
