///|
/// 30-desk-cable-tray
///
/// A parametric under-desk cable management tray.
/// Demonstrates profile construction with holes, assembly of multiple parts,
/// and precise text positioning on faces.
///
/// Usage (stdout):
///   moon run --target native examples/30-desk-cable-tray -- --length 200 > tray.step
async fn main {
  let base_args_spec = {
    "length": @cli.opt_double(
      200.0,
      help="Total length of the tray (mm)",
      min=50.0,
    ),
    "width": @cli.opt_double(
      60.0,
      help="Width/depth of the tray (mm)",
      min=20.0,
    ),
    "height": @cli.opt_double(
      50.0,
      help="Total height of the tray (mm)",
      min=20.0,
    ),
    "thickness": @cli.opt_double(3.0, help="Material thickness (mm)", min=1.0),
    "mountHoleSpacing": @cli.opt_double(
      120.0,
      help="Spacing between mounting holes (mm)",
      min=20.0,
    ),
    "mountHoleDia": @cli.opt_double(
      5.0,
      help="Diameter of mounting holes (mm)",
      min=1.0,
    ),
  }
  let args_spec = @cli.with_translate(@common.with_output_args(base_args_spec))
  guard @cli.parse(
      args_spec,
      prog="30-desk-cable-tray",
      description="Generate a parametric under-desk cable management tray.",
    )
    is Some(args) else {
    return
  }
  let length = args.double("length")
  let width = args.double("width")
  let height = args.double("height")
  let thick = args.double("thickness")
  let m_spacing = args.double("mountHoleSpacing")
  let m_dia = args.double("mountHoleDia")
  let output = @common.output_paths(args)
  let (tx, ty, tz) = match args.translate_xyz() {
    Some(v) => v
    None => {
      @cli.eprintln("error: invalid translation")
      return
    }
  }

  // 1. Back wall (mounting face)
  // Original XY plane (length x height), extruded by 'thick' in Z.
  // After rotate_x(90): x: 0..length, y: -thick..0, z: 0..height.
  let back_wall_outer = @cad.Profile2D::rect(length, height)
  let m_hole = @cad.Profile2D::circle(m_dia).rev()
  let back_wall_profile = @cad.Profile2D::new(back_wall_outer).add_holes_at(
    [
      (length / 2.0 - m_spacing / 2.0, height / 2.0),
      (length / 2.0 + m_spacing / 2.0, height / 2.0),
    ],
    m_hole,
  )
  let back_wall = @cad.ExtrudedProfile::new(
      back_wall_profile.outer,
      thick,
      holes=back_wall_profile.holes,
    )
    .with_name("back-wall")
    .with_color(@cad.Rgb::new(0.2, 0.3, 0.6))
    .rotate_x(90.0)
    .translate(x=-length / 2.0, y=0.0, z=0.0)

  // 2. Bottom plate
  // Fills the gap between back-wall (y=-thick) and front-lip (y=-width+thick).
  let bottom = @cad.Cuboid::new(length, width - 2.0 * thick, thick)
    .with_name("bottom-plate")
    .with_color(@cad.Rgb::new(0.3, 0.4, 0.7))
    .translate(x=-length / 2.0, y=-width + thick, z=0.0)

  // 3. Front lip
  // Positioned at the very front (min_y).
  let front_lip = @cad.Cuboid::new(length, thick, height * 0.4)
    .with_name("front-lip")
    .with_color(@cad.Rgb::new(0.4, 0.5, 0.8))
    .translate(x=-length / 2.0, y=-width, z=0.0)

  // 4. Labels
  let font = @cad.load_font("baloo")
  let design = @cad.Design::new(
      name="desk-cable-tray",
      documentation=args.documentation(),
    )
    .add(back_wall)
    .add(bottom)
    .add(front_lip)
    .add_text_on_face(
      front_lip,
      "CABLE TRAY",
      Back, // Outside face (min_y)
      font,
      font_size=height * 0.15,
      color=@cad.Rgb::white(),
    )
    .add_text_on_face(
      back_wall,
      "MOUNTING SIDE",
      Top, // Inside face (local +Z, world -Y)
      font,
      font_size=height * 0.1,
      color=@cad.Rgb::white(),
    )
    .translate(x=tx, y=ty, z=tz)
  @common.write_output(design, output)
}