package com.livingworld.modules.ecosystem;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class EcosystemRegionDataTest {

    @Test
    void defaultsAreModerateHealth() {
        EcosystemRegionData d = EcosystemRegionData.defaults();
        assertEquals(60.0, d.getEcosystemHealth(), 1e-9);
        assertEquals(20.0, d.getStress(),          1e-9);
        assertEquals(50.0, d.getResilience(),      1e-9);
        assertEquals(5.0,  d.getRecoveryRate(),    1e-9);
    }

    @Test
    void applyStressIncreasesStressAndDegradesResilience() {
        EcosystemRegionData d = EcosystemRegionData.defaults();
        d.applyStress(10.0);
        assertEquals(30.0, d.getStress(), 1e-9);
        assertTrue(d.getResilience() < 50.0, "resilience should decrease under stress");
    }

    @Test
    void applyStressNegativeThrows() {
        assertThrows(IllegalArgumentException.class,
                () -> EcosystemRegionData.defaults().applyStress(-1.0));
    }

    @Test
    void applyStressClampsAt100() {
        EcosystemRegionData d = new EcosystemRegionData(60.0, 90.0, 50.0, 5.0);
        d.applyStress(20.0);
        assertEquals(100.0, d.getStress(), 1e-9);
    }

    @Test
    void applyRecoveryDecreasesStressAndIncreasesResilience() {
        EcosystemRegionData d = new EcosystemRegionData(60.0, 40.0, 50.0, 5.0);
        d.applyRecovery(10.0);
        assertEquals(30.0, d.getStress(), 1e-9);
        assertTrue(d.getResilience() > 50.0, "resilience should increase during recovery");
    }

    @Test
    void applyRecoveryNegativeThrows() {
        assertThrows(IllegalArgumentException.class,
                () -> EcosystemRegionData.defaults().applyRecovery(-1.0));
    }

    @Test
    void applyRecoveryClampsBelowZero() {
        EcosystemRegionData d = new EcosystemRegionData(60.0, 5.0, 50.0, 5.0);
        d.applyRecovery(20.0);
        assertEquals(0.0, d.getStress(), 1e-9);
    }

    @Test
    void constructorClampsAbove100() {
        EcosystemRegionData d = new EcosystemRegionData(200.0, 200.0, 200.0, 200.0);
        assertEquals(100.0, d.getEcosystemHealth(), 1e-9);
        assertEquals(100.0, d.getStress(),          1e-9);
        assertEquals(100.0, d.getResilience(),      1e-9);
        assertEquals(100.0, d.getRecoveryRate(),    1e-9);
    }

    @Test
    void constructorClampsBelowZero() {
        EcosystemRegionData d = new EcosystemRegionData(-1.0, -1.0, -1.0, -1.0);
        assertEquals(0.0, d.getEcosystemHealth(), 1e-9);
        assertEquals(0.0, d.getStress(),          1e-9);
        assertEquals(0.0, d.getResilience(),      1e-9);
        assertEquals(0.0, d.getRecoveryRate(),    1e-9);
    }

    @Test
    void copyIsIndependent() {
        EcosystemRegionData original = EcosystemRegionData.defaults();
        EcosystemRegionData copy = original.copy();
        copy.applyStress(50.0);
        assertEquals(20.0, original.getStress(), 1e-9);
    }

    @Test
    void settersClampValues() {
        EcosystemRegionData d = EcosystemRegionData.defaults();
        d.setStress(-10.0);
        d.setResilience(999.0);
        assertEquals(0.0,   d.getStress(),     1e-9);
        assertEquals(100.0, d.getResilience(), 1e-9);
    }

    @Test
    void normalizeDoesNotChangeLegalValues() {
        EcosystemRegionData d = EcosystemRegionData.defaults();
        d.normalize();
        assertEquals(60.0, d.getEcosystemHealth(), 1e-9);
        assertEquals(20.0, d.getStress(),          1e-9);
    }
}
