use dear_imgui_rs::{Condition, Context};
use dear_imgui_wgpu::{WgpuInitInfo, WgpuRenderer};
use sdl3_sys::events::SDL_Event;

pub struct FrameStats
{
    pub fps: f32,
    pub frame_ms: f32,
    pub physics_budget_ms: f32,
    pub draw_call_count: usize,
}

pub struct Inspector
{
    imgui: Context,
    renderer: WgpuRenderer,
}

impl Inspector
{
    pub fn new(
        device: &wgpu::Device,
        queue: &wgpu::Queue,
        surface_format: wgpu::TextureFormat,
    ) -> Self
    {
        let mut imgui = Context::create();
        let init_info = WgpuInitInfo::new(device.clone(), queue.clone(), surface_format);
        let renderer =
            WgpuRenderer::new(init_info, &mut imgui).expect("Failed to create imgui wgpu renderer");
        Self { imgui, renderer }
    }

    pub fn init_platform(&mut self, window: &sdl3::video::Window)
    {
        dear_imgui_sdl3::init_for_other(&mut self.imgui, window)
            .expect("Failed to init imgui sdl3 platform");
    }

    pub fn begin_frame(&mut self)
    {
        dear_imgui_sdl3::sdl3_new_frame(&mut self.imgui);
    }

    pub fn process_event(&mut self, raw_event: &SDL_Event)
    {
        dear_imgui_sdl3::process_sys_event(raw_event);
    }

    pub fn wants_keyboard(&self) -> bool
    {
        self.imgui.io().want_capture_keyboard()
    }

    pub fn wants_mouse(&self) -> bool
    {
        self.imgui.io().want_capture_mouse()
    }

    pub fn build_ui(&mut self, stats: &FrameStats)
    {
        let ui = self.imgui.frame();
        ui.window("Inspector")
            .position([10.0, 10.0], Condition::FirstUseEver)
            .build(|| {
                ui.text(format!("FPS:        {:.1}", stats.fps));
                ui.text(format!("Frame:      {:.1} ms", stats.frame_ms));
                ui.text(format!("Physics:    {:.1} ms", stats.physics_budget_ms));
                ui.text(format!("Draw calls: {}", stats.draw_call_count));
            });
    }

    pub fn render(&mut self, encoder: &mut wgpu::CommandEncoder, view: &wgpu::TextureView)
    {
        let draw_data = self.imgui.render();

        let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
            label: Some("ImGui Render Pass"),
            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                view,
                resolve_target: None,
                ops: wgpu::Operations {
                    load: wgpu::LoadOp::Load,
                    store: wgpu::StoreOp::Store,
                },
                depth_slice: None,
            })],
            depth_stencil_attachment: None,
            occlusion_query_set: None,
            timestamp_writes: None,
            multiview_mask: None,
        });

        self.renderer
            .render_draw_data(draw_data, &mut render_pass)
            .expect("Failed to render imgui");
    }
}
