use sciforge::hub::domain::geology::petrology::{
    crystal_settling_velocity, differentiation_index, liquidus_temperature, mg_number,
    solidus_depression, total_alkali_silica,
};

pub struct MercuryVolcanism {
    pub currently_active: bool,
    pub past_volcanic_plains_fraction: f64,
}

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

impl MercuryVolcanism {
    pub fn new() -> Self {
        Self {
            currently_active: false,
            past_volcanic_plains_fraction: 0.27,
        }
    }

    pub fn smooth_plains_area_km2(&self) -> f64 {
        self.past_volcanic_plains_fraction * 7.48e7
    }

    pub fn volcanic_vents_count(&self) -> u32 {
        174
    }

    pub fn last_eruption_estimate_gyr(&self) -> f64 {
        1.0
    }

    pub fn intercrater_plains_fraction(&self) -> f64 {
        0.40
    }

    pub fn total_volcanic_coverage(&self) -> f64 {
        self.past_volcanic_plains_fraction + self.intercrater_plains_fraction()
    }
}

pub struct MercuryMagma {
    pub sio2_wt_percent: f64,
    pub mgo_wt_percent: f64,
    pub feo_wt_percent: f64,
    pub na2o_wt_percent: f64,
    pub k2o_wt_percent: f64,
    pub h2o_wt_percent: f64,
    pub temperature_c: f64,
}

impl MercuryMagma {
    pub fn northern_plains() -> Self {
        Self {
            sio2_wt_percent: 57.0,
            mgo_wt_percent: 8.0,
            feo_wt_percent: 1.5,
            na2o_wt_percent: 6.0,
            k2o_wt_percent: 0.1,
            h2o_wt_percent: 0.0,
            temperature_c: 1400.0,
        }
    }

    pub fn high_mg_region() -> Self {
        Self {
            sio2_wt_percent: 50.0,
            mgo_wt_percent: 15.0,
            feo_wt_percent: 2.0,
            na2o_wt_percent: 3.5,
            k2o_wt_percent: 0.05,
            h2o_wt_percent: 0.0,
            temperature_c: 1500.0,
        }
    }

    pub fn mg_number(&self) -> f64 {
        mg_number(self.mgo_wt_percent, self.feo_wt_percent)
    }

    pub fn total_alkali(&self) -> f64 {
        total_alkali_silica(
            self.na2o_wt_percent + self.k2o_wt_percent,
            self.sio2_wt_percent,
        )
    }

    pub fn liquidus_temp_c(&self) -> f64 {
        liquidus_temperature(self.sio2_wt_percent, self.h2o_wt_percent, 1000.0)
    }

    pub fn solidus_depression_c(&self) -> f64 {
        solidus_depression(self.h2o_wt_percent, 1000.0, 1.0)
    }

    pub fn differentiation_idx(&self) -> f64 {
        differentiation_index(
            self.sio2_wt_percent,
            self.na2o_wt_percent,
            self.k2o_wt_percent,
            0.0,
        )
    }

    pub fn olivine_settling_velocity(&self, crystal_diameter_m: f64) -> f64 {
        let crystal_density = 3300.0;
        let melt_density = 2700.0;
        let melt_viscosity = 10.0;
        crystal_settling_velocity(
            crystal_density,
            melt_density,
            crystal_diameter_m,
            melt_viscosity,
        )
    }
}

pub struct Hollow {
    pub name: &'static str,
    pub diameter_range_m: (f64, f64),
    pub depth_m: f64,
}

pub fn known_hollow_fields() -> Vec<Hollow> {
    vec![
        Hollow {
            name: "Raditladi",
            diameter_range_m: (100.0, 18_000.0),
            depth_m: 40.0,
        },
        Hollow {
            name: "Tyagaraja",
            diameter_range_m: (50.0, 5_000.0),
            depth_m: 30.0,
        },
        Hollow {
            name: "Sander",
            diameter_range_m: (100.0, 8_000.0),
            depth_m: 35.0,
        },
        Hollow {
            name: "Eminescu",
            diameter_range_m: (80.0, 10_000.0),
            depth_m: 45.0,
        },
    ]
}

pub fn hollow_count() -> u32 {
    4000
}
