<?php
include("../classes/manager.class.php");
ini_set('display_errors', 1);
error_reporting(E_ALL);
$m = new Manager();

if (!isset($_SESSION['sess_userid'])) { header("Location: " . PROJECT_ADMIN_URL); exit(); }

$output = '';
$is_edit   = isset($_GET['edit']) && isset($_GET['id']);
$purchase_id = $is_edit ? (int)$_GET['id'] : 0;

// Common data
$supers = SupplierSetup::GetSupplierSetupList(" WHERE status='active'");
$prods  = ProductSetup::GetProductSetupList(" WHERE status='active' ORDER BY product_order ASC");

// Build quick maps
$prodMap = []; $prodCP = []; $prodTP = [];
if ($prods) {
  foreach ($prods as $p) {
    $prodMap[(int)$p->id] = $p;
    $prodCP[(int)$p->id] = (int)$p->carton_pieces;
    $prodTP[(int)$p->id] = (float)$p->tp_rate;
  }
}

// Defaults (add mode)
$supplier_id = '';
$po_number   = '';
$date        = date('Y-m-d');
$remarks     = '';

// If editing, load existing header/items
$existingItems = [];
$existingProductIds = [];
$existingItemMap = [];
$stockByPurchaseItem = [];
$removedIds = [];

if ($is_edit) {
  $hdr = PurchaseSetup::GetPurchaseById($purchase_id);
  if (!$hdr) { die("Purchase not found."); }
  $supplier_id = $hdr->supplier_id;
  $po_number   = $hdr->po_number;
  $date        = $hdr->date;
  $remarks     = $hdr->remarks;

  $rows = PurchaseSetup::GetPurchaseItems($purchase_id);
  if ($rows) {
    foreach ($rows as $r) {
      $existingItems[] = $r;
      $existingProductIds[(int)$r->product_id] = true;
      $existingItemMap[(int)$r->id] = $r;
    }
  }
}

// handle submit (both add + edit)
if (!empty($_POST)) {
  $supplier_id  = isset($_POST['supplier_id']) ? (int)$_POST['supplier_id'] : 0;
  $po_number    = isset($_POST['po_number']) ? $_POST['po_number'] : '';
  $date         = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
  $remarks      = isset($_POST['remarks']) ? $_POST['remarks'] : '';

  // Arrays for items posted.
  // We use two sets:
  //  1) existing rows arrays (id[], product_id_existing[], cartons_existing[], pieces_existing[], unit_cost_existing[], batch_no_existing[], expiry_date_existing[])
  //  2) new rows arrays (product_id_new[], cartons_new[], pieces_new[], unit_cost_new[], batch_no_new[], expiry_date_new[])
  $ex_ids       = isset($_POST['item_id']) ? $_POST['item_id'] : [];
  $ex_pids      = isset($_POST['product_id_existing']) ? $_POST['product_id_existing'] : [];
  $ex_cartons   = isset($_POST['cartons_existing']) ? $_POST['cartons_existing'] : [];
  $ex_pieces    = isset($_POST['pieces_existing']) ? $_POST['pieces_existing'] : [];
  $ex_costs     = isset($_POST['unit_cost_existing']) ? $_POST['unit_cost_existing'] : [];
  $ex_batch     = isset($_POST['batch_no_existing']) ? $_POST['batch_no_existing'] : [];
  $ex_expiry    = isset($_POST['expiry_date_existing']) ? $_POST['expiry_date_existing'] : [];

  $new_pids     = isset($_POST['product_id_new']) ? $_POST['product_id_new'] : [];
  $new_cartons  = isset($_POST['cartons_new']) ? $_POST['cartons_new'] : [];
  $new_pieces   = isset($_POST['pieces_new']) ? $_POST['pieces_new'] : [];
  $new_costs    = isset($_POST['unit_cost_new']) ? $_POST['unit_cost_new'] : [];
  $new_batch    = isset($_POST['batch_no_new']) ? $_POST['batch_no_new'] : [];
  $new_expiry   = isset($_POST['expiry_date_new']) ? $_POST['expiry_date_new'] : [];

  $errors = [];
  if (empty($supplier_id)) $errors[] = "Please select supplier";
  if (empty($date))        $errors[] = "Please select date";

  $items = [];
  $line_total = 0.0;

  // Helper to compute qty from cartons/pieces for a product
  $qtyFrom = function($pid, $cartons, $pieces) use ($prodCP) {
    $cp = isset($prodCP[$pid]) ? (int)$prodCP[$pid] : 0;
    $cartons = (int)$cartons; $pieces = (int)$pieces;
    return ($cartons > 0 ? ($cartons * $cp) : 0) + ($pieces > 0 ? $pieces : 0);
  };

  // Existing rows
  for ($i=0; $i<count($ex_pids); $i++) {
    $pid = (int)$ex_pids[$i];
    $q   = $qtyFrom($pid, $ex_cartons[$i] ?? 0, $ex_pieces[$i] ?? 0);
    $uc  = (isset($ex_costs[$i]) && is_numeric($ex_costs[$i])) ? (float)$ex_costs[$i] : 0;
    if ($pid > 0 && $q > 0) {
      $items[] = [
        'mode'        => 'existing',
        'item_id'     => (int)$ex_ids[$i],
        'product_id'  => $pid,
        'qty'         => $q,
        'unit_cost'   => $uc,
        'batch_no'    => !empty($ex_batch[$i]) ? $ex_batch[$i] : null,
        'expiry_date' => !empty($ex_expiry[$i]) ? $ex_expiry[$i] : null,
      ];
      $line_total += ($q * $uc);
    }
  }

  // New rows
  for ($i=0; $i<count($new_pids); $i++) {
    $pid = (int)$new_pids[$i];
    $q   = $qtyFrom($pid, $new_cartons[$i] ?? 0, $new_pieces[$i] ?? 0);
    $uc  = (isset($new_costs[$i]) && is_numeric($new_costs[$i])) ? (float)$new_costs[$i] : 0;
    if ($pid > 0 && $q > 0) {
      $items[] = [
        'mode'        => 'new',
        'product_id'  => $pid,
        'qty'         => $q,
        'unit_cost'   => $uc,
        'batch_no'    => !empty($new_batch[$i]) ? $new_batch[$i] : null,
        'expiry_date' => !empty($new_expiry[$i]) ? $new_expiry[$i] : null,
      ];
      $line_total += ($q * $uc);
    }
  }

  if (empty($items)) $errors[] = "Please enter quantity (cartons and/or pieces) for at least one product";

  // --------- EXTRA VALIDATION FOR EDIT MODE: PROTECT USED STOCK ----------
  if ($is_edit && count($errors) == 0) {
    global $db;

   // Load stock rows for this purchase keyed by purchase_item_id
$stockByPurchaseItem = [];
$rowsStock = $db->fetch_all_array("SELECT * FROM ".TABLE_STOCK." WHERE purchase_id='".$purchase_id."'");
if ($rowsStock && $db->affected_rows > 0) {
    foreach ($rowsStock as $row) {
        // $row is an object, same style as GetPurchaseItems()
        $stockByPurchaseItem[(int)$row->purchase_item_id] = $row;
    }
}

    // Determine which existing purchase_item rows were removed in the form
    $postedExistingIds = [];
    if (!empty($ex_ids)) {
      foreach ($ex_ids as $eid) {
        $eid = (int)$eid;
        if ($eid > 0) $postedExistingIds[] = $eid;
      }
    }
    $existingDbIds = array_keys($existingItemMap);
    $removedIds = array_diff($existingDbIds, $postedExistingIds);

    // 1) Disallow removing lines that already have deducted stock
    foreach ($removedIds as $rid) {
      if (isset($stockByPurchaseItem[$rid]) && (int)$stockByPurchaseItem[$rid]->deducted_qty > 0) {
        $used = (int)$stockByPurchaseItem[$rid]->deducted_qty;
        $prodName = 'this product';
        if (isset($existingItemMap[$rid])) {
          $pi = $existingItemMap[$rid];
          if (isset($prodMap[$pi->product_id])) {
            $prodName = $prodMap[$pi->product_id]->name;
          }
        }
        $errors[] = "Cannot remove product \"$prodName\" because $used unit(s) have already been used in invoices.";
      }
    }

    // 2) Disallow reducing received quantity below already-used quantity
    foreach ($items as $it) {
      if ($it['mode'] === 'existing') {
        $piId = (int)$it['item_id'];
        if (isset($stockByPurchaseItem[$piId])) {
          $ded = (int)$stockByPurchaseItem[$piId]->deducted_qty;
          if ($it['qty'] < $ded) {
            $prodName = 'this product';
            if (isset($existingItemMap[$piId])) {
              $pi = $existingItemMap[$piId];
              if (isset($prodMap[$pi->product_id])) {
                $prodName = $prodMap[$pi->product_id]->name;
              }
            }
            $errors[] = "For product \"$prodName\", received quantity (".$it['qty'].") cannot be less than already used quantity (".$ded.").";
          }
        }
      }
    }
  }
  // --------- END EXTRA VALIDATION FOR EDIT MODE -------------------------

  if (count($errors) == 0) {

    if ($is_edit) {
      // Update header
      PurchaseSetup::UpdatePurchase($purchase_id, [
        'supplier_id'  => $supplier_id,
        'po_number'    => $po_number,
        'date'         => $date,
        'remarks'      => $remarks,
        'total_amount' => $line_total,
        'datetime'     => 'NOW()'
      ]);

      global $db;

      // 1) Delete fully removed lines (no deducted stock, already validated above)
      if (!empty($removedIds)) {
        $idsStr = implode(',', array_map('intval', $removedIds));
        if ($idsStr !== '') {
          $db->query("DELETE FROM ".TABLE_STOCK." WHERE purchase_item_id IN ($idsStr)");
          $db->query("DELETE FROM ".TABLE_PURCHASE_ITEM." WHERE id IN ($idsStr)");
        }
      }

      // 2) Update existing items and their stock in-place
      foreach ($items as $it) {
        if ($it['mode'] === 'existing') {
          $piId = (int)$it['item_id'];
          $pid  = (int)$it['product_id'];
          $qty  = (int)$it['qty'];
          $uc   = (float)$it['unit_cost'];
          $batch_no    = $it['batch_no'];
          $expiry_date = $it['expiry_date'];

          $batchSql  = ($batch_no !== null && $batch_no !== '') ? "'".$batch_no."'" : "NULL";
          $expirySql = ($expiry_date !== null && $expiry_date !== '') ? "'".$expiry_date."'" : "NULL";

          // Update purchase_item row
          $db->query("
            UPDATE ".TABLE_PURCHASE_ITEM."
               SET qty = '".$qty."',
                   unit_cost = '".$uc."',
                   batch_no = $batchSql,
                   expiry_date = $expirySql
             WHERE id = '".$piId."'
          ");

          // Preserve deducted_qty, recompute remaining_qty
          $ded = 0;
          if (isset($stockByPurchaseItem[$piId])) {
            $ded = (int)$stockByPurchaseItem[$piId]->deducted_qty;
          }
          $remaining = $qty - $ded;
          if ($remaining < 0) $remaining = 0;

          $db->query("
            UPDATE ".TABLE_STOCK."
               SET product_id    = '".$pid."',
                   unit_cost     = '".$uc."',
                   received_qty  = '".$qty."',
                   deducted_qty  = '".$ded."',
                   remaining_qty = '".$remaining."',
                   batch_no      = $batchSql,
                   expiry_date   = $expirySql
             WHERE purchase_item_id = '".$piId."'
               AND purchase_id = '".$purchase_id."'
          ");
        }
      }

      // 3) Insert new items + their stock (normal behaviour)
      foreach ($items as $it) {
        if ($it['mode'] === 'new') {
          $piId = PurchaseSetup::AddPurchaseItem([
            'purchase_id' => $purchase_id,
            'product_id'  => $it['product_id'],
            'qty'         => $it['qty'],
            'unit_cost'   => $it['unit_cost'],
            'batch_no'    => $it['batch_no'],
            'expiry_date' => $it['expiry_date'],
            'datetime'    => 'NOW()'
          ]);

          Stock::AddStock([
            'purchase_id'      => $purchase_id,
            'purchase_item_id' => $piId,
            'product_id'       => $it['product_id'],
            'unit_cost'        => $it['unit_cost'],
            'received_qty'     => $it['qty'],
            'deducted_qty'     => 0,
            'remaining_qty'    => $it['qty'],
            'batch_no'         => $it['batch_no'],
            'expiry_date'      => $it['expiry_date'],
            'datetime'         => 'NOW()'
          ]);
        }
      }

      echo "<script>window.location.href='purchase_setup.php?view&sucess'</script>";
      exit;

    } else {
      // ADD MODE
      $header = [
        'supplier_id'  => $supplier_id,
        'po_number'    => $po_number,
        'date'         => $date,
        'remarks'      => $remarks,
        'total_amount' => $line_total,
        'status'       => 'posted',
        'datetime'     => 'NOW()'
      ];
      $newId = PurchaseSetup::AddPurchase($header);

      if ($newId) {
        foreach ($items as $it) {
          $piId = PurchaseSetup::AddPurchaseItem([
            'purchase_id' => $newId,
            'product_id'  => $it['product_id'],
            'qty'         => $it['qty'],
            'unit_cost'   => $it['unit_cost'],
            'batch_no'    => $it['batch_no'],
            'expiry_date' => $it['expiry_date'],
            'datetime'    => 'NOW()'
          ]);
          Stock::AddStock([
            'purchase_id'      => $newId,
            'purchase_item_id' => $piId,
            'product_id'       => $it['product_id'],
            'unit_cost'        => $it['unit_cost'],
            'received_qty'     => $it['qty'],
            'deducted_qty'     => 0,
            'remaining_qty'    => $it['qty'],
            'batch_no'         => $it['batch_no'],
            'expiry_date'      => $it['expiry_date'],
            'datetime'         => 'NOW()'
          ]);
        }
        echo "<script>window.location.href='purchase_setup.php?view&sucess'</script>";
        exit;
      } else {
        $output .= "<div id='card-alert' class='card orange lighten-5'><div class='card-content orange-text'><p>WARNING: Could not save purchase.</p></div></div>";
      }
    }

  } else {
    foreach ($errors as $e) {
      $output .= "<div id='card-alert' class='card orange lighten-5'><div class='card-content orange-text'><p>WARNING: $e</p></div></div>";
    }
  }
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <?php include('includes/inc_head.php'); ?>
  <style>
    table.striped input[type="number"],
    table.striped input[type="text"],
    table.striped input[type="date"] { margin: 0; height: 2.2rem; }
    tfoot td { font-weight: 600; }
    .right-align { text-align:right; }
    .product-name-small { font-size:12px;color:#777; }
  </style>
</head>
<body>
<div id="loader-wrapper"><div id="loader"></div><div class="loader-section section-left"></div><div class="loader-section section-right"></div></div>
<div id="container">
<?php include('includes/inc_top.php'); ?>
<div class="row">
<div class="col s12 m12">
  <h3><?php echo $is_edit ? "Edit Purchase" : "Add Purchase"; ?></h3>
  <hr>

  <div class="row">
    <form method="post" action="" id="purchase_form">
      <?php echo $output; ?>
      <div class="col s10">
        <div class="row margin">
          <div class="input-field col s6">
            <select name="supplier_id" id="supplier_id">
              <option value="">Select Supplier</option>
              <?php if ($supers) foreach ($supers as $s) {
                $sel = ($supplier_id == $s->id) ? "selected" : "";
                echo "<option value='{$s->id}' $sel>".htmlspecialchars($s->name)."</option>";
              } ?>
            </select>
            <label for="supplier_id">Supplier *</label>
          </div>
          <div class="input-field col s3">
            <input type="text" id="po_number" name="po_number" value="<?php echo htmlspecialchars($po_number); ?>">
            <label for="po_number">PO Number</label>
          </div>
          <div class="input-field col s3">
            <input type="date" id="date" name="date"
  value="<?php echo htmlspecialchars(($date && $date !== '0000-00-00') ? $date : ''); ?>">
<label class="active" for="date">Date *</label>
          </div>
        </div>

        <div class="row margin">
          <div class="input-field col s12">
            <textarea class="materialize-textarea" id="remarks" name="remarks"><?php echo htmlspecialchars($remarks); ?></textarea>
            <label for="remarks">Remarks</label>
          </div>
        </div>

        <div class="row">
          <div class="col s12">
            <table class="striped highlight" id="productsTable">
              <thead>
                <tr>
                  <th style="width:26%">Product</th>
                  <th style="width:10%" class="right-align">Carton/Bags(s)</th>
                  <th style="width:10%" class="right-align">Piece(s)</th>
                  <th style="width:10%" class="right-align">Dozen/Qty</th>
                  <th style="width:12%" class="right-align">Unit Cost</th>
                  <th style="width:12%" class="right-align">Line Total</th>
                  <th style="width:10%">Batch No</th>
                  <th style="width:10%">Expiry</th>
                  <th style="width:10%">Action</th>
                </tr>
              </thead>
              <tbody>
              <?php if ($is_edit) { ?>
                <!-- EDIT MODE: show only existing items -->
                <?php foreach ($existingItems as $it) {
                  $p = isset($prodMap[$it->product_id]) ? $prodMap[$it->product_id] : null;
                  $name = $p ? $p->name : ('#'.$it->product_id);
                  $cp   = isset($prodCP[$it->product_id]) ? $prodCP[$it->product_id] : 0;
                  // derive cartons/pieces from saved qty. To preserve exact qty, default pieces=qty, cartons=0
                  $pieces = (int)$it->qty;
                  $cartons = 0;
                ?>
                <tr>
                  <td>
                    <input type="hidden" name="item_id[]" value="<?php echo (int)$it->id; ?>">
                    <input type="hidden" name="product_id_existing[]" value="<?php echo (int)$it->product_id; ?>">
                    <input type="hidden" class="carton_pieces" value="<?php echo (int)$cp; ?>">
                    <?php echo htmlspecialchars($name); ?>
                    <?php if ($cp > 0) { ?>
                      <div class="product-name-small">(<?php echo $cp; ?> pcs/carton)</div>
                    <?php } ?>
                  </td>
                  <td class="right-align">
                    <input type="number" class="cartons input-field" name="cartons_existing[]" min="0" value="<?php echo $cartons; ?>" style="text-align:right;">
                  </td>
                  <td class="right-align">
                    <input type="number" class="pieces input-field" name="pieces_existing[]" min="0" value="<?php echo $pieces; ?>" style="text-align:right;">
                  </td>
                  <td class="right-align">
                    <input type="number" class="qty input-field" value="<?php echo (int)$it->qty; ?>" readonly style="text-align:right;">
                  </td>
                  <td class="right-align">
                    <input type="text" class="unit_cost input-field" name="unit_cost_existing[]" value="<?php echo number_format((float)$it->unit_cost, 2, '.', ''); ?>" style="text-align:right;">
                  </td>
                  <td class="right-align">
                    <input type="text" class="line_total input-field" value="<?php echo number_format(((float)$it->unit_cost * (int)$it->qty), 2, '.', ''); ?>" readonly style="text-align:right;">
                  </td>
                  <td>
                    <input type="text" name="batch_no_existing[]" value="<?php echo htmlspecialchars($it->batch_no); ?>">
                  </td>
                  <td>
                    <input type="date" name="expiry_date_existing[]" value="<?php echo htmlspecialchars($it->expiry_date); ?>">
                  </td>
                  <td>
                    <a class="btn-small red removeRow">x</a>
                  </td>
                </tr>
                <?php } ?>
              <?php } else { ?>
                <!-- ADD MODE: preload all products -->
                <?php if ($prods) foreach ($prods as $p) { ?>
                <tr>
                  <td>
                    <input type="hidden" name="product_id_new[]" value="<?php echo (int)$p->id; ?>">
                    <input type="hidden" class="carton_pieces" value="<?php echo (int)$p->carton_pieces; ?>">
                    <?php echo htmlspecialchars($p->name); ?>
                    <?php if ((int)$p->carton_pieces > 0) { ?>
                      <div class="product-name-small">(<?php echo (int)$p->carton_pieces; ?> pcs/carton)</div>
                    <?php } ?>
                  </td>
                  <td class="right-align">
                    <input type="number" class="cartons input-field" name="cartons_new[]" min="0" value="0" style="text-align:right;">
                  </td>
                  <td class="right-align">
                    <input type="number" class="pieces input-field" name="pieces_new[]" min="0" value="0" style="text-align:right;">
                  </td>
                  <td class="right-align">
                    <input type="number" class="qty input-field" value="0" readonly style="text-align:right;">
                  </td>
                  <td class="right-align">
                    <input type="text" class="unit_cost input-field" name="unit_cost_new[]" value="<?php echo number_format((float)$p->tp_rate, 2, '.', ''); ?>" style="text-align:right;">
                  </td>
                  <td class="right-align">
                    <input type="text" class="line_total input-field" value="0.00" readonly style="text-align:right;">
                  </td>
                  <td><input type="text" name="batch_no_new[]" value=""></td>
                  <td><input type="date" name="expiry_date_new[]" value=""></td>
                  <td></td>
                </tr>
                <?php } ?>
              <?php } ?>
              </tbody>
              <tfoot>
                <tr>
                  <td class="right-align">Totals:</td>
                  <td class="right-align"><span id="ft_total_cartons">0</span></td>
                  <td class="right-align"><span id="ft_total_pieces">0</span></td>
                  <td class="right-align"><span id="ft_total_qty">0</span></td>
                  <td></td>
                  <td class="right-align"><span id="ft_grand_total">0.00</span></td>
                  <td></td><td></td><td></td>
                </tr>
              </tfoot>
            </table>

            <?php if ($is_edit) { ?>
              <!-- Add new product row (only products not already in the purchase) -->
              <div class="card-panel">
                <div class="row">
                  <div class="input-field col s4">
                    <select id="add_product_select">
                      <option value="">Select Product to Add</option>
                      <?php
                      if ($prods) {
                        foreach ($prods as $p) {
                          if (!isset($existingProductIds[$p->id])) {
                            echo "<option value='{$p->id}' data-cp='".(int)$p->carton_pieces."' data-tp='".number_format((float)$p->tp_rate,2,'.','')."'>".htmlspecialchars($p->name)."</option>";
                          }
                        }
                      }
                      ?>
                    </select>
                    <label for="add_product_select">Add Product</label>
                  </div>
                  <div class="input-field col s2">
                    <button type="button" id="btnAddProduct" class="btn waves-effect waves-light">Add Row</button>
                  </div>
                </div>
              </div>
            <?php } ?>

          </div>
        </div>

        <div class="row margin">
  <div class="input-field col s12">
    <button id="btnsubmit" type="submit" class="btn waves-effect waves-light">Submit</button>
    <a href="purchase_setup.php?view" class="btn waves-effect waves-light">Cancel</a>
  </div>
</div>

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

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

<?php include('includes/inc_footer.php'); ?>
<?php include('includes/inc_js.php'); ?>
<script>
// Guard Materialize init for Rocket Loader
(function initM(){
  function go(){
    if (window.M && M.FormSelect) {
      try { M.FormSelect.init(document.querySelectorAll('select')); } catch(e){}
    }
  }
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', go); else go();
})();

document.addEventListener('DOMContentLoaded', function() {
  var form = document.getElementById('purchase_form');
  var btn  = document.getElementById('btnsubmit');

  // If backend sent an invalid date like 0000-00-00, clear it so HTML5 doesn't block
  (function normalizeDate(){
    var d = document.getElementById('date');
    if (d && (d.value === '0000-00-00' || d.value === '0000-00-00T00:00:00')) d.value = '';
  })();

  // Custom validation for Materialize select + date
  function validateForm(){
    var supplier = document.getElementById('supplier_id');
    var dateEl   = document.getElementById('date');

    // Supplier required (do NOT use native required on Materialize select)
    if (!supplier || !supplier.value) {
      if (window.M && M.toast) M.toast({html: 'Please select supplier'});
      // Focus the visible dropdown input
      var wrapper = supplier && supplier.closest('.select-wrapper');
      var vis = wrapper && wrapper.querySelector('input.select-dropdown');
      if (vis) vis.focus();
      return false;
    }

    // Date required & must match yyyy-mm-dd
    if (!dateEl || !dateEl.value) {
      if (window.M && M.toast) M.toast({html: 'Please select date'});
      if (dateEl) dateEl.focus();
      return false;
    }
    // Simple pattern check (extra safety)
    if (!/^\d{4}-\d{2}-\d{2}$/.test(dateEl.value)) {
      if (window.M && M.toast) M.toast({html: 'Invalid date format'});
      dateEl.focus();
      return false;
    }

    return true;
  }

  // Use NORMAL form submit; just validate first and debounce button
  if (form && btn) {
    form.addEventListener('submit', function(e){
      if (!validateForm()) {
        e.preventDefault();
        return;
      }
      btn.disabled = true;
      setTimeout(function(){ btn.disabled = false; }, 3000);
    });
  }

  // ------- Totals / live math -------
  function toNum(v){ var n = parseFloat(v); return isNaN(n) ? 0 : n; }
  function fmt(v){ return toNum(v).toFixed(2); }

  function recalcRow(tr){
    var cartons      = toNum(tr.querySelector('.cartons')?.value || 0);
    var pieces       = toNum(tr.querySelector('.pieces')?.value || 0);
    var cp           = toNum(tr.querySelector('.carton_pieces')?.value || 0);
    var unitCost     = toNum(tr.querySelector('.unit_cost')?.value || 0);

    var qty = (cartons * cp) + pieces;
    if (tr.querySelector('.qty')) tr.querySelector('.qty').value = qty;

    var lineTotal = unitCost * qty;
    if (tr.querySelector('.line_total')) tr.querySelector('.line_total').value = fmt(lineTotal);
  }

  function recalcFooter(){
    var rows = document.querySelectorAll('#productsTable tbody tr');
    var tCartons = 0, tPieces = 0, tQty = 0, gTotal = 0;
    rows.forEach(function(tr){
      tCartons += toNum(tr.querySelector('.cartons')?.value || 0);
      tPieces  += toNum(tr.querySelector('.pieces')?.value || 0);
      tQty     += toNum(tr.querySelector('.qty')?.value || 0);
      gTotal   += toNum(tr.querySelector('.line_total')?.value || 0);
    });
    document.getElementById('ft_total_cartons').innerText = tCartons;
    document.getElementById('ft_total_pieces').innerText  = tPieces;
    document.getElementById('ft_total_qty').innerText     = tQty;
    document.getElementById('ft_grand_total').innerText   = fmt(gTotal);
  }

  // Mutual-exclusive cartons/pieces + live recalcs
  var tbody = document.querySelector('#productsTable tbody');
  if (tbody) {
    tbody.addEventListener('input', function(e){
      if (e.target.classList.contains('cartons') || e.target.classList.contains('pieces') || e.target.classList.contains('unit_cost')) {
        var tr = e.target.closest('tr');
        if (e.target.classList.contains('cartons')) {
          var c = toNum(e.target.value);
          if (c > 0) { var pe = tr.querySelector('.pieces'); if (pe) pe.value = 0; }
        } else if (e.target.classList.contains('pieces')) {
          var p = toNum(e.target.value);
          if (p > 0) { var ce = tr.querySelector('.cartons'); if (ce) ce.value = 0; }
        }
        recalcRow(tr);
        recalcFooter();
      }
    });

    // Remove row (edit mode / dynamic rows)
    tbody.addEventListener('click', function(e){
      if (e.target.classList.contains('removeRow')) {
        var tr = e.target.closest('tr');
        tr.parentNode.removeChild(tr);
        recalcFooter();
      }
    });
  }

  // Add new product row (edit mode)
  var addBtn = document.getElementById('btnAddProduct');
  if (addBtn) {
    addBtn.addEventListener('click', function(){
      var sel = document.getElementById('add_product_select');
      var pid = sel ? sel.value : '';
      if (!pid) return;
      var name = sel.options[sel.selectedIndex].text;
      var cp   = sel.options[sel.selectedIndex].getAttribute('data-cp') || "0";
      var tp   = sel.options[sel.selectedIndex].getAttribute('data-tp') || "0.00";

      var tr = document.createElement('tr');
      tr.innerHTML = `
        <td>
          <input type="hidden" name="product_id_new[]" value="${pid}">
          <input type="hidden" class="carton_pieces" value="${cp}">
          ${name}
          ${parseInt(cp)>0 ? `<div class="product-name-small">(${cp} pcs/carton)</div>` : ``}
        </td>
        <td class="right-align"><input type="number" class="cartons input-field" name="cartons_new[]" min="0" value="0" style="text-align:right;"></td>
        <td class="right-align"><input type="number" class="pieces input-field" name="pieces_new[]" min="0" value="0" style="text-align:right;"></td>
        <td class="right-align"><input type="number" class="qty input-field" value="0" readonly style="text-align:right;"></td>
        <td class="right-align"><input type="text" class="unit_cost input-field" name="unit_cost_new[]" value="${tp}" style="text-align:right;"></td>
        <td class="right-align"><input type="text" class="line_total input-field" value="0.00" readonly style="text-align:right;"></td>
        <td><input type="text" name="batch_no_new[]" value=""></td>
        <td><input type="date" name="expiry_date_new[]" value=""></td>
        <td><a class="btn-small red removeRow">x</a></td>
      `;
      if (tbody) tbody.appendChild(tr);

      // remove the option so it can't be added twice
      sel.remove(sel.selectedIndex);
      if (window.M && M.FormSelect) M.FormSelect.init(sel);

      recalcRow(tr);
      recalcFooter();
    });
  }

  // Initial compute
  document.querySelectorAll('#productsTable tbody tr').forEach(recalcRow);
  recalcFooter();
});
</script>


</body>
</html>
