<?php
/**
 * Balance Laboratory Work Form
 * Read-only fields are pulled from $request (companies/equipment/requests tables).
 * Editable fields are balance-specific and stored in balance_lab_forms.
 */
$pageTitle = 'Balance Lab Form — ' . e($request['request_number']);
include __DIR__ . '/../../shared/header.php';

// Alias for cleaner access to saved form data
$f   = $form ?? [];
$s   = fn($k, $def='') => htmlspecialchars((string)($f[$k] ?? $def), ENT_QUOTES, 'UTF-8');
$sel = fn($k, $val)    => ($f[$k] ?? '') === $val ? 'selected' : '';
?>

<div class="page-header">
  <div>
    <div class="page-title"><i class="bi bi-calculator me-2"></i>Balance Laboratory — Calibration Datasheet</div>
    <div class="page-subtitle">
      <code><?= e($request['request_number']) ?></code> &mdash;
      <?= e($request['lab_name']) ?>
      <?php if (!empty($f['form_status'])): ?>
        <span class="badge badge-<?= $f['form_status'] ?> ms-2"><?= ucfirst($f['form_status']) ?></span>
      <?php endif; ?>
    </div>
  </div>
  <a href="<?= APP_URL ?>/index.php?page=requests&action=view&id=<?= $request['request_id'] ?>" class="btn btn-outline-secondary">
    <i class="bi bi-arrow-left me-1"></i>Back to Request
  </a>
</div>

<!-- ── Read-only summary bar (from existing DB tables) ───── -->
<div class="card mb-3 border-0 bg-light">
  <div class="card-body py-2">
    <div class="row g-2 small">
      <div class="col-md-2"><span class="text-muted d-block" style="font-size:10px;">ORDER / LAB NO.</span><strong><?= e($request['request_number']) ?></strong></div>
      <div class="col-md-3"><span class="text-muted d-block" style="font-size:10px;">ITEM CALIBRATED</span><strong><?= e($request['equipment_name']) ?></strong></div>
      <div class="col-md-2"><span class="text-muted d-block" style="font-size:10px;">MANUFACTURER</span><?= e($request['manufacturer']) ?></div>
      <div class="col-md-2"><span class="text-muted d-block" style="font-size:10px;">TYPE / MODEL</span><?= e($request['model']) ?></div>
      <div class="col-md-2"><span class="text-muted d-block" style="font-size:10px;">SERIAL NO.</span><code><?= e($request['serial_number']) ?></code></div>
      <div class="col-md-1"><span class="text-muted d-block" style="font-size:10px;">CUSTOMER</span><?= e($request['company_name']) ?></div>
    </div>
  </div>
</div>

<div class="card">
  <div class="card-header p-0 border-bottom-0">
    <ul class="nav nav-tabs px-3 pt-2" id="balanceTabs" role="tablist">
      <li class="nav-item"><a class="nav-link active" data-bs-toggle="tab" href="#tab-admin-a">Administrative Data (A)</a></li>
      <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#tab-admin-b">Administrative Data (B)</a></li>
      <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#tab-error">Test of Error Indicator</a></li>
      <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#tab-repeat">Repeatability Test</a></li>
      <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#tab-ecc">Eccentricity Test</a></li>
    </ul>
  </div>

  <div class="card-body">
    <form method="POST" id="balance-form">
      <input type="hidden" name="csrf_token" value="<?= csrfToken() ?>">

      <div class="tab-content">

        <!-- ════════════════════════════════════════════════════
             TAB A — Administrative Data (A)
             Fields from existing tables shown read-only.
             Only balance-specific fields are editable.
        ════════════════════════════════════════════════════ -->
        <div class="tab-pane fade show active" id="tab-admin-a">
          <div class="row g-3 mt-1">

            <div class="col-md-3">
              <label class="form-label">Certificate No. <span class="text-danger">*</span></label>
              <input type="text" class="form-control" name="certification_number"
                     value="<?= $s('certification_number') ?>" required
                     placeholder="e.g. GSA/MRQL/2025/001">
            </div>

            <!-- READ-ONLY: from requests table -->
            <div class="col-md-3">
              <label class="form-label">Laboratory / Order No. <span class="badge bg-secondary" style="font-size:9px;">auto</span></label>
              <input type="text" class="form-control bg-light" value="<?= e($request['request_number']) ?>" readonly>
            </div>

            <div class="col-md-3">
              <label class="form-label">Accreditation</label>
              <select class="form-select" name="accreditation">
                <option value="">-- Select --</option>
                <option value="Dakks" <?= $sel('accreditation','Dakks') ?>>DAkkS</option>
                <option value="GSA"   <?= $sel('accreditation','GSA')   ?>>GSA</option>
              </select>
            </div>

            <div class="col-md-3">
              <label class="form-label">Calibration Date <span class="text-danger">*</span></label>
              <input type="date" class="form-control" name="calibration_date"
                     value="<?= $s('calibration_date', date('Y-m-d')) ?>" required>
            </div>

            <!-- READ-ONLY: from equipment table -->
            <div class="col-md-6">
              <label class="form-label">Item Calibrated <span class="badge bg-secondary" style="font-size:9px;">from equipment</span></label>
              <textarea class="form-control bg-light" rows="2" readonly><?= e($request['equipment_name']) ?></textarea>
            </div>

            <!-- READ-ONLY: from companies table -->
            <div class="col-md-6">
              <label class="form-label">Customer Details <span class="badge bg-secondary" style="font-size:9px;">from company</span></label>
              <textarea class="form-control bg-light" rows="2" readonly><?= e($request['company_name']) ?></textarea>
            </div>

            <!-- READ-ONLY: from equipment table -->
            <div class="col-md-4">
              <label class="form-label">Serial Number <span class="badge bg-secondary" style="font-size:9px;">from equipment</span></label>
              <input type="text" class="form-control bg-light" value="<?= e($request['serial_number']) ?>" readonly>
            </div>

            <div class="col-md-4">
              <label class="form-label">Max. Capacity <span class="text-danger">*</span></label>
              <input type="text" class="form-control" name="max_capacity"
                     value="<?= $s('max_capacity') ?>" required placeholder="e.g. 500">
            </div>

            <div class="col-md-4">
              <label class="form-label">Unit (Max Capacity)</label>
              <select class="form-select" name="unit" id="unit" required>
                <option value="">-- Select --</option>
                <option value="mg" <?= $sel('unit','mg') ?>>mg</option>
                <option value="g"  <?= $sel('unit','g')  ?>>g</option>
                <option value="kg" <?= $sel('unit','kg') ?>>kg</option>
              </select>
            </div>

            <!-- READ-ONLY: model from equipment -->
            <div class="col-md-4">
              <label class="form-label">Type / Model <span class="badge bg-secondary" style="font-size:9px;">from equipment</span></label>
              <input type="text" class="form-control bg-light" value="<?= e($request['model']) ?>" readonly>
            </div>

            <div class="col-md-4">
              <label class="form-label">Min. Capacity <span class="text-danger">*</span></label>
              <input type="text" class="form-control" name="min_capacity"
                     value="<?= $s('min_capacity') ?>" required placeholder="e.g. 20">
            </div>

            <div class="col-md-4">
              <label class="form-label">Unit (Min Capacity)</label>
              <select class="form-select" name="unitsec" id="unitsec" required>
                <option value="">-- Select --</option>
                <option value="mg" <?= $sel('unitsec','mg') ?>>mg</option>
                <option value="g"  <?= $sel('unitsec','g')  ?>>g</option>
                <option value="kg" <?= $sel('unitsec','kg') ?>>kg</option>
              </select>
            </div>

            <!-- READ-ONLY: manufacturer from equipment -->
            <div class="col-md-6">
              <label class="form-label">Manufacturer <span class="badge bg-secondary" style="font-size:9px;">from equipment</span></label>
              <textarea class="form-control bg-light" rows="2" readonly><?= e($request['manufacturer']) ?></textarea>
            </div>

            <div class="col-md-6">
              <label class="form-label">Test Method</label>
              <textarea class="form-control" name="test_method" rows="2"><?= $s('test_method','As outlined in the guidelines on the calibration of Non-Automatic Weighing Instruments (EURAMET/cg-18)') ?></textarea>
            </div>

            <div class="col-md-4">
              <label class="form-label">Place of Test <span class="text-danger">*</span></label>
              <input type="text" class="form-control" name="place_of_test"
                     value="<?= $s('place_of_test') ?>" required placeholder="e.g. GSA Mass Laboratory">
            </div>

            <div class="col-md-4">
              <label class="form-label">High Air Circulation</label>
              <select class="form-select" name="high_air_circulation">
                <option value="">-- Select --</option>
                <option value="Yes" <?= $sel('high_air_circulation','Yes') ?>>Yes</option>
                <option value="No"  <?= $sel('high_air_circulation','No')  ?>>No</option>
              </select>
            </div>

            <div class="col-md-4">
              <label class="form-label">High Vibration</label>
              <select class="form-select" name="high_vibration">
                <option value="">-- Select --</option>
                <option value="Yes" <?= $sel('high_vibration','Yes') ?>>Yes</option>
                <option value="No"  <?= $sel('high_vibration','No')  ?>>No</option>
              </select>
            </div>

            <div class="col-12">
              <label class="form-label fw-semibold">Temperature during Calibration</label>
            </div>
            <div class="col-md-3">
              <label class="form-label">Start (°C)</label>
              <input type="text" class="form-control" name="temp_during_cal_start"
                     value="<?= $s('temp_during_cal_start') ?>" placeholder="e.g. 22.3">
            </div>
            <div class="col-md-3">
              <label class="form-label">End (°C)</label>
              <input type="text" class="form-control" name="temp_during_cal_end"
                     value="<?= $s('temp_during_cal_end') ?>" placeholder="e.g. 23.1">
            </div>
          </div>
        </div>

        <!-- ════════════════════════════════════════════════════
             TAB B — Administrative Data (B)
        ════════════════════════════════════════════════════ -->
        <div class="tab-pane fade" id="tab-admin-b">
          <div class="row g-3 mt-1">
            <div class="col-12">
              <label class="form-label fw-semibold">Deviation before Adjustment</label>
            </div>
            <div class="col-md-3">
              <label class="form-label">Applied Load (L)</label>
              <input type="text" class="form-control" name="applied_load" value="<?= $s('applied_load') ?>">
            </div>
            <div class="col-md-3">
              <label class="form-label">Deviation</label>
              <input type="text" class="form-control" name="deviation" value="<?= $s('deviation') ?>">
            </div>
            <div class="col-md-4">
              <label class="form-label">Preloading Executed (0.8 Max ≤ L ≤ Max)</label>
              <select class="form-select" name="preloading_executed">
                <option value="">-- Select --</option>
                <option value="Yes" <?= $sel('preloading_executed','Yes') ?>>Yes</option>
                <option value="No"  <?= $sel('preloading_executed','No')  ?>>No</option>
              </select>
            </div>
            <div class="col-md-4">
              <label class="form-label">Balance Adjusted</label>
              <select class="form-select" name="balance_adjusted" id="balance_adjusted">
                <option value="">-- Select --</option>
                <option value="Yes" <?= $sel('balance_adjusted','Yes') ?>>Yes</option>
                <option value="No"  <?= $sel('balance_adjusted','No')  ?>>No</option>
              </select>
            </div>
            <div class="col-md-4">
              <label class="form-label">Change in Temperature (°C)</label>
              <select class="form-select" name="chng_temp" id="chng_temp">
                <option value="">-- Select --</option>
                <?php foreach ([0,1,2,3,5,7,10,15,20,25] as $v): ?>
                  <option value="<?= $v ?>" <?= $sel('chng_temp',(string)$v) ?>><?= $v ?></option>
                <?php endforeach; ?>
              </select>
            </div>
            <div class="col-md-4">
              <label class="form-label">Accuracy Class of Weight</label>
              <select class="form-select" name="accuracy_class_of_weight" id="accuracy_class_of_weight">
                <option value="">-- Select --</option>
                <option value="E2" <?= $sel('accuracy_class_of_weight','E2') ?>>E2</option>
                <option value="F1" <?= $sel('accuracy_class_of_weight','F1') ?>>F1</option>
                <option value="M1" <?= $sel('accuracy_class_of_weight','M1') ?>>M1</option>
              </select>
            </div>

            <div class="col-12"><label class="form-label fw-semibold">Acclimatization Records</label></div>
            <div class="col-md-3">
              <label class="form-label">Lab Temperature (°C)</label>
              <input type="text" class="form-control" name="lab_temperature" value="<?= $s('lab_temperature') ?>">
            </div>
            <div class="col-md-3">
              <label class="form-label">Site Temperature (°C)</label>
              <input type="text" class="form-control" name="site_temperature" value="<?= $s('site_temperature') ?>">
            </div>
            <div class="col-md-3">
              <label class="form-label">Time Waited</label>
              <input type="text" class="form-control" name="time_waited" value="<?= $s('time_waited') ?>" placeholder="e.g. 2 hours">
            </div>

            <div class="col-md-3">
              <label class="form-label">Calibrated By</label>
              <input type="text" class="form-control" name="calibrated_by" value="<?= $s('calibrated_by') ?>">
            </div>
            <div class="col-md-3">
              <label class="form-label">Date Calibrated</label>
              <input type="date" class="form-control" name="calibrated_date" value="<?= $s('calibrated_date') ?>">
            </div>
            <div class="col-md-3">
              <label class="form-label">Checked By</label>
              <input type="text" class="form-control" name="checked_by" value="<?= $s('checked_by', $_SESSION['name'] ?? '') ?>">
            </div>
            <div class="col-md-3">
              <label class="form-label">Date Checked</label>
              <input type="date" class="form-control" name="date_checked" value="<?= $s('date_checked') ?>">
            </div>
            <div class="col-md-3">
              <label class="form-label">Due Date</label>
              <input type="date" class="form-control" name="due_date" value="<?= $s('due_date') ?>">
            </div>
          </div>
        </div>

        <!-- ════════════════════════════════════════════════════
             TAB — Test of Error Indicator
        ════════════════════════════════════════════════════ -->
        <div class="tab-pane fade" id="tab-error">
          <div class="mt-3">
            <h6 class="fw-bold mb-3">A. TEST OF ERROR INDICATOR</h6>
            <div class="table-responsive">
              <table class="table table-bordered table-sm align-middle">
                <thead class="table-light">
                  <tr>
                    <th>Applied Load /%</th>
                    <th>Nominal Value</th>
                    <th>Load (mref) <small class="text-muted fw-normal">auto</small></th>
                    <th>Reference Weight</th>
                    <th>Indication</th>
                    <th>Deviation of Indication <small class="text-muted fw-normal">auto</small></th>
                  </tr>
                </thead>
                <tbody>
                  <?php foreach ([0=>'0 / min',25=>'25',50=>'50',75=>'75',100=>'100'] as $pct => $label): ?>
                  <tr>
                    <td class="text-center fw-semibold"><?= $label ?></td>
                    <td><input type="text" class="form-control form-control-sm nominal-value"
                               name="nominal_value_<?= $pct ?>" id="nominal_value_<?= $pct ?>"
                               value="<?= $s("nominal_value_$pct") ?>" required></td>
                    <td><input type="text" class="form-control form-control-sm load-value bg-light"
                               name="load_<?= $pct ?>" id="load_value_<?= $pct ?>"
                               value="<?= $s("load_$pct") ?>" readonly></td>
                    <td><input type="text" class="form-control form-control-sm"
                               name="reference_weight_<?= $pct ?>"
                               value="<?= $s("reference_weight_$pct") ?>"></td>
                    <td><input type="text" class="form-control form-control-sm"
                               name="indication_<?= $pct ?>" id="indication_<?= $pct ?>"
                               value="<?= $s("indication_$pct") ?>" required></td>
                    <td><input type="text" class="form-control form-control-sm bg-light"
                               name="deviation_of_indication_<?= $pct ?>" id="deviation_of_indication_<?= $pct ?>"
                               value="<?= $s("deviation_of_indication_$pct") ?>" readonly></td>
                  </tr>
                  <?php endforeach; ?>
                </tbody>
              </table>
            </div>

            <h6 class="fw-bold mt-3 mb-2">Calculated Values</h6>
            <div class="table-responsive">
              <table class="table table-bordered table-sm">
                <thead class="table-light">
                  <tr><th>Row</th><th>Point 1 (0%)</th><th>Point 2 (25%)</th><th>Point 3 (50%)</th><th>Point 4 (75%)</th><th>Point 5 (100%)</th></tr>
                </thead>
                <tbody>
                  <tr>
                    <td class="fw-semibold">MPE</td>
                    <?php for($i=1;$i<=5;$i++): ?>
                    <td><input type="text" class="form-control form-control-sm bg-light"
                               name="mpe_<?= $i ?>" id="mpe_<?= $i ?>"
                               value="<?= $s("mpe_$i") ?>" readonly></td>
                    <?php endfor; ?>
                  </tr>
                  <tr>
                    <td class="fw-semibold">U of std</td>
                    <?php for($i=1;$i<=5;$i++): ?>
                    <td><input type="text" class="form-control form-control-sm bg-light"
                               name="u_of_std_value_<?= $i ?>" id="u_of_std_value_<?= $i ?>"
                               value="<?= $s("u_of_std_value_$i") ?>" readonly></td>
                    <?php endfor; ?>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>

        <!-- ════════════════════════════════════════════════════
             TAB — Repeatability Test
        ════════════════════════════════════════════════════ -->
        <div class="tab-pane fade" id="tab-repeat">
          <div class="mt-3">
            <div class="row g-3 mb-3 align-items-end">
              <div class="col-md-6">
                <h6 class="fw-bold">B. REPEATABILITY TEST</h6>
                <p class="text-muted small mb-0">Near maximum load test (0.5 max ≤ L ≤ Max)</p>
              </div>
              <div class="col-md-3">
                <label class="form-label">Applied Load (L)</label>
                <input type="text" class="form-control" name="applied_load_rt" id="applied_load_rt"
                       value="<?= $s('applied_load_rt') ?>" placeholder="Value in measurement unit">
              </div>
            </div>
            <div class="table-responsive">
              <table class="table table-bordered table-sm">
                <thead class="table-light">
                  <tr><th>Row</th><th>Reading 1</th><th>Reading 2</th><th>Reading 3</th><th>Reading 4</th><th>Reading 5</th></tr>
                </thead>
                <tbody>
                  <tr>
                    <td class="fw-semibold">Indication</td>
                    <?php for($i=1;$i<=5;$i++): ?>
                    <td><input type="text" class="form-control form-control-sm repeatability"
                               name="repeatability<?= $i ?>" id="repeatability<?= $i ?>"
                               value="<?= $s("repeatability$i") ?>" required></td>
                    <?php endfor; ?>
                  </tr>
                  <tr>
                    <td class="fw-semibold">u(δIrep) <small class="text-muted fw-normal">auto</small></td>
                    <?php for($i=1;$i<=5;$i++): ?>
                    <td><input type="text" class="form-control form-control-sm bg-light"
                               name="repeat_value_<?= $i ?>" id="repeat_value_<?= $i ?>"
                               value="<?= $s("repeat_value_$i") ?>" readonly></td>
                    <?php endfor; ?>
                  </tr>
                </tbody>
              </table>
            </div>
            <div class="col-md-4 mt-2">
              <label class="form-label fw-semibold">Standard Deviation <small class="text-muted fw-normal">(auto-calculated)</small></label>
              <input type="text" class="form-control bg-light" name="standard_deviation" id="standard_deviation"
                     value="<?= $s('standard_deviation') ?>" readonly>
            </div>
          </div>
        </div>

        <!-- ════════════════════════════════════════════════════
             TAB — Eccentricity Test + Uncertainty Calculations
        ════════════════════════════════════════════════════ -->
        <div class="tab-pane fade" id="tab-ecc">
          <div class="mt-3">
            <div class="row g-3 mb-3 align-items-end">
              <div class="col-md-6"><h6 class="fw-bold">C. ECCENTRICITY TEST (≤ Max/3)</h6></div>
              <div class="col-md-3">
                <label class="form-label">Applied Load (L)</label>
                <input type="text" class="form-control" name="applied_load_et" id="applied_load_et"
                       value="<?= $s('applied_load_et') ?>">
              </div>
            </div>
            <div class="table-responsive mb-3">
              <table class="table table-bordered table-sm">
                <thead class="table-light">
                  <tr><th>#</th><th>Position</th><th>Indication</th><th>Deviation <small class="text-muted fw-normal">auto</small></th><th>|Deviation| <small class="text-muted fw-normal">auto</small></th></tr>
                </thead>
                <tbody>
                  <?php
                  $eccRows = [
                    ['1','CENTRE',     'EC_Indication1_Centre','EC_Deviation_Centre','EC_Abs_Deviation_Centre'],
                    ['2','FRONT LEFT', 'EC_Indication_FL',     'EC_Deviation_FL',    'EC_Abs_Deviation_FL'],
                    ['3','BACK LEFT',  'EC_Indication_BL',     'EC_Deviation_BL',    'EC_Abs_Deviation_BL'],
                    ['4','BACK RIGHT', 'EC_Indication_BR',     'EC_Deviation_BR',    'EC_Abs_Deviation_BR'],
                    ['5','FRONT RIGHT','EC_Indication_FR',     'EC_Deviation_FR',    'EC_Abs_Deviation_FR'],
                  ];
                  foreach ($eccRows as [$no,$pos,$indId,$devId,$absId]):
                  ?>
                  <tr>
                    <td><?= $no ?></td>
                    <td><?= $pos ?></td>
                    <td><input type="text" class="form-control form-control-sm ec-indication"
                               name="<?= $indId ?>" id="<?= $indId ?>"
                               value="<?= $s($indId) ?>" required></td>
                    <td><input type="text" class="form-control form-control-sm bg-light ec-deviation"
                               name="<?= $devId ?>" id="<?= $devId ?>"
                               value="<?= $s($devId) ?>" readonly></td>
                    <td><input type="text" class="form-control form-control-sm bg-light ec-abs-deviation"
                               name="<?= $absId ?>" id="<?= $absId ?>"
                               value="<?= $s($absId) ?>" readonly></td>
                  </tr>
                  <?php endforeach; ?>
                </tbody>
              </table>
            </div>
            <div class="col-md-4 mb-3">
              <label class="form-label fw-semibold">Max. Difference Between Readings <small class="text-muted fw-normal">(auto)</small></label>
              <input type="text" class="form-control bg-light" name="max_difference" id="max_difference"
                     value="<?= $s('max_difference') ?>" readonly>
            </div>

            <h6 class="fw-bold mt-3 mb-2">Uncertainty Budget Table <small class="text-muted fw-normal">(all auto-calculated)</small></h6>
            <div class="table-responsive">
              <table class="table table-bordered table-sm">
                <thead class="table-light">
                  <tr>
                    <th style="min-width:120px">Component</th>
                    <th>Point 1 (0%)</th><th>Point 2 (25%)</th><th>Point 3 (50%)</th><th>Point 4 (75%)</th><th>Point 5 (100%)</th>
                  </tr>
                </thead>
                <tbody>
                  <?php
                  // $uncRows = [
                  //   ['u (δIdig0)',  'Idig'],
                  //   ['u (δIdigL)',  'u_IdigL'],
                  //   ['u (δIecc)',   'Iecc_value'],
                  //   ['u (δmc)',     'u_omc'],
                  //   ['u (δmB)',     'u_mB'],
                  //   ['u (δmD)',     'u_mD'],
                  //   ['u (δmconv)', 'u_mconv'],
                  //   ['u(E)',        'u_E'],
                  //   ['Veff',        'Veff_value'],
                  //   ['K',           'K_value'],
                  //   ['U (Expanded)','U_value'],
                  // ];
                  $uncRows = [
                      ['u (δIdig0)',   'Idig_value'],
                      ['u (δIdigL)',   'u_IdigL_value'],
                      ['u (δIecc)',    'Iecc_value'],
                      ['u (δmc)',      'u_omc_value'],
                      ['u (δmB)',      'u_mB_value'],
                      ['u (δmD)',      'u_mD_value'],
                      ['u (δmconv)',   'u_mconv_value'],
                      ['u(E)',         'u_E_value'],
                      ['Veff',         'Veff_value'],
                      ['K',            'K_value'],
                      ['U (Expanded)', 'U_value_4dp'],
                      ['U (Expanded) 2', 'U_value_5dp'],
                  ];

                  foreach ($uncRows as [$label, $prefix]):
                    $isTotal = in_array($label, ['u(E)','K','U (Expanded)']);
                  ?>
                  <tr <?= $isTotal ? 'class="table-warning"' : '' ?>>
                    <td class="fw-semibold"><?= $label ?></td>
                    <?php //for($i=1;$i<=5;$i++):
                      // Map prefix to the actual HTML id used in JS
                      // $jsId = match($prefix) {
                      //   'Iecc_value'  => "Iecc_value_{$i}",
                      //   'Veff_value'  => "Veff_value_{$i}",
                      //   default       => "{$prefix}_value_{$i}",
                      // };
                    ?>
                    <!-- <td><input type="text" class="form-control form-control-sm bg-light"
                               name="<?//= $prefix ?>_<?//= $i ?>"
                               id="<?//= $jsId ?>"
                               value="<?//= $s("{$prefix}_{$i}") ?>"
                               readonly></td> -->
                    <?php //endfor; ?>
                    <?php for($i=1;$i<=5;$i++): ?>
                    <td>
                      <input type="text"
                            class="form-control form-control-sm bg-light"
                            name="<?= $prefix ?>_<?= $i ?>"
                            id="<?= $prefix ?>_<?= $i ?>"
                            value="<?= $s("{$prefix}_{$i}") ?>"
                            readonly>
                    </td>
                    <?php endfor; ?>
                  </tr>
                  <?php endforeach; ?>
                </tbody>
              </table>
            </div>

            <div class="col-md-8 mt-3">
              <label class="form-label">Comments</label>
              <textarea class="form-control" name="comments" rows="3"><?= $s('comments') ?></textarea>
            </div>
          </div>
        </div>

      </div><!-- /tab-content -->

      <!-- ── Action Buttons ─────────────────────────────── -->
      <div class="d-flex gap-3 mt-4 pt-3 border-top align-items-center">
        <button type="submit" name="form_status" value="draft" class="btn btn-outline-primary btn-lg">
          <i class="bi bi-floppy me-2"></i>Save as Draft
        </button>
        <button type="submit" name="form_status" value="submitted" class="btn btn-success btn-lg">
          <i class="bi bi-check-circle me-2"></i>Submit &amp; Generate Certificate
        </button>
        <a href="<?= APP_URL ?>/index.php?page=requests&action=view&id=<?= $request['request_id'] ?>" class="btn btn-outline-secondary btn-lg">
          Cancel
        </a>
      </div>

    </form>
  </div>
</div>

<!-- ════════════ Balance Lab Calculation Scripts ════════════ -->
<script>
// ============================================================
// All calculations ported from the original Django template.
// ============================================================

// ── Weight table for Load (mref) calculation ──────────────
const weightTable = {
  g:      [0,1000,500,200,100,50,20,10,5,2,1,0.5,0.2,0.1,0.05,0.02,0.01,0.005,0.002,0.001],
  kg:     [0,1,0.5,0.2,0.1,0.05,0.02,0.01,0.005,0.002,0.001,0.0005,0.0002,0.0001,0.00005,0.00002,0.00001,0.000005,0.000002,0.000001],
  conv_kg:[0,0.9999997,0.50000002,0.20000003,0.10000011,0.05,0.020000014,0.010000038,0.005000007,0.002000008,0.001000019,0.000500013,0.002000006,0.001000007,0.000049998,0.000020004,0.000010002,0.000005002,0.000002001,0.000001002],
  conv_g: [0,999.9997,500.00002,200.00003,100.00011,50,20.000014,10.000038,5.000007,2.000008,1.000019,0.500013,0.200006,0.100007,0.049998,0.020004,0.010002,0.005002,0.002001,0.001002]
};
const category = [0,1000,500,200,100,50,20,10,5,2,1,0.5,0.2,0.1,0.05,0.02,0.01,0.005,0.002,0.001];

document.addEventListener('DOMContentLoaded', function() {
  const unit     = document.getElementById('unit');
  const classEl  = document.getElementById('accuracy_class_of_weight');
  const adjEl    = document.getElementById('balance_adjusted');
  const tempEl   = document.getElementById('chng_temp');

  if (unit)    unit.addEventListener('change',    () => { updateAllLoadValues(); updateAllCalc(); updateAllTemp(); });
  if (classEl) classEl.addEventListener('change', () => { updateAllLoadValues(); updateAllCalc(); });
  if (adjEl)   adjEl.addEventListener('change',   updateAllCalc);
  if (tempEl)  tempEl.addEventListener('change',  updateAllTemp);

  document.querySelectorAll('.nominal-value').forEach(inp => {
    inp.addEventListener('input', function() {
      const id = this.id.replace('nominal_value_','');
      calculateLoadValue(id);
      updateAllCalc();
      updateTemperatureCorrection(id);
    });
  });

  document.querySelectorAll('.repeatability').forEach(inp => {
    inp.addEventListener('input', calculateStandardDeviation);
  });

  document.querySelectorAll('.ec-indication').forEach(inp => {
    inp.addEventListener('input', calculateEccentricity);
  });

  const etLoad = document.getElementById('applied_load_et');
  if (etLoad) etLoad.addEventListener('input', calculateEccentricity);

  // Initial pass
  updateAllLoadValues();
  updateAllCalc();
  updateAllTemp();           // populate u(δmconv) on page load
  calculateStandardDeviation();
  calculateEccentricity();
});

// ── Load (mref) ────────────────────────────────────────────
function updateAllLoadValues() {
  ['0','25','50','75','100'].forEach(id => calculateLoadValue(id));
}

function calculateLoadValue(rowId) {
  const classEl = document.getElementById('accuracy_class_of_weight');
  const unitEl  = document.getElementById('unit');
  if (!classEl || !unitEl) return;
  const cls   = classEl.value;
  const unit  = unitEl.value;
  const nomEl = document.getElementById('nominal_value_' + rowId);
  const ldEl  = document.getElementById('load_value_' + rowId);
  if (!nomEl || !ldEl) return;
  const val = parseFloat(nomEl.value);
  if (isNaN(val)) { ldEl.value = ''; return; }
  if (cls === 'F1' || cls === 'M1') {
    ldEl.value = val;
  } else if (cls === 'E2') {
    const { total } = findNearestCombination(val, unit);
    ldEl.value = total.toFixed(6);
  }
}

function findNearestCombination(value, unit) {
  let closestSum = -Infinity, bestComb = [];
  function combos(arr, k, start, cur, res) {
    if (cur.length === k) { res.push([...cur]); return; }
    for (let i = start; i < arr.length; i++) {
      cur.push(arr[i]);
      combos(arr, k, i, cur, res);
      cur.pop();
    }
  }
  const combs = [];
  combos(category, 2, 0, [], combs);
  combos(category, 3, 0, [], combs);
  for (const c of combs) {
    const sum = c.reduce((a,b) => a+b, 0);
    if (sum <= value && sum > closestSum) { closestSum = sum; bestComb = c; }
  }
  let total = 0;
  bestComb.forEach(p => {
    const idx = weightTable[unit === 'kg' ? 'kg' : 'g'].indexOf(p);
    if (idx !== -1) total += weightTable[unit === 'kg' ? 'conv_kg' : 'conv_g'][idx];
  });
  return { combination: bestComb, total };
}

// ── MPE / Uncertainty of Standard ─────────────────────────
const weightData = {
  mg: { weights:[1,2,5,10,20,50,100,200,500,1000,2000,5000,10000,20000,50000,100000,200000,500000,1000000,2000000,5000000,0],mpe_E2:[0.000006,0.000006,0.000006,0.000008,0.00001,0.000012,0.000016,0.00002,0.000025,0.00003,0.00004,0.00005,0.00006,0.00008,0.0001,0.00016,0.0003,0.0008,0.0016,0.003,0.008,0],mpe_F1:[0.00002,0.00002,0.00002,0.000025,0.00003,0.00004,0.00005,0.00006,0.00008,0.0001,0.00012,0.00016,0.0002,0.00025,0.0003,0.0005,0.001,0.0025,0.005,0.01,0.025,0],mpe_M1:[0.0002,0.0002,0.0002,0.00025,0.0003,0.0004,0.0005,0.0006,0.0008,0.004,0.0012,0.0016,0.002,0.0025,0.003,0.005,0.01,0.025,0.05,0.1,0.25,0],mpe_E1:[0.000003,0.000003,0.000003,0.000003,0.000003,0.000004,0.000005,0.000006,0.000008,0.00001,0.000012,0.000016,0.00002,0.000025,0.00003,0.00005,0.0001,0.00025,0.0005,0.001,0.0025,0] },
  g:  { weights:[0.001,0.002,0.005,0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000,2000,5000,0],mpe_E2:[0.000006,0.000006,0.000006,0.000008,0.00001,0.000012,0.000016,0.00002,0.000025,0.00003,0.00004,0.00005,0.00006,0.00008,0.0001,0.00016,0.0003,0.0008,0.0016,0.003,0.008,0],mpe_F1:[0.00002,0.00002,0.00002,0.000025,0.00003,0.00004,0.00005,0.00006,0.00008,0.0001,0.00012,0.00016,0.0002,0.00025,0.0003,0.0005,0.001,0.0025,0.005,0.01,0.025,0],mpe_M1:[0.0002,0.0002,0.0002,0.00025,0.0003,0.0004,0.0005,0.0006,0.0008,0.001,0.0012,0.0016,0.002,0.0025,0.003,0.005,0.01,0.025,0.05,0.1,0.25,0],mpe_E1:[0.000003,0.000003,0.000003,0.000003,0.000003,0.000004,0.000005,0.000006,0.000008,0.00001,0.000012,0.000016,0.00002,0.000025,0.00003,0.00005,0.0001,0.00025,0.0005,0.001,0.0025,0] },
  kg: { weights:[0.000001,0.000002,0.000005,0.00001,0.00002,0.00005,0.0001,0.0002,0.0005,0.001,0.002,0.005,0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,0],mpe_E2:[0.000006,0.000006,0.000006,0.000008,0.00001,0.000012,0.000016,0.00002,0.000025,0.00003,0.00004,0.00005,0.00006,0.00008,0.0001,0.00016,0.0003,0.0008,0.0016,0.003,0.008,0],mpe_F1:[0.00002,0.00002,0.00002,0.000025,0.00003,0.00004,0.00005,0.00006,0.00008,0.0001,0.00012,0.00016,0.0002,0.00025,0.0003,0.0005,0.001,0.0025,0.005,0.01,0.025,0],mpe_M1:[0.0002,0.0002,0.0002,0.00025,0.0003,0.0004,0.0005,0.0006,0.0008,0.001,0.0012,0.0016,0.002,0.0025,0.003,0.005,0.01,0.025,0.05,0.1,0.25,0],mpe_E1:[0.000003,0.000003,0.000003,0.000003,0.000003,0.000004,0.000005,0.000006,0.000008,0.00001,0.000012,0.000016,0.00002,0.000025,0.00003,0.00005,0.0001,0.00025,0.0005,0.001,0.0025,0] }
};

// ── Excel-faithful LOOKUP snap: returns the largest weight value <= val from the table ──
// Mirrors Excel LOOKUP(val, weights_array, weights_array) exact-match-or-floor behaviour.
function snapWeight(val, weights) {
  // weights array is sorted ascending (0 sentinel at end is excluded from snap)
  let best = null;
  for (let i = 0; i < weights.length; i++) {
    const w = weights[i];
    if (w === null || w === 0) continue; // skip sentinel 0
    if (w <= val) {
      if (best === null || w > best) best = w;
    }
  }
  return best !== null ? best : 0;
}

// ── Greedy 3-step decomposition matching Excel LOOKUP chain ──
// Excel: S28=LOOKUP(B,…), S29=LOOKUP(B-S28,…), S30=LOOKUP(B-S28-S29,…)
// then MPE = VLOOKUP(S28)+VLOOKUP(S29)+VLOOKUP(S30)
// This means: snap to largest ≤ nomVal, then take the remainder twice more.
// NO weight repetition within a single nominal value decomposition.
function getMPEAndU(nomVal, unit, cls) {
  if (!weightData[unit] || isNaN(nomVal) || nomVal === null) return { mpe:null, u:null };
  const d = weightData[unit];
  const mpeCol = cls==='E2'?'mpe_E2':cls==='F1'?'mpe_F1':'mpe_M1';
  const uCol   = cls==='E2'?'mpe_E1':cls==='F1'?'mpe_E2':'mpe_F1';

  // Special-case exact zero
  if (nomVal === 0) return { mpe: 0, u: 0 };

  // Helper: look up MPE/U for a snapped weight value
  function lookup(w) {
    if (w === 0 || w === null) return { mpe: 0, u: 0 };
    const idx = d.weights.indexOf(w);
    if (idx !== -1) return { mpe: d[mpeCol][idx] || 0, u: d[uCol][idx] || 0 };
    return { mpe: 0, u: 0 };
  }

  // Greedy decomposition: up to 3 steps
  const w1 = snapWeight(nomVal, d.weights);
  const rem1 = nomVal - w1;
  const w2 = snapWeight(rem1, d.weights);
  const rem2 = rem1 - w2;
  const w3 = snapWeight(rem2, d.weights);

  const r1 = lookup(w1);
  const r2 = lookup(w2);
  const r3 = lookup(w3);

  const mpe = r1.mpe + r2.mpe + r3.mpe;
  const u   = r1.u   + r2.u   + r3.u;
  return { mpe, u };
}

function updateAllCalc() {
  const cls  = document.getElementById('accuracy_class_of_weight')?.value;
  const unit = document.getElementById('unit')?.value;
  if (!cls || !unit) return;
  ['0','25','50','75','100'].forEach((pct, idx) => {
    const i    = idx + 1;
    const nom  = parseFloat(document.getElementById('nominal_value_' + pct)?.value);
    const { mpe, u } = getMPEAndU(nom, unit, cls);
    const mpeEl = document.getElementById('mpe_' + i);
    const uEl   = document.getElementById('u_of_std_value_' + i);
    if (mpeEl) mpeEl.value = mpe !== null ? mpe.toFixed(6) : '';
    if (uEl)   uEl.value   = u   !== null ? u.toFixed(6)   : '';
    // Deviation
    calculateDeviation(pct);
    // Uncertainty components
    calcIdig(i); calcUIdigL(i, pct); calcUMc(i, cls); calcUMb(i, pct, cls); calcUMd(i); calcUE(i);
  });
}

// ── Deviation of Indication ────────────────────────────────
function calculateDeviation(pct) {
  const unit = document.getElementById('unit')?.value;
  const load = parseFloat(document.getElementById('load_value_' + pct)?.value) || 0;
  const ind  = parseFloat(document.getElementById('indication_' + pct)?.value) || 0;
  const devEl = document.getElementById('deviation_of_indication_' + pct);
  if (!devEl) return;
  let dev = (unit === 'kg') ? (ind - load) * 1000 : (ind - load);
  devEl.value = dev.toFixed(4);
}

['0','25','50','75','100'].forEach(pct => {
  document.addEventListener('DOMContentLoaded', () => {
    document.getElementById('indication_' + pct)?.addEventListener('input', () => {
      calculateDeviation(pct); updateAllCalc();
    });
  });
});

// ── Standard Deviation (Repeatability) ────────────────────
function calculateStandardDeviation() {
  const vals = [];
  document.querySelectorAll('.repeatability').forEach(inp => {
    const v = parseFloat(inp.value);
    if (!isNaN(v)) vals.push(v);
  });
  const sdEl = document.getElementById('standard_deviation');
  if (!sdEl) return;
  if (vals.length === 5) {
    const mean = vals.reduce((a,b)=>a+b,0)/5;
    const sd   = Math.sqrt(vals.reduce((a,b)=>a+Math.pow(b-mean,2),0)/4);
    sdEl.value = sd.toFixed(6); //9 in Excel, but 6 is more reasonable for display
    for (let i=1;i<=5;i++) {
      const el = document.getElementById('repeat_value_' + i);
      if (el) el.value = sd.toFixed(6);
    }
  } else {
    sdEl.value = '';
    for (let i=1;i<=5;i++) {
      const el = document.getElementById('repeat_value_' + i);
      if (el) el.value = '';
    }
  }
  updateAllCalc();
}

// ── Eccentricity ───────────────────────────────────────────
function calculateEccentricity() {
  const centre = parseFloat(document.getElementById('EC_Indication1_Centre')?.value) || 0;
  const ids = ['EC_Indication1_Centre','EC_Indication_FL','EC_Indication_BL','EC_Indication_BR','EC_Indication_FR'];
  const devIds = ['EC_Deviation_Centre','EC_Deviation_FL','EC_Deviation_BL','EC_Deviation_BR','EC_Deviation_FR'];
  const absIds = ['EC_Abs_Deviation_Centre','EC_Abs_Deviation_FL','EC_Abs_Deviation_BL','EC_Abs_Deviation_BR','EC_Abs_Deviation_FR'];
  const absVals = [];
  ids.forEach((id, i) => {
    const val = parseFloat(document.getElementById(id)?.value) || 0;
    const dev = val - centre;
    const abs = Math.abs(dev);
    const dEl = document.getElementById(devIds[i]);
    const aEl = document.getElementById(absIds[i]);
    if (dEl) dEl.value = dev.toFixed(4);
    if (aEl) aEl.value = abs.toFixed(4);
    absVals.push(abs);
  });
  const maxDiff = Math.max(...absVals);
  const mdEl = document.getElementById('max_difference');
  if (mdEl) mdEl.value = maxDiff.toFixed(4);
  calculateUIecc(maxDiff);
  for (let i=1;i<=5;i++) calcUE(i);
}

function calculateUIecc(maxDiff) {
  const unit   = document.getElementById('unit')?.value;
  const etLoad = parseFloat(document.getElementById('applied_load_et')?.value) || 1;
  const factor = 0.2886751345948;
  ['0','25','50','75','100'].forEach((pct, idx) => {
    const i   = idx + 1;
    const ind = parseFloat(document.getElementById('indication_' + pct)?.value) || 0;
    let val   = (factor * maxDiff * ind) / etLoad;
    if (unit === 'mg') val /= 1000;
    const el  = document.getElementById('Iecc_value_' + i);
    if (el) el.value = val.toFixed(6);
  });
}

// ── Uncertainty Components ─────────────────────────────────
const DIG_CONST = 0.0001;

function calcIdig(i) {
  const r = (1 / (2 * Math.sqrt(3))) * DIG_CONST;
  const el = document.getElementById('Idig_value_' + i);
  if (el) el.value = r.toFixed(6);
  return r;
}

function calcUIdigL(i, pct, rawIdig) {
  const nom0 = parseFloat(document.getElementById('nominal_value_0')?.value) || 0;
  const idig = (rawIdig !== undefined) ? rawIdig
             : parseFloat(document.getElementById('Idig_value_' + i)?.value) || 0;
  const el   = document.getElementById('u_IdigL_value_' + i);
  const val  = (i === 1 && nom0 === 0) ? 0 : idig;
  if (el) el.value = val.toFixed(6);
  return val;
}

function calcUMc(i, cls) {
  const uStd = parseFloat(document.getElementById('u_of_std_value_' + i)?.value) || 0;
  const mpe  = parseFloat(document.getElementById('mpe_' + i)?.value) || 0;
  const res  = cls === 'E2' ? uStd / 2 : mpe / Math.sqrt(3);
  const el   = document.getElementById('u_omc_value_' + i);
  if (el) el.value = res.toFixed(6);
  return res;
}

function calcUMb(i, pct, cls) {
  // Excel formulas (G5 = balance_adjusted value, e.g. "NO"):
  //   F22: IF(G5="NO", IF(B4=0, 0, ((0.000015+(B13/(4*B4)))/SQRT(3))*B4), B13/(4*SQRT(3)))
  //   F23: IF(G5="NO", ((0.000015+(C13/(4*B5)))/SQRT(3))*B5, C13/(4*SQRT(3)))
  //   F24: IF(G5="NO", ((0.000015+(D13/(4*B6)))/SQRT(3))*B6, D13/(4*SQRT(3)))
  //   F25: IF(G5=G14, ((0.000015+(E13/(4*B7)))/SQRT(3))*B7, E13/(4*SQRT(3)))
  //          NOTE: G14 is an EMPTY cell, so condition is always FALSE -> E13/(4*SQRT(3))
  //   F26: IF(G5="NO", ((0.000015+(F13/(4*B8)))/SQRT(3))*B8, F13/(4*SQRT(3)))
  const adj = document.getElementById('balance_adjusted')?.value;
  const nom = parseFloat(document.getElementById('nominal_value_' + pct)?.value) || 0;
  const mpe = parseFloat(document.getElementById('mpe_' + i)?.value) || 0;
  const el  = document.getElementById('u_mB_value_' + i);
  if (!el) return;
  let res;
  if (i === 4) {
    // Point 4 (pct='75'): Excel F25 uses G5=G14 where G14 is empty -> always FALSE
    // Result: mpe / (4 * SQRT(3))  regardless of adj setting
    res = mpe / (4 * Math.sqrt(3));
  } else if (adj === 'No') {
    // Points 1,2,3,5 when not adjusted
    res = (i === 1 && nom === 0) ? 0 : ((0.000015 + (mpe / (4 * nom))) / Math.sqrt(3)) * nom;
  } else {
    // Points 1,2,3,5 when adjusted (Yes)
    res = mpe / (4 * Math.sqrt(3));
  }
  el.value = res.toFixed(6);
  return res;
}

function calcUMd(i) {
  // Excel formula:
  //   Point 1 (i=1):  G22 = MPE_1 / SQRT(3)
  //   Points 2-5:     G23..G26 = U_of_std_i * 1.25 / SQRT(3)
  let res;
  if (i === 1) {
    const mpe = parseFloat(document.getElementById('mpe_1')?.value) || 0;
    res = mpe / Math.sqrt(3);
  } else {
    const uStd = parseFloat(document.getElementById('u_of_std_value_' + i)?.value) || 0;
    res = (uStd * 1.25) / Math.sqrt(3);
  }
  const el = document.getElementById('u_mD_value_' + i);
  if (el) el.value = res.toFixed(6);
  return res;
}

// function calcUE(i) {
//   const ids = [
//     'Idig_value_' + i, 'u_IdigL_value_' + i, 'Iecc_value_' + i,
//     'repeat_value_' + i, 'u_omc_value_' + i, 'u_mB_value_' + i,
//     'u_mD_value_' + i, 'u_mconv_value_' + i
//   ];
//   const uE = Math.sqrt(ids.reduce((s, id) => {
//     const v = parseFloat(document.getElementById(id)?.value) || 0;
//     return s + v * v;
//   }, 0));
//   const el = document.getElementById('u_E_value_' + i);
//   if (el) el.value = uE.toFixed(6);
//   calcVeffK(i, uE);
//   return uE;
// }
function calcUE(i) {
  // Each calc function now returns its raw (unrounded) float so we NEVER
  // re-read a .toFixed(6) DOM string here.  Re-reading rounded strings would
  // amplify the 6th-decimal truncation error inside the u^4 terms of the
  // Welch-Satterthwaite denominator and produce a wrong Veff decimal part.
  //
  // Iecc, repeat (SD), and u_mconv are written by separate code paths that
  // run before calcUE, so reading their DOM values is safe here (no extra
  // rounding is introduced — they are already rounded at source).
  const cls  = document.getElementById('accuracy_class_of_weight')?.value || '';
  const pcts = ['0','25','50','75','100'];
  const pct  = pcts[i - 1];

  const rawIdig   = calcIdig(i);                 // u(δIdig0)  — returns raw float
  const rawIdigL  = calcUIdigL(i, pct, rawIdig); // u(δIdigL)  — receives rawIdig
  const rawIecc   = parseFloat(document.getElementById('Iecc_value_'    + i)?.value) || 0;
  const rawRepeat = parseFloat(document.getElementById('repeat_value_'  + i)?.value) || 0;
  const rawUMc    = calcUMc(i, cls);             // u(δmc)     — returns raw float
  const rawUMb    = calcUMb(i, pct, cls);        // u(δmB)     — returns raw float
  const rawUMd    = calcUMd(i);                  // u(δmD)     — returns raw float
  const rawUMconv = parseFloat(document.getElementById('u_mconv_value_' + i)?.value) || 0;

  const rawComponents = [
    [rawIdig,   1000 ],  // u(δIdig0)
    [rawIdigL,  1000 ],  // u(δIdigL)
    [rawIecc,   10000],  // u(δIecc)
    [rawRepeat, 4    ],  // u(δIrep)  — v = n-1 = 4
    [rawUMc,    1000 ],  // u(δmc)
    [rawUMb,    1000 ],  // u(δmB)
    [rawUMd,    1000 ],  // u(δmD)
    [rawUMconv, 1000 ],  // u(δmconv)
  ];

  const uE = Math.sqrt(rawComponents.reduce((s, [v]) => s + v * v, 0));
  const el = document.getElementById('u_E_value_' + i);
  if (el) el.value = uE.toFixed(6);
  calcVeffK(i, uE, rawComponents);
  return uE;
}

// function calcVeffK(i, uE) {
//   const components = [
//     [document.getElementById('Idig_value_' + i),     1000],
//     [document.getElementById('u_IdigL_value_' + i),  1000],
//     [document.getElementById('Iecc_value_' + i),     10000],
//     [document.getElementById('repeat_value_' + i),   4],
//     [document.getElementById('u_omc_value_' + i),    1000],
//     [document.getElementById('u_mB_value_' + i),     1000],
//     [document.getElementById('u_mD_value_' + i),     1000],
//     [document.getElementById('u_mconv_value_' + i),  1000],
//   ];
//   const denom = components.reduce((s, [el, div]) => {
//     const v = parseFloat(el?.value) || 0;
//     return s + Math.pow(v, 4) / div;
//   }, 0);
//   const veff = denom > 0 ? Math.pow(uE, 4) / denom : 0;
//   const vEl  = document.getElementById('Veff_value_' + i);
//   if (vEl) vEl.value = veff.toFixed(4);
//   const k   = 2; // simplified — TINV approximation
//   const kEl = document.getElementById('K_value_' + i);
//   if (kEl) kEl.value = k.toFixed(2);
//   const uEl = document.getElementById('U_value_' + i);
//   if (uEl) uEl.value = (k * uE).toFixed(5);
// }

// ── Welch-Satterthwaite Veff, TINV-based k, and U (Expanded) ─────────────
//
// Excel formulas (point i, rows 31-35):
//   Veff : A3x = uE^4 / SUM(u_j^4 / v_j)
//            degrees of freedom per component:
//            u(δIdig0)=1000, u(δIdigL)=1000, u(δIecc)=10000,
//            u(δIrep)=4,     u(δmc)=1000,    u(δmB)=1000,
//            u(δmD)=1000,    u(δmconv)=1000
//   k    : B3x = IF($M$6=0, 2, TINV(1-0.9545, A3x))
//            Excel TINV truncates Veff to integer (INT) before computing.
//            TINV(p, df) = t such that P(|T|>t) = p  (two-tailed t-distribution)
//            In JS: jStat.ttest equivalent -> use regularizedIncompleteBeta
//   U    : C3x = k * uE

function calcVeffK(i, uE, rawComponents) {
  // rawComponents: array of [rawFloatValue, degreesOfFreedom]
  // passed in from calcUE so we use unrounded floats, not DOM-read strings.
  const denom = rawComponents.reduce((s, [v, dof]) => s + Math.pow(v, 4) / dof, 0);
  const veff  = denom > 0 ? Math.pow(uE, 4) / denom : 0;

  const vEl = document.getElementById('Veff_value_' + i);
  if (vEl) vEl.value = veff.toFixed(4);

  // k: TINV(1-0.9545, INT(veff))
  // Excel INT truncates toward negative infinity (same as Math.floor for positive values).
  const df = Math.floor(veff);
  const k  = df > 0 ? tinv(0.0455, df) : 2;
  const kEl = document.getElementById('K_value_' + i);
  // K → 2 decimal places
  // if (kEl) kEl.value = k.toFixed(6);
  if (kEl) kEl.value = k.toFixed(2);

  // U (Expanded) → 5 decimal places
  const uEl5 = document.getElementById('U_value_5dp_' + i);
  if (uEl5) uEl5.value = (k * uE).toFixed(5);
  // if (uEl) uEl.value = (k * uE).toFixed(6);

  // U (Expanded) → 4 decimal places
  const uEl4 = document.getElementById('U_value_4dp_' + i);
  if (uEl4) uEl4.value = (k * uE).toFixed(4);
}

// ── Two-tailed inverse t-distribution  (mirrors Excel TINV) ──────────────
// TINV(p, df): returns t > 0 such that P(|T| > t) = p for T ~ t(df)
// Equivalent to: t.ppf(1 - p/2, df) in scipy / R qt(1-p/2, df)
// Uses a Newton-Raphson iteration on the regularised incomplete beta function.
function tinv(p, df) {
  // Two-tailed: find t such that 2*(1 - CDF(t,df)) = p
  // i.e. CDF(t, df) = 1 - p/2
  // CDF of t(df): 0.5 * I(df/(df+t^2), df/2, 0.5)  [regularised incomplete beta]
  // We iterate using bisection then Newton-Raphson for speed & accuracy.

  const target = 1.0 - p / 2;   // target CDF value

  // t-CDF via regularised incomplete beta
  function tCDF(t) {
    const x = df / (df + t * t);
    return 1.0 - 0.5 * incompleteBeta(x, df / 2, 0.5);
  }

  // Bisect to find t
  let lo = 0, hi = 1e6;
  // Make sure hi is large enough
  while (tCDF(hi) < target) hi *= 2;
  for (let iter = 0; iter < 100; iter++) {
    const mid = (lo + hi) / 2;
    if (tCDF(mid) < target) lo = mid; else hi = mid;
    if (hi - lo < 1e-12) break;
  }
  return (lo + hi) / 2;
}

// ── Regularised incomplete beta  I_x(a, b) ───────────────────────────────
// Uses continued fraction expansion (Lentz's algorithm) for accuracy.
function incompleteBeta(x, a, b) {
  if (x <= 0) return 0;
  if (x >= 1) return 1;

  // Use symmetry relation when x > (a+1)/(a+b+2) for faster convergence
  if (x > (a + 1) / (a + b + 2)) {
    return 1 - incompleteBeta(1 - x, b, a);
  }

  // Log of the beta function normalisation constant
  const lbeta = logGamma(a) + logGamma(b) - logGamma(a + b);
  const front  = Math.exp(Math.log(x) * a + Math.log(1 - x) * b - lbeta) / a;

  // Lentz continued fraction
  function cf() {
    const TINY = 1e-30;
    let f = TINY, C = f, D = 0;
    for (let m = 0; m <= 200; m++) {
      for (let s = 0; s <= 1; s++) {
        let d;
        if (m === 0 && s === 0) {
          d = 1;
        } else if (s === 0) {
          d = (m * (b - m) * x) / ((a + 2*m - 1) * (a + 2*m));
        } else {
          d = -((a + m) * (a + b + m) * x) / ((a + 2*m) * (a + 2*m + 1));
        }
        D = 1 + d * D; if (Math.abs(D) < TINY) D = TINY; D = 1/D;
        C = 1 + d / C; if (Math.abs(C) < TINY) C = TINY;
        f *= C * D;
        if (Math.abs(C * D - 1) < 1e-14) return f;
      }
    }
    return f;
  }
  return front * cf();
}

// ── Log-gamma function (Lanczos approximation) ───────────────────────────
function logGamma(z) {
  const g = 7;
  const c = [
    0.99999999999980993,  676.5203681218851,    -1259.1392167224028,
    771.32342877765313,   -176.61502916214059,    12.507343278686905,
    -0.13857109526572012,  9.9843695780195716e-6,  1.5056327351493116e-7
  ];
  if (z < 0.5) return Math.log(Math.PI / Math.sin(Math.PI * z)) - logGamma(1 - z);
  z -= 1;
  let x = c[0];
  for (let i = 1; i < g + 2; i++) x += c[i] / (z + i);
  const t = z + g + 0.5;
  return 0.5 * Math.log(2 * Math.PI) + (z + 0.5) * Math.log(t) - t + Math.log(x);
}

// ── Temperature Correction (u_mconv) ──────────────────────
// Abbreviated table — covers common mass values
const tempTableKg = {temps:[25,20,15,10,7,5,3,2,1,0,0],values:{50:[113.23,87.06,60.23,43.65,32.27,20.47,14.3,7.79,0,0],20:[49.23,38,26.43,19.25,14.3,9.14,6.42,3.53,0,0],10:[26.43,20.47,14.3,10.45,7.79,5.01,3.53,1.96,0,0],5:[14.3,11.1,7.79,5.72,4.28,2.76,1.96,1.09,0,0],2:[6.42,5.01,3.53,2.61,1.96,1.27,0.91,0.51,0,0],1:[3.53,2.76,1.96,1.45,1.09,0.72,0.51,0.29,0,0],0.5:[1.96,1.54,1.09,0.81,0.61,0.4,0.29,0.17,0,0],0.2:[0.91,0.72,0.51,0.38,0.29,0.19,0.14,0.08,0,0],0.1:[0.51,0.4,0.29,0.22,0.17,0.11,0.08,0.05,0,0]}};
const tempTableG  = {temps:[25,20,15,10,7,5,3,2,1,0,0],values:{50000:[113.23,87.06,60.23,43.65,32.27,20.47,14.3,7.79,0,0],20000:[49.23,38,26.43,19.25,14.3,9.14,6.42,3.53,0,0],10000:[26.43,20.47,14.3,10.45,7.79,5.01,3.53,1.96,0,0],5000:[14.3,11.1,7.79,5.72,4.28,2.76,1.96,1.09,0,0],2000:[6.42,5.01,3.53,2.61,1.96,1.27,0.91,0.51,0,0],1000:[3.53,2.76,1.96,1.45,1.09,0.72,0.51,0.29,0,0],500:[1.96,1.54,1.09,0.81,0.61,0.4,0.29,0.17,0,0],200:[0.91,0.72,0.51,0.38,0.29,0.19,0.14,0.08,0,0],100:[0.51,0.4,0.29,0.22,0.17,0.11,0.08,0.05,0,0]}};

function updateAllTemp() {
  ['0','25','50','75','100'].forEach(updateTemperatureCorrection);
}

function updateTemperatureCorrection(rowId) {
  const unit = document.getElementById('unit')?.value;
  const temp = parseFloat(document.getElementById('chng_temp')?.value);
  const nom  = parseFloat(document.getElementById('nominal_value_' + rowId)?.value);
  const i    = parseInt(rowId)/25 + 1;
  const el   = document.getElementById('u_mconv_value_' + i);
  if (!el) return;
  if (!unit || isNaN(temp) || isNaN(nom)) { el.value = ''; return; }
  const table = unit === 'kg' ? tempTableKg : tempTableG;
  const tIdx  = table.temps.indexOf(temp);
  if (tIdx === -1) { el.value = ''; return; }
  let correction = 0;
  const keys = Object.keys(table.values).map(Number).filter(w => w <= nom && w > 0).sort((a,b)=>b-a);
  let rem = nom;
  for (const k of keys) { if (rem <= 0) break; correction += table.values[k][tIdx]; rem -= k; }
  el.value = ((correction / 1000) / Math.sqrt(3)).toFixed(6);
  calcUE(i);
}
</script>

<?php include __DIR__ . '/../../shared/footer.php'; ?>