pub struct ShaderEndpoint {
    pub name: &'static str,
    pub uniforms: Vec<ShaderUniform>,
}

#[derive(Debug, Clone)]
pub enum UniformValue {
    Float(f32),
    Vec3([f32; 3]),
    Vec4([f32; 4]),
    Int(i32),
}

#[derive(Debug, Clone)]
pub struct ShaderUniform {
    pub name: &'static str,
    pub value: UniformValue,
}

impl ShaderEndpoint {
    pub fn terrain() -> Self {
        Self {
            name: "cloud_top_pbr",
            uniforms: vec![
                ShaderUniform {
                    name: "u_sun_direction",
                    value: UniformValue::Vec3([0.0, 1.0, 0.0]),
                },
                ShaderUniform {
                    name: "u_camera_pos",
                    value: UniformValue::Vec3([0.0, 0.0, 0.0]),
                },
                ShaderUniform {
                    name: "u_planet_radius",
                    value: UniformValue::Float(crate::NEPTUNEEQUATORIALRADIUS as f32),
                },
                ShaderUniform {
                    name: "u_atmosphere_height",
                    value: UniformValue::Float(600_000.0),
                },
            ],
        }
    }

    pub fn atmosphere() -> Self {
        Self {
            name: "neptune_scattering",
            uniforms: vec![
                ShaderUniform {
                    name: "u_rayleigh_coeff",
                    value: UniformValue::Vec3([1.2e-6, 3.5e-6, 8.5e-6]),
                },
                ShaderUniform {
                    name: "u_mie_coeff",
                    value: UniformValue::Float(5e-6),
                },
                ShaderUniform {
                    name: "u_mie_g",
                    value: UniformValue::Float(0.75),
                },
                ShaderUniform {
                    name: "u_sun_intensity",
                    value: UniformValue::Float(0.024),
                },
                ShaderUniform {
                    name: "u_scale_height_rayleigh",
                    value: UniformValue::Float(*crate::SCALEHEIGHT as f32),
                },
                ShaderUniform {
                    name: "u_scale_height_mie",
                    value: UniformValue::Float(15_000.0),
                },
                ShaderUniform {
                    name: "u_methane_absorption",
                    value: UniformValue::Vec3([0.0, 0.001, 0.01]),
                },
            ],
        }
    }

    pub fn interior_ocean() -> Self {
        Self {
            name: "superionic_water",
            uniforms: vec![
                ShaderUniform {
                    name: "u_pressure",
                    value: UniformValue::Float(200.0),
                },
                ShaderUniform {
                    name: "u_temperature",
                    value: UniformValue::Float(2000.0),
                },
                ShaderUniform {
                    name: "u_deep_color",
                    value: UniformValue::Vec3([0.02, 0.05, 0.15]),
                },
                ShaderUniform {
                    name: "u_emissive",
                    value: UniformValue::Vec3([0.01, 0.02, 0.05]),
                },
            ],
        }
    }

    pub fn band_dynamics() -> Self {
        Self {
            name: "neptune_bands",
            uniforms: vec![
                ShaderUniform {
                    name: "u_band_count",
                    value: UniformValue::Int(6),
                },
                ShaderUniform {
                    name: "u_wind_shear",
                    value: UniformValue::Float(0.012),
                },
                ShaderUniform {
                    name: "u_methane_tint",
                    value: UniformValue::Vec3([0.1, 0.3, 0.8]),
                },
            ],
        }
    }
}
