use std::collections::HashMap;

use lib::{BlockPalette, StructureExporter, VoxelType};

pub struct McFunctionExporter {
    palette: HashMap<VoxelType, String>,
}

impl McFunctionExporter {
    pub fn new(palette: &BlockPalette) -> Self {
        let mut map = HashMap::new();
        map.insert(VoxelType::Body, palette.resolve(&VoxelType::Body));
        map.insert(VoxelType::Outline, palette.resolve(&VoxelType::Outline));
        map.insert(VoxelType::Shadow, palette.resolve(&VoxelType::Shadow));
        Self { palette: map }
    }
}

impl StructureExporter for McFunctionExporter {
    fn export(&self, grid: &lib::VoxelGrid) -> anyhow::Result<Vec<u8>> {
        let mut output = String::new();

        output.push_str(&format!("# Generated by Minecraft Text Builder\n"));
        output.push_str(&format!(
            "# Dimensions: {}x{}x{}\n\n",
            grid.width, grid.height, grid.depth
        ));

        for z in 0..grid.depth {
            for y in 0..grid.height {
                for x in 0..grid.width {
                    if let Some(voxel_type) = grid.get(x, y, z) {
                        if let Some(block_id) = self.palette.get(&voxel_type) {
                            // ~x ~y ~z generates blocks relative to where the command is executed
                            let command = format!("setblock ~{} ~{} ~{} {}\n", x, y, z, block_id);
                            output.push_str(&command);
                        }
                    }
                }
            }
        }

        Ok(output.into_bytes())
    }

    fn file_extension(&self) -> &'static str {
        "mcfunction"
    }
}
