use super::{ComponentInspector, EditorContext};
use nightshade::prelude::*;

pub struct LightInspector;

impl ComponentInspector for LightInspector {
    fn name(&self) -> &str {
        "Light"
    }

    fn has_component(&self, world: &World, entity: Entity) -> bool {
        world.entity_has_light(entity)
    }

    fn add_component(&self, world: &mut World, entity: Entity) {
        world.set_light(entity, Light::default());
    }

    fn remove_component(&self, world: &mut World, entity: Entity) {
        world.remove_light(entity);
    }

    fn ui(
        &mut self,
        world: &mut World,
        entity: Entity,
        ui: &mut egui::Ui,
        _editor: &mut EditorContext,
    ) {
        if let Some(light) = world.get_light_mut(entity) {
            ui.horizontal(|ui| {
                ui.label("Type:");
                egui::ComboBox::from_id_salt("light_type")
                    .selected_text(match light.light_type {
                        LightType::Directional => "Directional",
                        LightType::Point => "Point",
                        LightType::Spot => "Spot",
                    })
                    .show_ui(ui, |ui| {
                        ui.selectable_value(
                            &mut light.light_type,
                            LightType::Directional,
                            "Directional",
                        );
                        ui.selectable_value(&mut light.light_type, LightType::Point, "Point");
                        ui.selectable_value(&mut light.light_type, LightType::Spot, "Spot");
                    });
            });

            ui.separator();

            ui.horizontal(|ui| {
                ui.label("Color:");
                let mut color = [light.color.x, light.color.y, light.color.z];
                if ui.color_edit_button_rgb(&mut color).changed() {
                    light.color.x = color[0];
                    light.color.y = color[1];
                    light.color.z = color[2];
                }
            });

            ui.horizontal(|ui| {
                ui.label("Intensity:");
                ui.add(egui::Slider::new(&mut light.intensity, 0.0..=10.0));
            });

            ui.separator();

            ui.horizontal(|ui| {
                ui.label("Cast Shadows:");
                ui.checkbox(&mut light.cast_shadows, "");
            });

            if light.cast_shadows {
                ui.horizontal(|ui| {
                    ui.label("Shadow Bias:");
                    ui.add(egui::Slider::new(&mut light.shadow_bias, 0.0..=0.01).step_by(0.0001));
                });
            }

            ui.separator();

            match light.light_type {
                LightType::Directional => {
                    ui.label("Directional Light");
                    ui.label("Use entity rotation to control direction");
                }
                LightType::Point => {
                    ui.horizontal(|ui| {
                        ui.label("Range:");
                        ui.add(egui::Slider::new(&mut light.range, 0.1..=100.0));
                    });
                }
                LightType::Spot => {
                    ui.label("Spot Light");
                    ui.label("Use entity rotation to control direction");
                    ui.separator();

                    ui.horizontal(|ui| {
                        ui.label("Range:");
                        ui.add(egui::Slider::new(&mut light.range, 0.1..=100.0));
                    });

                    ui.horizontal(|ui| {
                        ui.label("Inner Cone:");
                        let mut inner_degrees = light.inner_cone_angle.to_degrees();
                        if ui
                            .add(egui::Slider::new(&mut inner_degrees, 0.0..=90.0).suffix("°"))
                            .changed()
                        {
                            light.inner_cone_angle = inner_degrees.to_radians();
                        }
                    });

                    ui.horizontal(|ui| {
                        ui.label("Outer Cone:");
                        let mut outer_degrees = light.outer_cone_angle.to_degrees();
                        if ui
                            .add(egui::Slider::new(&mut outer_degrees, 0.0..=90.0).suffix("°"))
                            .changed()
                        {
                            light.outer_cone_angle = outer_degrees.to_radians();
                        }
                    });
                }
            }
        }
    }
}
