pub struct InteriorLayerData {
    pub resolutionarcsec: f64,
    pub data: Vec<f64>,
    pub rows: usize,
    pub cols: usize,
}

impl InteriorLayerData {
    pub fn global(resolutionarcsec: f64) -> Self {
        let effectiveres = resolutionarcsec.max(600.0);
        let rows = (180.0 * 3600.0 / effectiveres) as usize;
        let cols = (360.0 * 3600.0 / effectiveres) as usize;
        let mut data = vec![0.0; rows * cols];
        for r in 0..rows {
            for c in 0..cols {
                let lat = 90.0 - (r as f64 + 0.5) * effectiveres / 3600.0;
                let lon = -180.0 + (c as f64 + 0.5) * effectiveres / 3600.0;
                let depth = interiorlayerdepthkm(lat, lon);
                data[r * cols + c] = depth;
            }
        }
        Self {
            resolutionarcsec: effectiveres,
            data,
            rows,
            cols,
        }
    }

    pub fn sample(&self, latdeg: f64, londeg: f64) -> f64 {
        let latfrac = (latdeg + 90.0) / 180.0;
        let lonfrac = (londeg + 180.0) / 360.0;
        let row =
            ((1.0 - latfrac) * (self.rows - 1) as f64).clamp(0.0, (self.rows - 1) as f64) as usize;
        let col = (lonfrac * (self.cols - 1) as f64).clamp(0.0, (self.cols - 1) as f64) as usize;
        self.data.get(row * self.cols + col).copied().unwrap_or(0.0)
    }

    pub fn isicemantle(&self, latdeg: f64, londeg: f64) -> bool {
        self.sample(latdeg, londeg) < -7000.0
    }

    pub fn interiorstats() -> InteriorStats {
        InteriorStats {
            atmospheredepthkm: 7000.0,
            icemantledepthkm: 17000.0,
            coreradiuskm: 7500.0,
            totalradiuskm: 24622.0,
        }
    }
}

pub struct InteriorStats {
    pub atmospheredepthkm: f64,
    pub icemantledepthkm: f64,
    pub coreradiuskm: f64,
    pub totalradiuskm: f64,
}

pub struct InteriorLayer {
    pub name: String,
    pub outerboundarykm: f64,
    pub innerboundarykm: f64,
    pub avgdensitykgm3: f64,
}

impl InteriorLayer {
    pub fn majorlayers() -> Vec<Self> {
        vec![
            Self {
                name: "Upper Atmosphere".into(),
                outerboundarykm: 24622.0,
                innerboundarykm: 24572.0,
                avgdensitykgm3: 0.45,
            },
            Self {
                name: "Lower Atmosphere".into(),
                outerboundarykm: 24572.0,
                innerboundarykm: 17622.0,
                avgdensitykgm3: 50.0,
            },
            Self {
                name: "Superionic Ice Mantle".into(),
                outerboundarykm: 17622.0,
                innerboundarykm: 10000.0,
                avgdensitykgm3: 3500.0,
            },
            Self {
                name: "Ionic Ocean".into(),
                outerboundarykm: 10000.0,
                innerboundarykm: 7500.0,
                avgdensitykgm3: 5000.0,
            },
            Self {
                name: "Rock-Iron Core".into(),
                outerboundarykm: 7500.0,
                innerboundarykm: 0.0,
                avgdensitykgm3: 9000.0,
            },
        ]
    }
}

fn interiorlayerdepthkm(lat: f64, lon: f64) -> f64 {
    let base = -7000.0;
    let latmod = 500.0 * (2.0 * lat.to_radians()).cos();
    let lonmod = 200.0 * (3.0 * lon.to_radians()).sin();
    base + latmod + lonmod
}
