use crate::utils::sampling::AliasTableHost;
use shared::core::light::{Light, LightTrait};
use shared::spectra::{SampledSpectrum, SampledWavelengths};
use std::collections::HashMap;
use std::sync::Arc;

pub struct PowerSamplerHost {
    pub lights: Vec<Arc<Light>>,
    pub light_to_index: HashMap<usize, usize>,
    pub alias_table: AliasTableHost,
}

impl PowerSamplerHost {
    pub fn new(lights: &[Arc<Light>]) -> Self {
        if lights.is_empty() {
            return Self {
                lights: Vec::new(),
                light_to_index: HashMap::new(),
                alias_table: AliasTableHost::new(&[]),
            };
        }

        let mut lights_vec = Vec::with_capacity(lights.len());
        let mut light_to_index = HashMap::with_capacity(lights.len());
        let mut light_power = Vec::with_capacity(lights.len());

        let lambda = SampledWavelengths::sample_visible(0.5);

        for (i, light) in lights.iter().enumerate() {
            lights_vec.push(light.clone());

            let ptr = Arc::as_ptr(light) as usize;
            light_to_index.insert(ptr, i);

            let phi = SampledSpectrum::safe_div(&light.phi(lambda), &lambda.pdf());
            light_power.push(phi.average());
        }

        let alias_table = AliasTableHost::new(&light_power);

        Self {
            lights: lights_vec,
            light_to_index,
            alias_table,
        }
    }
}
