///|
fn template_source(label : String) -> DataSource {
  source("template", "MoonBit chemreport engineering template: \{label}")
}

///|
pub fn heat_exchanger_report() -> ChemReport {
  report(
    "Heat Exchanger Duty Summary",
    summary="Sensible-duty report for a single-phase exchanger.",
    inputs=[
      input("mass flow", quantity("2.0", "kg/s")),
      input("heat capacity", quantity("4.18", "kJ/(kg K)")),
      input("temperature rise", quantity("25", "K")),
    ],
    assumptions=[assumption("single phase", "no latent heat is represented")],
    formulas=[
      formula("duty", "Q = m_dot * Cp * DeltaT", ["m_dot", "Cp", "DeltaT"]),
    ],
    results=[
      result("duty", quantity("209.0", "kW"), procedure="2.0 * 4.18 * 25"),
    ],
    sources=[template_source("heat exchanger")],
  )
}

///|
pub fn pump_power_report() -> ChemReport {
  report(
    "Pump Hydraulic Power Summary",
    summary="Hydraulic power before pump efficiency correction.",
    inputs=[
      input("density", quantity("998", "kg/m3")),
      input("flow", quantity("0.01", "m3/s")),
      input("head", quantity("30", "m")),
    ],
    assumptions=[assumption("incompressible liquid", "density is fixed")],
    formulas=[
      formula("hydraulic power", "P = rho * g * Q * H", ["rho", "g", "Q", "H"]),
    ],
    results=[
      result(
        "hydraulic power",
        quantity("2.934", "kW"),
        procedure="998 * 9.81 * 0.01 * 30",
      ),
    ],
    sources=[template_source("pump power")],
  )
}

///|
pub fn flash_split_report() -> ChemReport {
  report(
    "Flash Split Summary",
    summary="Two-phase split record with component-free recovery figures.",
    inputs=[
      input("feed", quantity("100", "kmol/h")),
      input("vapor fraction", quantity("0.35", "1")),
      input("liquid fraction", quantity("0.65", "1")),
    ],
    assumptions=[assumption("single feed", "no side draw is recorded")],
    formulas=[formula("split", "V = beta F; L = (1-beta) F", ["beta", "F"])],
    results=[
      result("vapor flow", quantity("35", "kmol/h"), procedure="0.35 * 100"),
      result("liquid flow", quantity("65", "kmol/h"), procedure="0.65 * 100"),
    ],
    sources=[template_source("flash split")],
  )
}

///|
pub fn stoichiometric_yield_report() -> ChemReport {
  report(
    "Stoichiometric Yield Summary",
    summary="Single-reaction yield record with explicit limiting-feed basis.",
    inputs=[
      input("limiting reactant", quantity("10", "mol")),
      input("theoretical product", quantity("8", "mol")),
      input("actual product", quantity("7.2", "mol")),
    ],
    assumptions=[
      assumption(
        "single reaction", "selectivity losses are represented by yield only",
      ),
    ],
    formulas=[
      formula("yield", "Y = actual / theoretical", ["actual", "theoretical"]),
    ],
    results=[result("yield", quantity("90", "%"), procedure="7.2 / 8 * 100")],
    warnings=[
      caution(
        "selectivity and impurity profile require a reaction-specific report",
      ),
    ],
    sources=[template_source("stoichiometric yield")],
  )
}

///|
pub fn mixing_report() -> ChemReport {
  report(
    "Adiabatic Mixing Temperature",
    summary="A two-stream mixing record with an explicit enthalpy-basis equation.",
    inputs=[
      input("stream one", quantity("10", "kg/s")),
      input("stream one temperature", quantity("300", "K")),
      input("stream two", quantity("5", "kg/s")),
      input("stream two temperature", quantity("360", "K")),
      input("heat capacity", quantity("4.18", "kJ/(kg K)")),
    ],
    assumptions=[
      assumption(
        "adiabatic mixing", "heat loss is excluded from the enthalpy closure",
      ),
    ],
    formulas=[
      formula("mixed temperature", "sum(m Cp T)_in / sum(m Cp)_in", [
        "m", "Cp", "T",
      ]),
    ],
    results=[
      result(
        "mixed temperature",
        quantity("320.0", "K"),
        procedure="(10 * 300 + 5 * 360) / 15",
      ),
    ],
    sources=[template_source("mixing temperature")],
  )
}

///|
pub fn pressure_drop_report() -> ChemReport {
  report(
    "Pipe Pressure-Drop Summary",
    summary="A friction-loss record for a single pipe segment.",
    inputs=[
      input("friction factor", quantity("0.020", "1")),
      input("pipe length", quantity("100", "m")),
      input("pipe diameter", quantity("0.050", "m")),
      input("density", quantity("998", "kg/m3")),
      input("velocity", quantity("2.0", "m/s")),
    ],
    assumptions=[
      assumption("Darcy-Weisbach basis", "minor losses are reported separately"),
    ],
    formulas=[
      formula("friction loss", "DeltaP = f L/D rho v^2/2", [
        "f", "L", "D", "rho", "v",
      ]),
    ],
    results=[
      result(
        "friction pressure drop",
        quantity("39920", "Pa"),
        procedure="0.020 * 100 / 0.050 * 998 * 2^2 / 2",
      ),
    ],
    warnings=[
      caution(
        "include fittings, elevation, and pump margin before equipment selection",
      ),
    ],
    sources=[template_source("pipe pressure drop")],
  )
}

///|
pub fn reaction_rate_report() -> ChemReport {
  report(
    "Reaction-Rate Snapshot",
    summary="A rate-law record that keeps kinetics assumptions beside the calculated rate.",
    inputs=[
      input("rate constant", quantity("0.12", "1/h")),
      input("reactant concentration", quantity("2.0", "kmol/m3")),
      input("reaction order", quantity("1", "1")),
    ],
    assumptions=[
      assumption(
        "power-law kinetics", "the rate law is valid only over the cited operating window",
      ),
    ],
    formulas=[formula("rate law", "r = k C_A^n", ["k", "C_A", "n"])],
    results=[
      result(
        "reaction rate",
        quantity("0.24", "kmol/m3/h"),
        procedure="0.12 * 2.0^1",
      ),
    ],
    warnings=[
      caution(
        "attach fitted-data uncertainty and temperature dependence for production use",
      ),
    ],
    sources=[template_source("reaction rate")],
  )
}

///|
pub fn distillation_stage_report() -> ChemReport {
  report(
    "Distillation Stage Efficiency",
    summary="A single-stage efficiency record with equilibrium composition traceability.",
    inputs=[
      input("inlet vapor composition", quantity("0.40", "mol/mol")),
      input("outlet vapor composition", quantity("0.72", "mol/mol")),
      input("equilibrium composition", quantity("0.80", "mol/mol")),
    ],
    assumptions=[
      assumption(
        "Murphree vapor efficiency", "the reference equilibrium value is evaluated at the stage condition",
      ),
    ],
    formulas=[
      formula("stage efficiency", "E_M = (y_out-y_in)/(y_star-y_in)", [
        "y_out", "y_in", "y_star",
      ]),
    ],
    results=[
      result(
        "Murphree efficiency",
        quantity("80", "%"),
        procedure="(0.72 - 0.40) / (0.80 - 0.40) * 100",
      ),
    ],
    sources=[template_source("distillation stage")],
  )
}

///|
pub fn drying_report() -> ChemReport {
  report(
    "Solid Drying Rate Summary",
    summary="A drying-rate record that distinguishes the measured surface basis.",
    inputs=[
      input("mass-transfer coefficient", quantity("0.004", "kg/m2/h")),
      input("area", quantity("20", "m2")),
      input("driving force", quantity("0.30", "1")),
    ],
    assumptions=[
      assumption(
        "constant-rate region", "the reported driving force is treated as constant",
      ),
    ],
    formulas=[
      formula("drying rate", "N_A = k_y a (Y-Y*)", ["k_y", "a", "Y", "Y*"]),
    ],
    results=[
      result(
        "water removal rate",
        quantity("0.024", "kg/h"),
        procedure="0.004 * 20 * 0.30",
      ),
    ],
    warnings=[
      caution(
        "falling-rate behavior and equilibrium moisture need a dedicated drying model",
      ),
    ],
    sources=[template_source("drying rate")],
  )
}

///|
pub fn filtration_report() -> ChemReport {
  report(
    "Cake Filtration Rate Summary",
    summary="A pressure-driven filtration record with medium and cake resistance terms.",
    inputs=[
      input("pressure difference", quantity("100000", "Pa")),
      input("filter area", quantity("2", "m2")),
      input("viscosity", quantity("0.001", "Pa s")),
      input("total resistance", quantity("100000000", "1/m")),
    ],
    assumptions=[
      assumption(
        "constant pressure", "the pressure difference is held over the reported interval",
      ),
    ],
    formulas=[
      formula("filtration rate", "dV/dt = DeltaP A / (mu R_total)", [
        "DeltaP", "A", "mu", "R_total",
      ]),
    ],
    results=[
      result(
        "filtrate rate",
        quantity("2", "m3/s"),
        procedure="100000 * 2 / (0.001 * 100000000)",
      ),
    ],
    warnings=[
      caution(
        "cake compressibility and solids loading require plant data before scale-up",
      ),
    ],
    sources=[template_source("filtration rate")],
  )
}