use crate::{EUROPA_DAY_HOURS, MAX_SURFACE_TEMP_K, MIN_SURFACE_TEMP_K};

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct ThermalEnvironment {
    pub local_time_hours: f64,
    pub latitude_deg: f64,
    pub shadowed: bool,
}

impl ThermalEnvironment {
    pub fn surface_temperature_k(&self) -> f64 {
        if self.shadowed {
            return MIN_SURFACE_TEMP_K;
        }

        let diurnal_phase = (self.local_time_hours / EUROPA_DAY_HOURS).fract();
        let solar_term = -((diurnal_phase * std::f64::consts::TAU).cos());
        let latitude_cooling = self.latitude_deg.abs() * 0.20;
        let ice_shell_thickness_km = 20.0;
        let tidal_heating = 5.0 / ice_shell_thickness_km;
        (80.0 + 15.0 * solar_term.max(-0.95) - latitude_cooling + tidal_heating)
            .clamp(MIN_SURFACE_TEMP_K, MAX_SURFACE_TEMP_K)
    }
}

pub fn thermal_cycle_span_k(latitude_deg: f64) -> f64 {
    let noon = ThermalEnvironment {
        local_time_hours: EUROPA_DAY_HOURS * 0.5,
        latitude_deg,
        shadowed: false,
    }
    .surface_temperature_k();
    let midnight = ThermalEnvironment {
        local_time_hours: 0.0,
        latitude_deg,
        shadowed: false,
    }
    .surface_temperature_k();
    noon - midnight
}
