package com.livingworld.modules.soil;

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

class SoilRegionDataTest {

    @Test
    void defaultsAreHealthyValues() {
        SoilRegionData d = SoilRegionData.defaults();
        assertEquals(60.0, d.getFertility(),     1e-9);
        assertEquals(50.0, d.getMoisture(),      1e-9);
        assertEquals(0.0,  d.getContamination(), 1e-9);
        assertEquals(10.0, d.getCompaction(),    1e-9);
        assertEquals(0.0,  d.getErosion(),       1e-9);
    }

    @Test
    void degradeReducesFertilityAndIncreasesContaminationAndErosion() {
        SoilRegionData d = SoilRegionData.defaults();
        d.degrade(10.0);
        assertTrue(d.getFertility() < 60.0,     "fertility should decrease");
        assertTrue(d.getContamination() > 0.0,  "contamination should increase");
        assertTrue(d.getErosion() > 0.0,        "erosion should increase");
    }

    @Test
    void degradeByZeroChangesNothing() {
        SoilRegionData d = SoilRegionData.defaults();
        d.degrade(0.0);
        assertEquals(60.0, d.getFertility(),     1e-9);
        assertEquals(0.0,  d.getContamination(), 1e-9);
        assertEquals(0.0,  d.getErosion(),       1e-9);
    }

    @Test
    void degradeNegativeAmountThrows() {
        SoilRegionData d = SoilRegionData.defaults();
        assertThrows(IllegalArgumentException.class, () -> d.degrade(-1.0));
    }

    @Test
    void recoverIncreasesFertilityAndReducesContaminationAndErosion() {
        SoilRegionData d = new SoilRegionData(40.0, 50.0, 20.0, 10.0, 15.0);
        d.recover(10.0);
        assertTrue(d.getFertility()     > 40.0, "fertility should increase");
        assertTrue(d.getContamination() < 20.0, "contamination should decrease");
        assertTrue(d.getErosion()       < 15.0, "erosion should decrease");
    }

    @Test
    void recoverNegativeAmountThrows() {
        SoilRegionData d = SoilRegionData.defaults();
        assertThrows(IllegalArgumentException.class, () -> d.recover(-1.0));
    }

    @Test
    void valuesAreClampedAbove100() {
        SoilRegionData d = new SoilRegionData(200.0, 200.0, 200.0, 200.0, 200.0);
        assertEquals(100.0, d.getFertility(),     1e-9);
        assertEquals(100.0, d.getMoisture(),      1e-9);
        assertEquals(100.0, d.getContamination(), 1e-9);
        assertEquals(100.0, d.getCompaction(),    1e-9);
        assertEquals(100.0, d.getErosion(),       1e-9);
    }

    @Test
    void valuesAreClampedBelowZero() {
        SoilRegionData d = new SoilRegionData(-10.0, -10.0, -10.0, -10.0, -10.0);
        assertEquals(0.0, d.getFertility(),     1e-9);
        assertEquals(0.0, d.getMoisture(),      1e-9);
        assertEquals(0.0, d.getContamination(), 1e-9);
        assertEquals(0.0, d.getCompaction(),    1e-9);
        assertEquals(0.0, d.getErosion(),       1e-9);
    }

    @Test
    void copyIsIndependent() {
        SoilRegionData original = SoilRegionData.defaults();
        SoilRegionData copy = original.copy();
        copy.degrade(30.0);
        assertEquals(60.0, original.getFertility(), 1e-9);
        assertEquals(0.0, original.getContamination(), 1e-9);
    }

    @Test
    void settersClampValues() {
        SoilRegionData d = SoilRegionData.defaults();
        d.setFertility(-5.0);
        d.setErosion(999.0);
        assertEquals(0.0,   d.getFertility(), 1e-9);
        assertEquals(100.0, d.getErosion(),   1e-9);
    }
}
