use sciforge::hub::domain::meteorology::radiation::{
    planck_function, radiative_forcing_co2, solar_constant, solar_zenith_angle,
    stefan_boltzmann_flux,
};
use sciforge::hub::prelude::constants::SIGMA_SB;

pub const NEPTUNEEQUILIBRIUMTEMPK: f64 = 46.6;
pub const NEPTUNEEFFECTIVETEMPK: f64 = 59.3;
pub const NEPTUNEALBEDO: f64 = crate::BONDALBEDO;

pub struct ClimateState {
    pub ch4fraction: f64,
    pub globalmeantempk: f64,
    pub albedo: f64,
    pub internalheatwm2: f64,
}

impl ClimateState {
    pub fn current() -> Self {
        Self {
            ch4fraction: 0.015,
            globalmeantempk: crate::ONEBARTEMPK,
            albedo: NEPTUNEALBEDO,
            internalheatwm2: crate::INTERNALHEATINGWM2,
        }
    }

    pub fn outgoinglongwaveradiation(&self) -> f64 {
        stefan_boltzmann_flux(self.globalmeantempk)
    }

    pub fn absorbedsolarradiation(&self) -> f64 {
        solar_constant() * (1.0 - self.albedo) / (4.0 * 30.07 * 30.07)
    }

    pub fn internalplussolarheatflux(&self) -> f64 {
        self.absorbedsolarradiation() + self.internalheatwm2
    }

    pub fn energyimbalance(&self) -> f64 {
        self.internalplussolarheatflux() - self.outgoinglongwaveradiation()
    }

    pub fn effectiveemissiontemperature(&self) -> f64 {
        let flux = self.internalplussolarheatflux();
        (flux / SIGMA_SB).powf(0.25)
    }

    pub fn methanegreenhouseeffectk(&self) -> f64 {
        self.globalmeantempk - self.effectiveemissiontemperature()
    }

    pub fn ch4radiativeforcing(&self) -> f64 {
        0.036 * (self.ch4fraction * 1e6).sqrt()
    }
}

pub fn solarzenith(latitudedeg: f64, declinationdeg: f64, hourangledeg: f64) -> f64 {
    solar_zenith_angle(latitudedeg, declinationdeg, hourangledeg)
}

pub fn planck_spectral_radiance(wavelengthm: f64, temperaturek: f64) -> f64 {
    planck_function(wavelengthm, temperaturek)
}

pub fn solarfluxatneptune() -> f64 {
    solar_constant() / (30.07 * 30.07)
}

pub fn co2doublingforcing() -> f64 {
    radiative_forcing_co2(560.0, 280.0)
}
