// tests/test_recoverysystem.cpp

#include "vendor/catch_amalgamated.hpp"
#include "RecoverySystem.h"

// Bring Approx into scope
using Catch::Approx;

TEST_CASE("RecoverySystem basic behavior", "[recoverysystem]") {
    RecoverySystem apogeeRecovery(
        "MainChute",
        RecoverySystem::DeploymentType::Apogee,
        0.0,    // trigger value ignored for Apogee type
        1.5,    // drag coefficient
        2.0     // reference area (m2)
    );

    RecoverySystem altitudeRecovery(
        "DrogueChute",
        RecoverySystem::DeploymentType::Altitude,
        300.0,  // trigger altitude (meters)
        1.2,    // drag coefficient
        1.0     // reference area (m2)
    );

    RecoverySystem timerRecovery(
        "BackupChute",
        RecoverySystem::DeploymentType::Timer,
        15.0,   // trigger time (seconds)
        1.8,    // drag coefficient
        1.5     // reference area (m2)
    );

    SECTION("RecoverySystem properties are correctly initialized") {
        REQUIRE(apogeeRecovery.getName() == "MainChute");
        REQUIRE(altitudeRecovery.getDragCoefficient() == Approx(1.2));
        REQUIRE(timerRecovery.getReferenceArea() == Approx(1.5));
    }

    SECTION("Apogee deployment triggers correctly") {
        bool deploy = apogeeRecovery.checkDeploymentCondition(
            1000.0, // altitude
            -10.0,  // descending
            10.0,   // flight time
            true    // atApogee
        );
        REQUIRE(deploy == true);
    }

    SECTION("Altitude deployment triggers correctly") {
        bool deployHigh = altitudeRecovery.checkDeploymentCondition(
            500.0, // altitude
            -10.0, // descending
            10.0,  // flight time
            false  // not necessarily at apogee
        );
        REQUIRE(deployHigh == false);

        bool deployLow = altitudeRecovery.checkDeploymentCondition(
            250.0, // below trigger altitude
            -10.0, // descending
            10.0,  // flight time
            false
        );
        REQUIRE(deployLow == true);
    }

    SECTION("Timer deployment triggers correctly") {
        bool deployEarly = timerRecovery.checkDeploymentCondition(
            500.0, // altitude
            -10.0, // descending
            10.0,  // flight time (too early)
            false
        );
        REQUIRE(deployEarly == false);

        bool deployLate = timerRecovery.checkDeploymentCondition(
            500.0, // altitude
            -10.0, // descending
            20.0,  // flight time (after timer)
            false
        );
        REQUIRE(deployLate == true);
    }

    SECTION("Deployment state tracks correctly") {
        RecoverySystem testRecovery(
            "TestChute",
            RecoverySystem::DeploymentType::Apogee,
            0.0,
            1.5,
            2.0
        );

        REQUIRE(testRecovery.isDeployed() == false);

        testRecovery.deploy();

        REQUIRE(testRecovery.isDeployed() == true);

        // Once deployed, checkDeploymentCondition should return false
        REQUIRE(testRecovery.checkDeploymentCondition(
            1000.0, -10.0, 10.0, true) == false);
    }
}
