"""Tests for the two-compartment urea kinetics model."""

import pytest

from nephrosim.models.urea_kinetics import UreaKineticsModel


@pytest.fixture
def model():
    return UreaKineticsModel(
        ecf_volume=14500,
        icf_volume=29000,
        koa=800,
        intercompartment_kc=800,
        urea_generation_rate=8.0,
    )


class TestUreaKineticsModel:
    def test_initial_state(self, model):
        state = model.reset(70.0, 70.0)
        assert abs(state[0] - 70.0) < 0.01
        assert abs(state[1] - 70.0) < 0.01

    def test_clearance_positive(self, model):
        k = model.dialyzer_clearance(350, 500)
        assert k > 0

    def test_clearance_bounded_by_blood_flow(self, model):
        k = model.dialyzer_clearance(200, 500)
        assert k <= 200

    def test_clearance_bounded_by_dialysate_flow(self, model):
        k = model.dialyzer_clearance(500, 300)
        assert k <= 300

    def test_clearance_increases_with_blood_flow(self, model):
        k1 = model.dialyzer_clearance(200, 500)
        k2 = model.dialyzer_clearance(400, 500)
        assert k2 > k1

    def test_clearance_increases_with_dialysate_flow(self, model):
        k1 = model.dialyzer_clearance(350, 300)
        k2 = model.dialyzer_clearance(350, 600)
        assert k2 > k1

    def test_clearance_equal_flows(self, model):
        k = model.dialyzer_clearance(400, 400)
        assert k > 0
        assert k < 400

    def test_urea_decreases_during_dialysis(self, model):
        model.reset(70.0, 70.0)
        result = model.step(350, 500, dt=10.0)
        assert result["c_ecf"] < 70.0

    def test_ecf_clears_faster_than_icf(self, model):
        model.reset(70.0, 70.0)
        result = model.step(350, 500, dt=30.0)
        assert result["c_ecf"] < result["c_icf"]

    def test_urea_removed_positive(self, model):
        model.reset(70.0, 70.0)
        result = model.step(350, 500, dt=5.0)
        assert result["urea_removed_mg"] > 0

    def test_kt_v_increases_over_time(self, model):
        model.reset(70.0, 70.0)
        kt_v1 = model.compute_kt_v(250, 60)
        kt_v2 = model.compute_kt_v(250, 120)
        assert kt_v2 > kt_v1

    def test_kt_v_target_reachable(self, model):
        model.reset(70.0, 70.0)
        kt_v = model.compute_kt_v(250, 240)
        assert kt_v > 1.0  # should be achievable in 4 hours

    def test_zero_flow_no_clearance(self, model):
        k = model.dialyzer_clearance(0, 500)
        assert k < 1.0

    def test_multiple_steps_cumulative(self, model):
        model.reset(70.0, 70.0)
        for _ in range(60):
            result = model.step(350, 500, dt=1.0)
        assert result["c_ecf"] < 50.0  # significant clearance after 60 min

    def test_state_stays_positive(self, model):
        model.reset(70.0, 70.0)
        for _ in range(300):
            result = model.step(500, 800, dt=1.0)
        assert result["c_ecf"] >= 0
        assert result["c_icf"] >= 0
