use crate::config::parameters::*;

pub struct Centaur {
    pub radius: f64,
    pub density: f64,
    pub mass: f64,
    pub semi_major_axis: f64,
    pub eccentricity: f64,
    pub inclination: f64,
    pub albedo: f64,
    pub coma_active: bool,
    pub perihelion_distance: f64,
}

impl Centaur {
    pub fn new(radius_m: f64, density: f64, semi_major_au: f64, eccentricity: f64) -> Self {
        let radius = radius_m.clamp(MIN_ASTEROID_RADIUS, MAX_ASTEROID_RADIUS);
        let density = density.clamp(300.0, 3000.0);
        let mass = sphere_mass(radius, density);
        let ecc = eccentricity.clamp(0.0, 0.999);
        let perihelion = semi_major_au * (1.0 - ecc);
        let coma_active = perihelion < 12.0;

        Self {
            radius,
            density,
            mass,
            semi_major_axis: semi_major_au,
            eccentricity: ecc,
            inclination: 0.0,
            albedo: 0.07,
            coma_active,
            perihelion_distance: perihelion,
        }
    }

    pub fn with_inclination(mut self, inc_deg: f64) -> Self {
        self.inclination = inc_deg.to_radians();
        self
    }

    pub fn with_albedo(mut self, a: f64) -> Self {
        self.albedo = a.clamp(0.01, 0.5);
        self
    }

    pub fn perihelion_au(&self) -> f64 {
        self.perihelion_distance
    }

    pub fn aphelion_au(&self) -> f64 {
        self.semi_major_axis * (1.0 + self.eccentricity)
    }

    pub fn orbital_period(&self) -> f64 {
        orbital_period(self.semi_major_axis, SOLAR_MASS)
    }

    pub fn orbital_period_years(&self) -> f64 {
        self.orbital_period() / YEAR
    }

    pub fn surface_gravity(&self) -> f64 {
        surface_gravity(self.mass, self.radius)
    }

    pub fn escape_velocity(&self) -> f64 {
        escape_velocity(self.mass, self.radius)
    }

    pub fn tisserand_jupiter(&self) -> f64 {
        tisserand_parameter(
            self.semi_major_axis * AU,
            self.eccentricity,
            self.inclination,
            5.2 * AU,
        )
    }

    pub fn tisserand_neptune(&self) -> f64 {
        tisserand_parameter(
            self.semi_major_axis * AU,
            self.eccentricity,
            self.inclination,
            30.07 * AU,
        )
    }

    pub fn dynamical_lifetime_estimate(&self) -> f64 {
        1e7 * YEAR * (self.semi_major_axis / 10.0).powf(1.5)
    }

    pub fn is_cometary(&self) -> bool {
        self.coma_active
    }

    pub fn equilibrium_temperature(&self) -> f64 {
        equilibrium_temperature(SOLAR_LUMINOSITY, self.semi_major_axis * AU, self.albedo)
    }

    pub fn sublimation_distance_water(&self) -> f64 {
        2.7
    }

    pub fn is_inside_snow_line(&self) -> bool {
        self.perihelion_distance < self.sublimation_distance_water()
    }
}
