use crate::render::wgpu::rendergraph::{PassExecutionContext, PassNode};

#[derive(Default)]
pub struct ClearPass;

impl ClearPass {
    pub fn new() -> Self {
        Self
    }
}

impl PassNode<crate::ecs::world::World> for ClearPass {
    fn name(&self) -> &str {
        "clear_pass"
    }

    fn reads(&self) -> Vec<&str> {
        vec![]
    }

    fn writes(&self) -> Vec<&str> {
        vec!["color", "depth"]
    }

    fn reads_writes(&self) -> Vec<&str> {
        vec![]
    }

    fn prepare(
        &mut self,
        _device: &wgpu::Device,
        _queue: &wgpu::Queue,
        _world: &crate::ecs::world::World,
    ) {
    }

    fn execute<'r, 'e>(
        &mut self,
        context: PassExecutionContext<'r, 'e, crate::ecs::world::World>,
    ) -> crate::render::wgpu::rendergraph::Result<
        Vec<crate::render::wgpu::rendergraph::SubGraphRunCommand<'r>>,
    > {
        let (color_view, _color_load, color_store) = context.get_color_attachment("color")?;
        let (depth_view, depth_load, depth_store) = context.get_depth_attachment("depth")?;

        let clear_color = if let Some(ref fog) = context.configs.resources.graphics.fog {
            wgpu::Color {
                r: fog.color[0] as f64,
                g: fog.color[1] as f64,
                b: fog.color[2] as f64,
                a: 1.0,
            }
        } else {
            let cc = context.configs.resources.graphics.clear_color;
            wgpu::Color {
                r: cc[0] as f64,
                g: cc[1] as f64,
                b: cc[2] as f64,
                a: cc[3] as f64,
            }
        };

        let render_pass = context
            .encoder
            .begin_render_pass(&wgpu::RenderPassDescriptor {
                label: Some("Clear Pass"),
                color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                    view: color_view,
                    resolve_target: None,
                    ops: wgpu::Operations {
                        load: wgpu::LoadOp::Clear(clear_color),
                        store: color_store,
                    },
                    depth_slice: None,
                })],
                depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
                    view: depth_view,
                    depth_ops: Some(wgpu::Operations {
                        load: depth_load,
                        store: depth_store,
                    }),
                    stencil_ops: None,
                }),
                timestamp_writes: None,
                occlusion_query_set: None,
            });

        drop(render_pass);

        Ok(context.into_sub_graph_commands())
    }
}
