use crate::physics::orbit::MERCURY_MASS;
use crate::physics::orbit::MERCURY_RADIUS;
use sciforge::hub::domain::astronomy::orbits::kepler_period;
use sciforge::hub::domain::common::constants::G;

pub struct ArtificialSatellite {
    pub name: &'static str,
    pub periapsis_km: f64,
    pub apoapsis_km: f64,
    pub inclination_deg: f64,
    pub eccentricity: f64,
}

impl ArtificialSatellite {
    pub fn semi_major_axis_m(&self) -> f64 {
        ((self.periapsis_km + self.apoapsis_km) / 2.0) * 1000.0 + MERCURY_RADIUS
    }

    pub fn orbital_period_s(&self) -> f64 {
        kepler_period(self.semi_major_axis_m(), MERCURY_MASS)
    }

    pub fn periapsis_radius_m(&self) -> f64 {
        self.periapsis_km * 1000.0 + MERCURY_RADIUS
    }

    pub fn apoapsis_radius_m(&self) -> f64 {
        self.apoapsis_km * 1000.0 + MERCURY_RADIUS
    }

    pub fn velocity_at_periapsis(&self) -> f64 {
        let a = self.semi_major_axis_m();
        let r = self.periapsis_radius_m();
        (G * MERCURY_MASS * (2.0 / r - 1.0 / a)).sqrt()
    }

    pub fn velocity_at_apoapsis(&self) -> f64 {
        let a = self.semi_major_axis_m();
        let r = self.apoapsis_radius_m();
        (G * MERCURY_MASS * (2.0 / r - 1.0 / a)).sqrt()
    }
}

pub fn messenger() -> ArtificialSatellite {
    ArtificialSatellite {
        name: "MESSENGER",
        periapsis_km: 200.0,
        apoapsis_km: 15193.0,
        inclination_deg: 82.5,
        eccentricity: 0.74,
    }
}

pub fn bepicolombo_mpo() -> ArtificialSatellite {
    ArtificialSatellite {
        name: "BepiColombo MPO",
        periapsis_km: 480.0,
        apoapsis_km: 1500.0,
        inclination_deg: 90.0,
        eccentricity: 0.16,
    }
}

pub fn bepicolombo_mmo() -> ArtificialSatellite {
    ArtificialSatellite {
        name: "BepiColombo MMO",
        periapsis_km: 590.0,
        apoapsis_km: 11640.0,
        inclination_deg: 90.0,
        eccentricity: 0.83,
    }
}

pub fn all_missions() -> Vec<ArtificialSatellite> {
    vec![messenger(), bepicolombo_mpo(), bepicolombo_mmo()]
}
