///|
/// 34-belt-tensioner-block
///
/// A tensioner block with computed belt path and teeth geometry.
/// Demonstrates complex profile generation with integrated cutouts and teeth.
///
/// Usage (stdout):
///   moon run --target native examples/34-belt-tensioner-block -- > tensioner.step
///
/// Usage (write file):
///   moon run --target native examples/34-belt-tensioner-block -- -o tensioner.step
async fn main {
  let base_args_spec = {
    "length": @cli.opt_double(50.0, help="Block length (mm)"),
    "width": @cli.opt_double(20.0, help="Block width (mm)"),
    "height": @cli.opt_double(15.0, help="Block height (mm)"),
    "beltThickness": @cli.opt_double(1.5, help="Belt thickness (mm)"),
    "toothPitch": @cli.opt_double(2.0, help="Belt tooth pitch (GT2 = 2mm)"),
    "boltDia": @cli.opt_double(4.2, help="Tensioning bolt diameter (mm)"),
  }
  let args_spec = @cli.with_translate(
    @common.with_output_args(base_args_spec, out_help="Write output to a file"),
  )
  guard @cli.parse(args_spec, prog="34-belt-tensioner-block") is Some(args) else {
    return
  }
  let l = args.double("length")
  let w = args.double("width")
  let h = args.double("height")
  let belt_t = args.double("beltThickness")
  let pitch = args.double("toothPitch")
  let bolt_d = args.double("boltDia")
  let output = @common.output_paths(args)
  let (tx, ty, tz) = args.translate_xyz().unwrap_or((0.0, 0.0, 0.0))

  // 1. Side Profile (XZ Plane)
  // We'll extrude this along the Y axis (width)
  let r = 3.0 // corner radius
  let n = 8
  let slot_h = belt_t + 1.0
  let slot_y = h / 2.0 - slot_h / 2.0
  let slot_l = l * 0.7

  // Construct a single CCW loop
  let outer = []

  // Start from the top-right corner of the belt entry
  outer.push((l, slot_y + slot_h))

  // Top-right fillet
  outer.push_iter(
    @cad.Profile2D::arc(2.0 * r, 0.0, 0.5 * @math.PI, segments=n)
    .iter()
    .map(fn(p) { (p.0 + l - r, p.1 + h - r) }),
  )

  // Top-left fillet
  outer.push_iter(
    @cad.Profile2D::arc(2.0 * r, 0.5 * @math.PI, @math.PI, segments=n)
    .iter()
    .map(fn(p) { (p.0 + r, p.1 + h - r) }),
  )

  // Bottom-left fillet
  outer.push_iter(
    @cad.Profile2D::arc(2.0 * r, @math.PI, 1.5 * @math.PI, segments=n)
    .iter()
    .map(fn(p) { (p.0 + r, p.1 + r) }),
  )

  // Bottom-right corner (SHARP)
  outer.push((l, 0.0))

  // Lower part of the belt entry
  outer.push((l, slot_y))

  // Teeth along the bottom of the slot
  let tooth_h = 0.7
  let tooth_w = pitch / 2.0
  let num_teeth = (slot_l / pitch).to_int()
  for i in 0.. 0 {
      outer.push((tx, slot_y))
    }
    outer.push((tx - tooth_w / 2.0, slot_y + tooth_h))
    outer.push((tx - tooth_w, slot_y))
  }

  // End of slot - only push if it's not identical to the last tooth point
  let last_tx = l - Double::from_int(num_teeth - 1) * pitch - tooth_w
  if Double::abs(last_tx - (l - slot_l)) > 0.001 {
    outer.push((l - slot_l, slot_y))
  }
  outer.push((l - slot_l, slot_y + slot_h))
  // Back to start (implied by loop)

  // 2. Bolt Hole (must be fully inside and not intersect the slot)
  let bolt_x = (l - slot_l) / 2.0
  let bolt_hole = @cad.Profile2D::circle(bolt_d).rev()
  let bolt_hole_translated = @cad.translate_pts(bolt_hole, bolt_x, h / 2.0)

  // 3. Create the main solid
  let tensioner = @cad.ExtrudedProfile::new(outer, w, holes=[
      bolt_hole_translated,
    ])
    .with_name("tensioner-block")
    .with_color(@cad.Rgb::new(0.2, 0.6, 0.9)) // Beautiful Sky Blue
    .rotate_x(90.0)
    .translate(x=tx - l / 2.0, y=ty + w / 2.0, z=tz)

  // 4. Design and Labels

  let font = @cad.load_font("baloo")
  let design = @cad.Design::new(
      name="belt-tensioner",
      documentation=args.documentation(),
    )
    .add(tensioner)
    .add_text_on_face(
      tensioner,
      "BELT",
      Top,
      font,
      font_size=4.0,
      offset_y=h / 3.0,
    )
  @common.write_output(design, output)
}