use sciforge::hub::prelude::constants::elements::atomic_mass;

pub struct AerialChemotroph {
    pub name: &'static str,
    pub reactivesurfaream2: f64,
    pub maxchemosynthesisumolm2s: f64,
    pub suspensionaltitudem: f64,
    pub metabolicreservoirkgm3: f64,
}

impl AerialChemotroph {
    pub fn chemosynthesisrate(&self, substrateppm: f64, irradianceumolm2s: f64, tempk: f64) -> f64 {
        let vmax =
            self.maxchemosynthesisumolm2s * (-3500.0 / tempk).exp() / (-3500.0 / 298.15_f64).exp();
        let km = 50.0;
        let substraterate = vmax * substrateppm / (km + substrateppm);
        let photofactor = 1.0 + irradianceumolm2s / (irradianceumolm2s + 200.0);
        substraterate * photofactor
    }

    pub fn columnproduction(&self, cellrate: f64) -> f64 {
        cellrate * self.reactivesurfaream2 * (1.0 - (-0.3 * self.reactivesurfaream2).exp())
    }

    pub fn volatilefluxmmday(&self, partialpressurekpa: f64, diffusioncoeff: f64) -> f64 {
        diffusioncoeff * partialpressurekpa * self.reactivesurfaream2 * 86400.0 / 1000.0
    }

    pub fn nppkgcm2yr(&self, grossumolm2s: f64) -> f64 {
        let ckgperumol = atomic_mass(6) * 1e-6;
        let gppcarbonkg = grossumolm2s * ckgperumol * 1e-3 * crate::SECONDSPERYEAR;
        gppcarbonkg * 0.4
    }

    pub fn reservoirturnoveryr(&self, npp: f64) -> f64 {
        if npp.abs() < 1e-30 {
            return f64::INFINITY;
        }
        self.metabolicreservoirkgm3 / npp
    }
}

pub fn hypotheticalchemotroph() -> AerialChemotroph {
    AerialChemotroph {
        name: "Hypothetical Chemotroph",
        reactivesurfaream2: 0.0,
        maxchemosynthesisumolm2s: 0.0,
        suspensionaltitudem: 0.0,
        metabolicreservoirkgm3: 0.0,
    }
}

pub fn cloudlayerchemosynthesisefficiency(opticaldepth: f64, scatteringcoeff: f64) -> f64 {
    (-scatteringcoeff * opticaldepth).exp()
}
