use crate::SIDEREAL_ORBIT_PERIOD_S;
use std::f64::consts::PI;

pub const SEMI_MAJOR_AXIS_M: f64 = 9_376_000.0;
pub const ECCENTRICITY: f64 = 0.0151;
pub const INCLINATION_DEG: f64 = 1.093;
pub const PLANET_GRAVITATIONAL_PARAMETER: f64 = 4.282_83e13;

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct PhobosOrbit {
    pub semi_major_axis_m: f64,
    pub eccentricity: f64,
    pub inclination_deg: f64,
    pub true_anomaly_rad: f64,
}

impl Default for PhobosOrbit {
    fn default() -> Self {
        Self::new()
    }
}

impl PhobosOrbit {
    pub fn new() -> Self {
        Self {
            semi_major_axis_m: SEMI_MAJOR_AXIS_M,
            eccentricity: ECCENTRICITY,
            inclination_deg: INCLINATION_DEG,
            true_anomaly_rad: 0.0,
        }
    }
    pub fn orbital_period_s(&self) -> f64 {
        SIDEREAL_ORBIT_PERIOD_S
    }
    pub fn mean_motion_rad_s(&self) -> f64 {
        2.0 * PI / self.orbital_period_s()
    }
    pub fn periapsis_m(&self) -> f64 {
        self.semi_major_axis_m * (1.0 - self.eccentricity)
    }
    pub fn apoapsis_m(&self) -> f64 {
        self.semi_major_axis_m * (1.0 + self.eccentricity)
    }
    pub fn current_distance_m(&self) -> f64 {
        let num = self.semi_major_axis_m * (1.0 - self.eccentricity.powi(2));
        num / (1.0 + self.eccentricity * self.true_anomaly_rad.cos())
    }
    pub fn orbital_speed_m_s(&self, distance_m: f64) -> f64 {
        (PLANET_GRAVITATIONAL_PARAMETER * (2.0 / distance_m - 1.0 / self.semi_major_axis_m)).sqrt()
    }
}
