pub use sciforge::hub::prelude::constants::{C, G, K_B, SOLAR_MASS};

pub const PI: f64 = std::f64::consts::PI;
pub const AU: f64 = 1.496e11;
pub const YEAR: f64 = 365.25 * 86400.0;
pub const SOLAR_LUMINOSITY: f64 = 3.828e26;
pub const EARTH_MASS: f64 = 5.972e24;
pub const EARTH_RADIUS: f64 = 6.371e6;
pub const STEFAN_BOLTZMANN: f64 = 5.6704e-8;

pub const CERES_MASS: f64 = 9.393e20;
pub const VESTA_MASS: f64 = 2.59076e20;

pub const MIN_ASTEROID_RADIUS: f64 = 0.5;
pub const MAX_ASTEROID_RADIUS: f64 = 5.0e5;

pub fn sphere_volume(radius: f64) -> f64 {
    (4.0 / 3.0) * std::f64::consts::PI * radius.powi(3)
}

pub fn sphere_mass(radius: f64, density: f64) -> f64 {
    sphere_volume(radius) * density
}

pub fn surface_gravity(mass: f64, radius: f64) -> f64 {
    if radius < 1.0 {
        return 0.0;
    }
    G * mass / (radius * radius)
}

pub fn escape_velocity(mass: f64, radius: f64) -> f64 {
    if radius < 1.0 {
        return 0.0;
    }
    (2.0 * G * mass / radius).sqrt()
}

pub fn orbital_period(semi_major_au: f64, central_mass: f64) -> f64 {
    let a = semi_major_au * AU;
    2.0 * std::f64::consts::PI * (a.powi(3) / (G * central_mass)).sqrt()
}

pub fn vis_viva(central_mass: f64, r: f64, a: f64) -> f64 {
    (G * central_mass * (2.0 / r - 1.0 / a)).sqrt()
}

pub fn hill_sphere(a: f64, m_body: f64, m_central: f64) -> f64 {
    a * (m_body / (3.0 * m_central)).powf(1.0 / 3.0)
}

pub fn tisserand_parameter(a: f64, e: f64, i_rad: f64, a_planet: f64) -> f64 {
    let ratio = a_planet / a;
    ratio + 2.0 * ((1.0 - e * e) * a / a_planet).sqrt() * i_rad.cos()
}

pub fn bond_albedo_to_geometric(bond: f64, phase_integral: f64) -> f64 {
    bond / phase_integral
}

pub fn equilibrium_temperature(luminosity: f64, distance: f64, albedo: f64) -> f64 {
    let flux = luminosity / (4.0 * std::f64::consts::PI * distance * distance);
    ((flux * (1.0 - albedo)) / (4.0 * STEFAN_BOLTZMANN)).powf(0.25)
}
