// moonbit-4d-schedule - CLI Entrypoint & Demonstration Solver

///|
pub fn create_sample_building_project() -> @types.ScheduleProject {
  let cal = @types.WorkCalendar::default_standard()

  let elements : Array[@types.BimElement] = [
    {
      guid: "GUID_FND_01",
      name: "Raft Foundation F1",
      category: Foundation,
      level: "B1",
      zone: "Zone A",
      bounds: {
        min_point: { x: 0.0, y: 0.0, z: -3.0 },
        max_point: { x: 20.0, y: 30.0, z: 0.0 },
      },
      volume: 1800.0,
    },
    {
      guid: "GUID_COL_B1_01",
      name: "Column Group C_B1",
      category: Column,
      level: "B1",
      zone: "Zone A",
      bounds: {
        min_point: { x: 0.0, y: 0.0, z: 0.0 },
        max_point: { x: 20.0, y: 30.0, z: 3.5 },
      },
      volume: 120.0,
    },
    {
      guid: "GUID_SLAB_L1_01",
      name: "Floor Slab S_L1",
      category: Slab,
      level: "L1",
      zone: "Zone A",
      bounds: {
        min_point: { x: 0.0, y: 0.0, z: 3.5 },
        max_point: { x: 20.0, y: 30.0, z: 3.8 },
      },
      volume: 180.0,
    },
    {
      guid: "GUID_COL_L1_01",
      name: "Column Group C_L1",
      category: Column,
      level: "L1",
      zone: "Zone A",
      bounds: {
        min_point: { x: 0.0, y: 0.0, z: 3.8 },
        max_point: { x: 20.0, y: 30.0, z: 7.3 },
      },
      volume: 120.0,
    },
    {
      guid: "GUID_SLAB_L2_01",
      name: "Roof Slab S_L2",
      category: Roof,
      level: "L2",
      zone: "Zone A",
      bounds: {
        min_point: { x: 0.0, y: 0.0, z: 7.3 },
        max_point: { x: 20.0, y: 30.0, z: 7.6 },
      },
      volume: 180.0,
    },
    {
      guid: "GUID_MEP_01",
      name: "HVAC & Electrical Riser",
      category: MEP,
      level: "L1-L2",
      zone: "Core",
      bounds: {
        min_point: { x: 8.0, y: 12.0, z: 0.0 },
        max_point: { x: 12.0, y: 18.0, z: 7.6 },
      },
      volume: 45.0,
    },
  ]

  let activities : Array[@types.Activity] = [
    {
      id: "ACT_01",
      code: "100",
      name: "Site Preparation & Excavation",
      duration: 10.0,
      optimistic_duration: 8.0,
      pessimistic_duration: 14.0,
      calendar_id: cal.id,
      constraint: { constraint_type: AsSoonAsPossible, target_date: None },
      predecessors: [],
      element_ids: ["GUID_FND_01"],
    },
    {
      id: "ACT_02",
      code: "110",
      name: "Cast Raft Foundation",
      duration: 12.0,
      optimistic_duration: 9.0,
      pessimistic_duration: 18.0,
      calendar_id: cal.id,
      constraint: { constraint_type: AsSoonAsPossible, target_date: None },
      predecessors: [{ activity_id: "ACT_01", dep_type: FS, lag_days: 0.0 }],
      element_ids: ["GUID_FND_01"],
    },
    {
      id: "ACT_03",
      code: "200",
      name: "Erect B1 Columns & Shearing Walls",
      duration: 15.0,
      optimistic_duration: 12.0,
      pessimistic_duration: 21.0,
      calendar_id: cal.id,
      constraint: { constraint_type: AsSoonAsPossible, target_date: None },
      predecessors: [{ activity_id: "ACT_02", dep_type: FS, lag_days: 0.0 }],
      element_ids: ["GUID_COL_B1_01"],
    },
    {
      id: "ACT_04",
      code: "210",
      name: "Pour L1 Floor Slab",
      duration: 10.0,
      optimistic_duration: 8.0,
      pessimistic_duration: 14.0,
      calendar_id: cal.id,
      constraint: { constraint_type: AsSoonAsPossible, target_date: None },
      predecessors: [{ activity_id: "ACT_03", dep_type: FS, lag_days: 0.0 }],
      element_ids: ["GUID_SLAB_L1_01"],
    },
    {
      id: "ACT_05",
      code: "300",
      name: "Erect L1 Columns",
      duration: 14.0,
      optimistic_duration: 10.0,
      pessimistic_duration: 20.0,
      calendar_id: cal.id,
      constraint: { constraint_type: AsSoonAsPossible, target_date: None },
      predecessors: [{ activity_id: "ACT_04", dep_type: FS, lag_days: 0.0 }],
      element_ids: ["GUID_COL_L1_01"],
    },
    {
      id: "ACT_06",
      code: "310",
      name: "Pour L2 Roof Slab",
      duration: 10.0,
      optimistic_duration: 7.0,
      pessimistic_duration: 15.0,
      calendar_id: cal.id,
      constraint: { constraint_type: AsSoonAsPossible, target_date: None },
      predecessors: [{ activity_id: "ACT_05", dep_type: FS, lag_days: 0.0 }],
      element_ids: ["GUID_SLAB_L2_01"],
    },
    {
      id: "ACT_07",
      code: "400",
      name: "MEP Rough-in & Ducting",
      duration: 18.0,
      optimistic_duration: 14.0,
      pessimistic_duration: 26.0,
      calendar_id: cal.id,
      constraint: { constraint_type: AsSoonAsPossible, target_date: None },
      predecessors: [{ activity_id: "ACT_04", dep_type: SS, lag_days: 5.0 }],
      element_ids: ["GUID_MEP_01"],
    },
  ]

  let resources : Array[@types.Resource] = [
    {
      id: "RES_LABOR",
      code: "LAB-01",
      name: "Steel Fixers & Carpenters",
      kind: Labor,
      unit: "Man-days",
      max_capacity: 25.0,
      cost_per_unit: 350.0,
    },
    {
      id: "RES_CRANE",
      code: "EQP-01",
      name: "Tower Crane 50t",
      kind: Equipment,
      unit: "Hours",
      max_capacity: 10.0,
      cost_per_unit: 1200.0,
    },
  ]

  let demands : Array[@types.ResourceDemand] = [
    { activity_id: "ACT_01", resource_id: "RES_CRANE", units_per_day: 8.0 },
    { activity_id: "ACT_02", resource_id: "RES_LABOR", units_per_day: 20.0 },
    { activity_id: "ACT_03", resource_id: "RES_LABOR", units_per_day: 18.0 },
    { activity_id: "ACT_03", resource_id: "RES_CRANE", units_per_day: 6.0 },
    { activity_id: "ACT_04", resource_id: "RES_LABOR", units_per_day: 15.0 },
    { activity_id: "ACT_05", resource_id: "RES_LABOR", units_per_day: 18.0 },
    { activity_id: "ACT_06", resource_id: "RES_LABOR", units_per_day: 15.0 },
    { activity_id: "ACT_07", resource_id: "RES_LABOR", units_per_day: 10.0 },
  ]

  {
    id: "PROJ_4D_DEMO",
    name: "4D BIM Commercial Building Schedule",
    start_date: { year: 2026, month: 9, day: 1 },
    calendars: [cal],
    activities,
    elements,
    resources,
    demands,
  }
}

///|
pub fn run_cli_demo() -> Unit {
  let proj = create_sample_building_project()
  println("=================================================================")
  println("  moonbit-4d-schedule Engine - Smart Construction 4D BIM Solver")
  println("=================================================================")
  println("Project: " + proj.name + " (" + proj.id + ")")
  println("Start Date: " + proj.start_date.to_iso_string())
  println("Activities: " + proj.activities.length().to_string())
  println("BIM Elements: " + proj.elements.length().to_string())
  println("")

  let graph = match @graph.NetworkGraph::build(proj.activities) {
    Ok(g) => g
    Err(_) => return ()
  }
  let cpm = match @graph.solve_cpm(graph) {
    Ok(c) => c
    Err(_) => return ()
  }

  println("[CPM Schedule Analysis]")
  println(
    "Total Project Duration: " + cpm.project_duration.to_string() + " Days",
  )
  println("Critical Path Count: " + cpm.critical_path.length().to_string())
  for act_id in proj.activities {
    let fl = cpm.floats.get(act_id.id).unwrap()
    let crit_tag = if fl.is_critical { " [CRITICAL]" } else { "" }
    println(
      "  Activity " +
      act_id.code +
      ": " +
      act_id.name +
      " -> ES=" +
      fl.early_start.to_string() +
      " EF=" +
      fl.early_finish.to_string() +
      " TF=" +
      fl.total_float.to_string() +
      crit_tag,
    )
  }
  println("")

  println("[PERT 3-Estimate Probabilistic Analysis]")
  let pert_res = match @pert.analyze_pert(proj.activities) {
    Ok(p) => p
    Err(_) => return ()
  }
  println(
    "Expected Project Duration: " +
    pert_res.expected_project_duration.to_string() +
    " Days",
  )
  println(
    "Total Variance (Critical Path): " + pert_res.total_variance.to_string(),
  )
  println("Standard Deviation: " + pert_res.total_std_dev.to_string() + " Days")

  let target_d = pert_res.expected_project_duration + 5.0
  let prob = @pert.calculate_completion_probability(pert_res, target_d)
  println(
    "Completion Probability by Day " +
    target_d.to_string() +
    ": " +
    (prob * 100.0).to_int().to_string() +
    "%",
  )
  println("")

  println("[Burgess-Killebrew Resource Leveling]")
  let lev = @leveling.level_resource_burgess(
    "RES_LABOR",
    proj.activities,
    proj.demands,
    cpm,
  )
  println("Resource: Steel Fixers & Carpenters (RES_LABOR)")
  println(
    "Peak Demand (Before Leveling): " +
    lev.initial_profile.max_demand.to_string(),
  )
  println(
    "Peak Demand (After Leveling):  " +
    lev.leveled_profile.max_demand.to_string(),
  )
  println(
    "Sum of Demand Squares Reduction: " +
    (lev.sum_squares_reduction * 100.0).to_int().to_string() +
    "%",
  )
  println("")

  println("[4D BIM State Snapshot at Day 25]")
  let snap = @bim4d.generate_4d_snapshot(proj, cpm, 25.0)
  println("Timestamp: Day 25")
  println(
    "Overall Completion: " +
    (snap.overall_completion * 100.0).to_int().to_string() +
    "%",
  )
  println(
    "Active BIM Elements in Progress: " + snap.active_activity_count.to_string(),
  )

  for elem_st in snap.elements {
    println(
      "  Element " +
      elem_st.guid +
      ": Status=" +
      elem_st.status.to_color() +
      " (" +
      (elem_st.completion_ratio * 100.0).to_int().to_string() +
      "%)",
    )
  }

  println("")
  println("[JSON Serialized Snapshot Payload Sample]")
  let json_payload = @json.serialize_state_snapshot(snap)
  println(json_payload)
  println("=================================================================")
}

///|
fn main {
  run_cli_demo()
}