<?php require_once __DIR__ . '/../includes/auth.php'; require_login(); $isSuperAdmin = has_role(['super_admin']); $isAdmin = has_role(['admin','super_admin']); ?>
<div class="page-sales">
  <div class="container-fluid p-4">
    <input type="hidden" id="csrf" value="<?php echo htmlspecialchars(csrf_token()); ?>" />
    <input type="hidden" id="isSuperAdmin" value="<?php echo $isSuperAdmin ? '1' : '0'; ?>" />
    <input type="hidden" id="isAdmin" value="<?php echo $isAdmin ? '1' : '0'; ?>" />
    <input type="hidden" id="userBranchId" value="<?php echo htmlspecialchars($_SESSION['branch_id'] ?? ''); ?>" />
    <!-- Removed top tabs; showing invoices content directly -->
    <div>

<!-- Pick Cut Piece Modal -->
<div class="modal fade" id="cutPickModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Pick Cut Piece</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div class="d-flex justify-content-between align-items-center mb-2">
          <div class="small text-muted">Showing available cut pieces from Slab Cutting inventory</div>
          <div class="d-flex gap-2">
            <button class="btn btn-sm btn-outline-secondary" id="btnReloadCutPieces"><i class="bi bi-arrow-clockwise"></i></button>
            <button class="btn btn-sm btn-primary" id="btnAddSelectedCut">Add Selected</button>
          </div>
        </div>
        <div class="table-responsive">
          <table class="table table-hover align-middle" id="cutPickTable">
            <thead><tr><th><input type="checkbox" id="cutPickAll"></th><th>ID</th><th>Job</th><th>Piece</th><th>Size (mm)</th><th>Area (sqft)</th></tr></thead>
            <tbody></tbody>
          </table>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
  </div>

<!-- Quick Pick Modal (FP/Cut/Prod) -->
<div class="modal fade" id="quickPickModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-scrollable">
    <div class="modal-content">
      <div class="modal-header"><h5 class="modal-title" id="qp_title">Pick Item</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div>
      <div class="modal-body">
        <div class="input-group mb-2">
          <input type="text" id="qp_search" class="form-control" placeholder="Search...">
          <button type="button" class="btn btn-outline-secondary" id="qp_btn_search"><i class="bi bi-search"></i></button>
        </div>
        <div class="table-responsive">
          <table class="table table-sm align-middle" id="qp_table"><thead><tr id="qp_head"></tr></thead><tbody></tbody></table>
        </div>
      </div>
      <div class="modal-footer"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button><button type="button" class="btn btn-primary" id="qp_use">Use Selected</button></div>
    </div>
  </div>
</div>

<!-- Final Product Details / Re-measure Modal -->
<div class="modal fade" id="fpDetailModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-scrollable">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Final Product Details</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <form id="fpDetailForm">
        <div class="modal-body">
          <input type="hidden" name="csrf" value="<?php echo htmlspecialchars(csrf_token()); ?>">
          <input type="hidden" name="id" id="fp_id">
          <div class="row g-3">
            <div class="col-md-6">
              <div class="border rounded p-2 h-100">
                <div class="fw-semibold mb-2">Before Polishing</div>
                <div class="small text-muted">From polishing job/raw material</div>
                <div>Slab No: <span id="fp_slab"></span></div>
                <div>Polisher: <span id="fp_worker"></span></div>
                <div>Start: <span id="fp_start"></span></div>
                <div>End: <span id="fp_end"></span></div>
                <div>Pre Size: <span id="fp_pre_h"></span> x <span id="fp_pre_l"></span></div>
                <div>PO: <span id="fp_po"></span></div>
              </div>
            </div>
            <div class="col-md-6">
              <div class="border rounded p-2 h-100">
                <div class="fw-semibold mb-2">After Polishing (Editable)</div>
                <div class="row g-2">
                  <div class="col-6"><label class="form-label">Final Height</label><input type="number" step="0.001" class="form-control" name="final_height" id="fp_final_h"></div>
                  <div class="col-6"><label class="form-label">Final Length</label><input type="number" step="0.001" class="form-control" name="final_length" id="fp_final_l"></div>
                  <div class="col-12"><label class="form-label">Finish</label><select class="form-select" name="finish_id" id="fp_finish"></select></div>
                  <div class="col-12"><label class="form-label">Quality</label><input type="text" class="form-control" name="quality" id="fp_quality"></div>
                  <div class="col-12 small text-muted">Sq.Ft auto from HxL</div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
          <button type="submit" class="btn btn-primary">Save</button>
        </div>
      </form>
    </div>
  </div>
</div>

<style>
  /* Ensure the invoice modal body scrolls so footer stays visible */
  #invoiceModal .modal-body{ max-height: calc(100vh - 200px); overflow:auto; }
  /* Improve touch targets inside modal */
  /* Smaller, consistent controls inside cart table */
  #invoiceModal #cartm-table .form-control,
  #invoiceModal #cartm-table .form-select { min-height: 32px; font-size: 0.9rem; padding: .25rem .5rem; }
  #invoiceModal #cartm-table td, #invoiceModal #cartm-table th { font-size: 0.9rem; }
  #invoiceModal #cartm-table .cart-line, #invoiceModal #cartm-table .cart-area { font-size: 0.9rem; }
  /* Prevent table header from jumping */
  #invoiceModal .table thead th { position: sticky; top: 0; background: #fff; z-index: 1; }
  /* Fix modal z-index to ensure item picker appears on top */
  .modal { z-index: 1055; }
  .modal-backdrop { z-index: 1050; }
  /* Quick pick modal should be on top when opened */
  #quickPickModal { z-index: 1060; }
  #quickPickModal ~ .modal-backdrop { z-index: 1055; }
  /* Cut pick modal should be on top when opened */
  #cutPickModal { z-index: 1060; }
  #cutPickModal ~ .modal-backdrop { z-index: 1055; }
</style>
      <!-- Invoices -->
      <div id="tab-invoices">
        <div class="d-flex justify-content-between align-items-center mb-2">
          <h4 class="mb-0">Invoices</h4>
          <div class="d-flex gap-2 align-items-center flex-wrap justify-content-end">
            <div class="btn-group btn-group-sm">
              <button class="btn btn-outline-secondary inv-filter active" data-status="">All</button>
              <button class="btn btn-outline-secondary inv-filter" data-status="draft">Draft</button>
              <button class="btn btn-outline-secondary inv-filter" data-status="issued">Issued</button>
              <button class="btn btn-outline-secondary inv-filter" data-status="paid">Paid</button>
            </div>
            <button id="btnCreateInvoice" class="btn btn-primary btn-sm"><i class="bi bi-receipt"></i> Create Invoice</button>
          </div>
        </div>
        <div class="d-flex gap-2 align-items-center flex-wrap mb-3">
          <input type="text" id="invSearch" class="form-control form-control-sm" placeholder="Search invoice no" style="max-width: 180px;">
          <input type="hidden" id="invCustomerFilterId" value="">
          <input type="text" id="invCustomerFilterText" class="form-control form-control-sm" style="max-width: 180px;" placeholder="Customer" list="invCustomerFilterList" autocomplete="off">
          <datalist id="invCustomerFilterList"></datalist>
          <select id="invBranchFilter" class="form-select form-select-sm" style="max-width: 160px;"><option value="">All Branches</option></select>
          <select id="invPayTermList" class="form-select form-select-sm" style="max-width: 140px;">
            <option value="">All Terms</option>
            <option value="Cash">Cash</option>
            <option value="Credit">Credit</option>
            <option value="Cheque">Cheque</option>
          </select>
          <select id="invDatePreset" class="form-select form-select-sm" style="max-width: 160px;">
            <option value="custom">Custom Range</option>
            <option value="daily">Daily</option>
            <option value="monthly" selected>Monthly</option>
            <option value="yearly">Yearly</option>
          </select>
          <input type="date" id="invDateFrom" class="form-control form-control-sm" style="max-width: 160px;" placeholder="From">
          <input type="date" id="invDateTo" class="form-control form-control-sm" style="max-width: 160px;" placeholder="To">
          <button type="button" class="btn btn-outline-secondary btn-sm" id="btnInvSearchGo"><i class="bi bi-search"></i></button>
        </div>
        <div class="row g-2 mb-3" id="salesKpis">
          <div class="col-6 col-md-3">
            <div class="p-3 rounded-3 bg-light border">
              <div class="small text-muted">Sales Quantity (SQF)</div>
              <div class="fs-4" id="sk_qty">0</div>
            </div>
          </div>
          <div class="col-6 col-md-3">
            <div class="p-3 rounded-3 bg-light border">
              <div class="small text-muted">Sales Value</div>
              <div class="fs-4" id="sk_value">LKR 0.00</div>
            </div>
          </div>
          <div class="col-6 col-md-3">
            <div class="p-3 rounded-3 bg-light border">
              <div class="small text-muted">Paid Amount</div>
              <div class="fs-4" id="sk_paid">LKR 0.00</div>
            </div>
          </div>
          <div class="col-6 col-md-3">
            <div class="p-3 rounded-3 bg-light border">
              <div class="small text-muted">Outstanding Amount</div>
              <div class="fs-4" id="sk_outstanding">LKR 0.00</div>
            </div>
          </div>
        </div>
        <div class="card shadow-sm"><div class="card-body">
          <div class="table-responsive">
            <table id="invoices-table" class="table table-hover align-middle">
              <thead>
                <tr>
                  <th>No</th><th>Date</th><th>Customer</th><th>Status</th><th>Payment Term</th><th class="text-end">Total (LKR)</th><th class="text-end">Balance (LKR)</th><th>Actions</th>
                </tr>
              </thead>
              <tbody></tbody>
            </table>
          </div>
        </div></div>
      </div>

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

<!-- Invoice View & Payments Modal -->
<div class="modal fade" id="invoiceViewModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-scrollable">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Invoice</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div class="d-flex justify-content-between align-items-start mb-2">
          <div>
            <div class="fw-semibold" id="iv_no">INV-</div>
            <div class="small text-muted" id="iv_date">Date</div>
            <div class="small"><span class="badge bg-secondary" id="iv_status">status</span></div>
          </div>
          <div class="text-end">
            <div class="fw-semibold" id="iv_customer">Customer</div>
            <div class="small" id="iv_address"></div>
            <div class="small" id="iv_contact"></div>
          </div>
        </div>
        <div class="table-responsive mb-2">
          <table class="table table-sm align-middle" id="iv_items">
            <thead><tr><th>Description</th><th class="text-end">Qty</th><th class="text-end">Unit (LKR)</th><th class="text-end">Line (LKR)</th><th>Actions</th></tr></thead>
            <tbody></tbody>
          </table>
        </div>
        <div class="d-flex justify-content-end">
          <div style="min-width:300px">
            <div class="d-flex justify-content-between"><div>Subtotal</div><div id="iv_subtotal">LKR 0.00</div></div>
            <div class="d-flex justify-content-between"><div>Tax (<span id="iv_taxp">0</span>%)</div><div id="iv_tax">LKR 0.00</div></div>
            <div class="d-flex justify-content-between"><div>Discount</div><div id="iv_disc">LKR 0.00</div></div>
            <div class="d-flex justify-content-between fw-semibold"><div>Total</div><div id="iv_total">LKR 0.00</div></div>
            <hr class="my-2">
            <div class="d-flex justify-content-between"><div>Paid</div><div id="iv_paid">LKR 0.00</div></div>
            <div class="d-flex justify-content-between fw-semibold"><div>Balance</div><div id="iv_balance">LKR 0.00</div></div>
          </div>
        </div>
        <hr>
        <div class="d-flex justify-content-between align-items-center mb-2">
          <h6 class="mb-0">Payments</h6>
          <button class="btn btn-sm btn-primary" id="btnAddPaymentOpen">Add Payment</button>
        </div>
        <div class="table-responsive">
          <table class="table table-sm" id="iv_payments">
            <thead><tr><th>Date</th><th>Method</th><th>Ref</th><th class="text-end">Amount (LKR)</th></tr></thead>
            <tbody></tbody>
          </table>
        </div>
      </div>
      <div class="modal-footer">
        <div class="me-auto d-flex flex-wrap gap-2">
          <button type="button" class="btn btn-outline-primary" id="btnAddItem">Add Item</button>
          <button type="button" class="btn btn-outline-danger" id="btnDeleteInvoice" style="display:none;">Delete Invoice</button>
        </div>
        <a href="#" target="_blank" id="btnPrintInvoice" class="btn btn-outline-secondary">Print</a>
        <button type="button" class="btn btn-outline-secondary" id="btnIssueInvoice">Issue</button>
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

<!-- Add Payment Modal -->
<div class="modal fade" id="paymentModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Add Payment</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <form id="paymentForm">
        <div class="modal-body">
          <input type="hidden" name="csrf" value="<?php echo htmlspecialchars(csrf_token()); ?>">
          <input type="hidden" name="invoice_id" id="pay_invoice_id">
          <div class="row g-2">
            <div class="col-md-6">
              <label class="form-label">Date</label>
              <input type="date" class="form-control" name="pay_date" id="pay_date" required>
            </div>
            <div class="col-md-6">
              <label class="form-label">Method</label>
              <select class="form-select" name="method" id="pay_method" required>
                <option value="Cash">Cash</option>
                <option value="Bank Transfer">Bank Transfer</option>
                <option value="Cheque">Cheque</option>
                <option value="Online">Online</option>
                <option value="Credit">Credit</option>
              </select>
            </div>
            <div class="col-12" id="pay_bank_account_row">
              <label class="form-label">Bank Account <span class="text-danger">*</span></label>
              <select class="form-select" name="bank_account_id" id="pay_bank_account_id">
                <option value="">-- Select Bank Account --</option>
              </select>
            </div>
            <div class="col-md-6">
              <label class="form-label">Amount (LKR)</label>
              <input type="number" step="0.01" class="form-control" name="amount" id="pay_amount" required>
              <div class="form-text">Balance: <span id="pay_balance">LKR 0.00</span></div>
            </div>
            <div class="col-md-6">
              <label class="form-label">Reference</label>
              <input type="text" class="form-control" name="reference_no" id="pay_ref">
            </div>
            <div class="col-12">
              <label class="form-label">Notes</label>
              <input type="text" class="form-control" name="notes" id="pay_notes">
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
          <button type="submit" class="btn btn-primary">Save Payment</button>
        </div>
      </form>
    </div>
  </div>
</div>
<!-- Create Invoice Modal (Unified) -->
<div class="modal fade" id="invoiceModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-xl modal-dialog-scrollable modal-fullscreen-lg-down">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Create Invoice</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <form id="invoiceForm">
        <div class="modal-body fs-6" id="invoiceModalBody">
          <input type="hidden" name="csrf" value="<?php echo htmlspecialchars(csrf_token()); ?>">
          <input type="hidden" id="invAction" name="_action" value="create">
          <input type="hidden" id="invId" name="id" value="">
          <div class="alert alert-info py-2 mb-2">
            <small class="text-muted">Invoice No:</small>
            <strong id="invNoPreview">Loading...</strong>
            <small class="text-muted">(Branch: <?php echo htmlspecialchars($_SESSION['branch_name'] ?? 'Main'); ?>)</small>
          </div>
          <div class="row g-2">
            <div class="col-md-6">
              <label class="form-label">Customer</label>
              <select class="form-select form-select-lg" name="customer_id" id="invCustomer" required></select>
            </div>
            <div class="col-md-6 d-flex align-items-end">
              <button type="button" class="btn btn-outline-secondary btn-lg w-100" id="invAddCustomer" data-bs-toggle="modal" data-bs-target="#customerModal">Add New Customer</button>
            </div>
            <div class="col-md-4">
              <label class="form-label">Date</label>
              <input type="date" class="form-control form-control-lg" name="invoice_date" id="invDate" required>
            </div>
            <div class="col-md-4">
              <label class="form-label">Payment Term</label>
              <select class="form-select form-select-lg" name="payment_term" id="invPayTerm">
                <option value=""></option>
              </select>
            </div>
            <div class="col-md-4" id="invBankAccountTopRow" style="display:none;">
              <label class="form-label">Bank Account <span class="text-danger">*</span></label>
              <select class="form-select form-select-lg" name="bank_account_id" id="invBankAccountId">
                <option value="">-- Select Bank Account --</option>
              </select>
            </div>
            <div class="col-md-4">
              <label class="form-label">Status</label>
              <select class="form-select form-select-lg" name="status" id="invStatus">
                <option value="draft">Draft (Temporary)</option>
                <option value="issued">Issue Now</option>
              </select>
            </div>
            <?php if (has_role(['admin','super_admin'])): ?>
            <div class="col-md-6">
              <label class="form-label">Branch (Final Products)</label>
              <select class="form-select form-select-lg" id="invBranchFilter">
                <?php if (!empty($_SESSION['branch_id'])): ?>
                  <option value="<?php echo (int)$_SESSION['branch_id']; ?>" selected><?php echo htmlspecialchars($_SESSION['branch_name'] ?? ('Branch #'.(int)$_SESSION['branch_id'])); ?></option>
                <?php else: ?>
                  <option value="">All Branches</option>
                <?php endif; ?>
              </select>
            </div>
            <?php endif; ?>
          </div>
          <hr>
          <ul class="nav nav-pills mb-2" id="invPickTabs" role="tablist">
            <li class="nav-item"><button class="nav-link active" data-bs-toggle="tab" data-bs-target="#pickFP" type="button" role="tab">Pick Final Products</button></li>
            <li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#pickCut" type="button" role="tab">Pick Cut Pieces</button></li>
            <li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#pickProd" type="button" role="tab">Pick Production Items</button></li>
            <li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#pickSvc" type="button" role="tab">Services</button></li>
          </ul>
          <div class="tab-content border rounded p-2 mb-2" style="max-height:320px; overflow:auto;">
            <div class="tab-pane fade show active" id="pickFP" role="tabpanel">
              <div class="d-flex gap-2 mb-2">
                <input type="text" id="fpModalSearch" class="form-control" placeholder="Search final products">
                <button type="button" class="btn btn-outline-secondary" id="btnFpModalSearch"><i class="bi bi-search"></i></button>
              </div>
              <div class="table-responsive">
                <table class="table table-sm align-middle" id="fpModalTable"><thead><tr><th>PO No</th><th>Slab</th><th>Finish</th><th>Type</th><th>Color</th><th>H</th><th>L</th><th>Sq.Ft</th><th></th></tr></thead><tbody></tbody></table>
              </div>
            </div>
            <div class="tab-pane fade" id="pickCut" role="tabpanel">
              <div class="row g-2 mb-2">
                <div class="col-md-4"><input type="text" id="cutSearch" class="form-control" placeholder="Search by ID or Job ID"></div>
                <div class="col-md-4"><input type="text" id="cutSlabSearch" class="form-control" placeholder="Search by Slab No"></div>
                <div class="col-md-4 d-flex gap-2">
                  <button type="button" class="btn btn-outline-secondary" id="btnCutSearch"><i class="bi bi-search"></i></button>
                  <button type="button" class="btn btn-outline-secondary" id="btnReloadCutPiecesM" title="Reload"><i class="bi bi-arrow-clockwise"></i></button>
                  <button type="button" class="btn btn-primary" id="btnAddSelectedCutM">Add Selected</button>
                </div>
              </div>
              <div class="row g-2 mb-2">
                <div class="col-md-3"><input type="number" step="1" id="cutLenMin" class="form-control" placeholder="Len min (mm)"></div>
                <div class="col-md-3"><input type="number" step="1" id="cutLenMax" class="form-control" placeholder="Len max (mm)"></div>
                <div class="col-md-3"><input type="number" step="1" id="cutWidMin" class="form-control" placeholder="Wid min (mm)"></div>
                <div class="col-md-3"><input type="number" step="1" id="cutWidMax" class="form-control" placeholder="Wid max (mm)"></div>
              </div>
              <div class="table-responsive">
                <table class="table table-sm align-middle" id="cutPickTableM"><thead><tr><th><input type="checkbox" id="cutPickAllM"></th><th>ID</th><th>Job</th><th>Piece</th><th>Slab</th><th>PO No</th><th>Size (mm)</th><th>Area (sqft)</th></tr></thead><tbody></tbody></table>
              </div>
            </div>
            <div class="tab-pane fade" id="pickProd" role="tabpanel">
              <div class="row g-2 mb-2">
                <div class="col-md-3"><label class="form-label">Type</label><select id="prodPickType" class="form-select"><option value="">All</option></select></div>
                <div class="col-md-3"><label class="form-label">Quality</label><select id="prodPickQuality" class="form-select"><option value="">All</option></select></div>
                <div class="col-md-3"><label class="form-label">Availability</label>
                  <select id="prodPickAvail" class="form-select"><option value="available">Available</option><option value="reserved">Reserved</option><option value="sold">Sold</option><option value="">All</option></select>
                </div>
                <div class="col-md-3"><label class="form-label">Search</label>
                  <div class="input-group">
                    <input type="text" id="prodPickSearch" class="form-control" placeholder="Notes contains...">
                    <button type="button" class="btn btn-outline-secondary" id="btnProdSearchM"><i class="bi bi-search"></i></button>
                  </div>
                </div>
              </div>
              <div class="d-flex gap-2 mb-2">
                <button type="button" class="btn btn-outline-secondary" id="btnReloadProdM" title="Reload"><i class="bi bi-arrow-clockwise"></i></button>
                <button type="button" class="btn btn-primary" id="btnAddSelectedProdM">Add Selected</button>
              </div>
              <div class="table-responsive">
                <table class="table table-sm align-middle" id="prodPickTableM"><thead><tr><th><input type="checkbox" id="prodPickAllM"></th><th>ID</th><th>Name</th><th>Type</th><th>Color</th><th>Finish</th><th class="text-end">L</th><th class="text-end">W</th><th class="text-end">T</th><th class="text-end">Qty</th><th>Avail</th><th>Notes</th></tr></thead><tbody></tbody></table>
              </div>
            </div>
            <div class="tab-pane fade" id="pickSvc" role="tabpanel">
              <div class="row g-2 align-items-end">
                <div class="col-md-4">
                  <label class="form-label">Service</label>
                  <select class="form-select" id="svcPickSelect"></select>
                </div>
                <div class="col-md-2">
                  <label class="form-label">Unit</label>
                  <select class="form-select" id="svcPickUnit">
                    <option value="ft" selected>FT</option>
                    <option value="pcs">PCS</option>
                  </select>
                </div>
                <div class="col-md-2">
                  <label class="form-label">Qty</label>
                  <input type="number" step="0.001" min="0" class="form-control" id="svcPickQty" placeholder="0">
                </div>
                <div class="col-md-2">
                  <label class="form-label">Unit Price (LKR)</label>
                  <input type="number" step="0.01" min="0" class="form-control" id="svcPickRate" placeholder="0">
                </div>
                <div class="col-md-2 d-grid">
                  <button type="button" class="btn btn-primary" id="btnAddServiceM">Add</button>
                </div>
                <div class="col-12">
                  <label class="form-label">Description</label>
                  <input type="text" class="form-control" id="svcPickDesc" placeholder="Description for invoice">
                </div>
              </div>
            </div>
          </div>
          <div class="table-responsive small">
            <table class="table table-sm" id="cartm-table">
              <thead><tr><th>Item</th><th style="width:90px">Unit</th><th class="text-end" style="width:100px">Area</th><th class="text-end" style="width:90px">Qty</th><th class="text-end" style="width:110px">Rate</th><th class="text-end" style="width:110px">Total</th><th style="width:40px"></th></tr></thead>
              <tbody></tbody>
            </table>
          </div>
          <div class="row g-2 mt-2">
            <div class="col-md-4">
              <label class="form-label">Tax %</label>
              <input type="number" step="0.01" class="form-control form-control-lg" name="tax_percent" id="invTax" value="0">
            </div>
            <div class="col-md-4">
              <label class="form-label">Discount %</label>
              <input type="number" step="0.01" class="form-control form-control-lg" name="discount_percent" id="invDiscountP" value="0">
            </div>
            <div class="col-md-4">
              <label class="form-label">Discount (LKR)</label>
              <input type="number" step="0.01" class="form-control form-control-lg" name="discount" id="invDiscount" value="0">
              <div class="form-text">If both are provided, % is used.</div>
            </div>
            <div class="col-md-4">
              <label class="form-label">Transport Charges (LKR)</label>
              <input type="number" step="0.01" class="form-control form-control-lg" name="transport_charges" id="invTransport" value="0">
            </div>
            <div class="col-md-4">
              <label class="form-label">Advance Payment (LKR)</label>
              <input type="number" step="0.01" class="form-control form-control-lg" name="advance_amount" id="invAdvance" value="0">
            </div>
            <div class="col-12">
              <label class="form-label">Notes</label>
              <input type="text" class="form-control form-control-lg" name="notes" id="invNotes">
            </div>
          </div>
          <div class="d-flex justify-content-end mt-2">
            <div style="min-width:300px">
              <div class="d-flex justify-content-between"><div>Subtotal</div><div id="cartmSubtotal">LKR 0.00</div></div>
              <div class="d-flex justify-content-between"><div>Tax</div><div id="cartmTax">LKR 0.00</div></div>
              <div class="d-flex justify-content-between"><div>Transport</div><div id="cartmTransport">LKR 0.00</div></div>
              <div class="d-flex justify-content-between"><div>Discount</div><div id="cartmDisc">LKR 0.00</div></div>
              <div class="d-flex justify-content-between fw-semibold"><div>Total</div><div id="cartmTotal">LKR 0.00</div></div>
              <hr class="my-2">
              <div class="d-flex justify-content-between"><div>Advance</div><div id="cartmAdvance">LKR 0.00</div></div>
              <div class="d-flex justify-content-between fw-semibold"><div>Balance</div><div id="cartmBalance">LKR 0.00</div></div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary btn-lg" data-bs-dismiss="modal">Close</button>
          <button type="submit" class="btn btn-success btn-lg">Save Invoice</button>
        </div>
      </form>
    </div>
  </div>
</div>

<!-- Customer Modal -->
<div class="modal fade" id="customerModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Customer</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <form id="customerForm">
        <div class="modal-body">
          <input type="hidden" name="csrf" value="<?php echo htmlspecialchars(csrf_token()); ?>">
          <input type="hidden" name="id" id="custId">
          <input type="hidden" name="action" id="custAction" value="create">
          <div class="row g-2">
            <div class="col-md-6">
              <label class="form-label">Customer Name *</label>
              <input type="text" class="form-control" name="name" id="custName" required>
            </div>
            <div class="col-md-6">
              <label class="form-label">Company Name</label>
              <input type="text" class="form-control" name="company_name" id="custCompany">
            </div>
          </div>
          <div class="row g-2 mt-0">
            <div class="col-md-6">
              <label class="form-label">Email Address</label>
              <input type="email" class="form-control" name="email" id="custEmail">
            </div>
            <div class="col-md-6">
              <label class="form-label">Phone Number</label>
              <input type="text" class="form-control" name="phone" id="custPhone">
            </div>
          </div>
          <div class="mb-2">
            <label class="form-label">Address</label>
            <textarea class="form-control" name="address" id="custAddress" rows="2"></textarea>
          </div>
          <div class="row g-2 mt-0">
            <div class="col-md-4">
              <label class="form-label">City</label>
              <input type="text" class="form-control" name="city" id="custCity">
            </div>
            <div class="col-md-4">
              <label class="form-label">State</label>
              <input type="text" class="form-control" name="state" id="custState">
            </div>
            <div class="col-md-4">
              <label class="form-label">Country</label>
              <input type="text" class="form-control" name="country" id="custCountry" value="Sri Lanka">
            </div>
          </div>
          <div class="mb-2 mt-2">
            <label class="form-label">GST Number</label>
            <input type="text" class="form-control" name="gst_no" id="custGST" placeholder="e.g., 22AAAAA0000A1Z5">
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
          <button type="submit" class="btn btn-primary">Save</button>
        </div>
      </form>
    </div>
  </div>
</div>

<!-- Add/Edit Invoice Item Modal -->
<div class="modal fade" id="ivItemModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header"><h5 class="modal-title">Invoice Item</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div>
      <form id="ivItemForm">
        <div class="modal-body">
          <input type="hidden" name="csrf" value="<?php echo htmlspecialchars(csrf_token()); ?>">
          <input type="hidden" id="ivItemId" name="id">
          <input type="hidden" id="ivItemInvoiceId" name="invoice_id">
          <div class="mb-2">
            <label class="form-label">Link Type</label>
            <select class="form-select" id="ivItemType">
              <option value="manual">Manual</option>
              <option value="fp">Final Product</option>
              <option value="cut">Cut Piece</option>
              <option value="prod">Production Item</option>
            </select>
          </div>
          <div class="row g-2 mb-2">
            <div class="col-md-6">
              <label class="form-label">FP ID</label>
              <div class="input-group">
                <input type="number" class="form-control" id="ivItemFp">
                <button type="button" class="btn btn-outline-secondary" id="btnPickFp">Pick</button>
              </div>
            </div>
            <div class="col-md-6">
              <label class="form-label">Cut Piece ID</label>
              <div class="input-group">
                <input type="number" class="form-control" id="ivItemCut">
                <button type="button" class="btn btn-outline-secondary" id="btnPickCut">Pick</button>
              </div>
            </div>
            <div class="col-md-6">
              <label class="form-label">Production Item ID</label>
              <div class="input-group">
                <input type="number" class="form-control" id="ivItemProd">
                <button type="button" class="btn btn-outline-secondary" id="btnPickProd">Pick</button>
              </div>
            </div>
          </div>
          <div class="mb-2"><label class="form-label">Description</label><input type="text" class="form-control" id="ivItemDesc" required></div>
          <div class="row g-2 mb-2">
            <div class="col-md-6"><label class="form-label">Qty</label><input type="number" step="0.001" min="0" class="form-control" id="ivItemQty" required></div>
            <div class="col-md-6"><label class="form-label">Unit Price (LKR)</label><input type="number" step="0.01" min="0" class="form-control" id="ivItemPrice" required></div>
          </div>
        </div>
        <div class="modal-footer"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button><button type="submit" class="btn btn-primary">Save</button></div>
      </form>
    </div>
  </div>
  </div>

<!-- Return Item Modal -->
<div class="modal fade" id="returnItemModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Return Invoice Item</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <form id="returnItemForm">
        <div class="modal-body">
          <input type="hidden" name="csrf" value="<?php echo htmlspecialchars(csrf_token()); ?>">
          <input type="hidden" id="ret_item_id" name="item_id">
          <div class="mb-2">
            <label class="form-label">Quantity to Return</label>
            <input type="number" step="0.001" min="0.001" class="form-control" id="ret_qty" name="qty" required>
            <div class="form-text" id="ret_hint"></div>
          </div>
          <div class="mb-2">
            <label class="form-label">Reason</label>
            <input type="text" class="form-control" id="ret_reason" name="reason" placeholder="Damaged / Customer return / ...">
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
          <button type="submit" class="btn btn-primary">Process Return</button>
        </div>
      </form>
    </div>
  </div>
  </div>

<script>
(function($){
$(function(){
  if (!$('.page-sales').length) return;
  const fmt = n => Number(n||0).toLocaleString('en-LK',{style:'currency',currency:'LKR'});

  // ── Bank account helpers ─────────────────────────────────────────────────
  let _banksCache = null;
  function loadBankAccounts(cb) {
    if (_banksCache) { if (cb) cb(_banksCache); return; }
    $.get('api/finance.php', { action: 'list_bank_accounts', is_active: 1 }, function(res){
      _banksCache = res.data || [];
      if (cb) cb(_banksCache);
    });
  }

  function populateBankSelect($sel, banks, selectedId) {
    const cur = selectedId || $sel.val();
    $sel.empty().append('<option value="">-- Select Bank Account --</option>');
    banks.forEach(b => {
      const label = b.account_name + (b.bank_name ? ' (' + b.bank_name + ')' : '');
      const opt = $('<option>').val(b.id).text(label);
      if (String(b.id) === String(cur) || (b.is_default == 1 && !cur)) opt.prop('selected', true);
      $sel.append(opt);
    });
  }

  // Show/hide bank account row in payment modal based on method
  function updatePayBankRow() {
    const method = $('#pay_method').val();
    const needsBank = ['Cash','Bank Transfer','Cheque','Online'].includes(method);
    $('#pay_bank_account_row').toggle(needsBank);
    if (needsBank) {
      loadBankAccounts(function(banks){
        populateBankSelect($('#pay_bank_account_id'), banks);
      });
    }
  }
  $('#pay_method').on('change', updatePayBankRow);

  // Show/hide bank account row in invoice modal based on payment term
  function updateInvBankRow() {
    const term = $('#invPayTerm').val();
    const needsBank = ['Cash','Bank Transfer','Cheque','Online'].includes(term);
    $('#invBankAccountTopRow').toggle(needsBank);
    if (needsBank) {
      loadBankAccounts(function(banks){
        populateBankSelect($('#invBankAccountId'), banks);
      });
    }
  }
  $('#invPayTerm').on('change', updateInvBankRow);

  function setDatePreset(preset){
    const now = new Date();
    function ymd(d){
      const y = d.getFullYear();
      const m = String(d.getMonth()+1).padStart(2,'0');
      const day = String(d.getDate()).padStart(2,'0');
      return `${y}-${m}-${day}`;
    }

    if (preset === 'daily') {
      const t = ymd(now);
      $('#invDateFrom').val(t);
      $('#invDateTo').val(t);
    } else if (preset === 'monthly') {
      const first = new Date(now.getFullYear(), now.getMonth(), 1);
      const last = new Date(now.getFullYear(), now.getMonth()+1, 0);
      $('#invDateFrom').val(ymd(first));
      $('#invDateTo').val(ymd(last));
    } else if (preset === 'yearly') {
      const first = new Date(now.getFullYear(), 0, 1);
      const last = new Date(now.getFullYear(), 11, 31);
      $('#invDateFrom').val(ymd(first));
      $('#invDateTo').val(ymd(last));
    }
  }

  // CART state (simple client-side)
  let cart = []; // {fp_id?, cut_piece_id?, production_item_id?, service_id?, desc, unit:'sqft'|'sqm'|'pcs'|'ft', area?, qty?, rate:number}
  let servicesCache = [];
  function loadServicesPick(){
    $.get('api/services.php', { action:'list', active:1 }, function(res){
      servicesCache = res.data || [];
      const $sel = $('#svcPickSelect');
      if (!$sel.length) return;
      $sel.empty();
      $sel.append('<option value="">Select service</option>');
      servicesCache.forEach(s=>{
        $sel.append(`<option value="${s.id}">${$('<div>').text(s.name||'').html()}</option>`);
      });
    });
  }

  function renderCartInto($tableBody, subtotalOnlyEl){
    $tableBody.empty();
    let subtotal=0;
    cart.forEach((it, idx)=>{
      const isProd = !!it.production_item_id;
      const isSvc = !!it.service_id;
      const areaVal = (isProd || isSvc) ? 0 : (it.unit==='sqm' ? (Number(it.area||0)*0.09290304) : Number(it.area||0));
      const qtyVal = isProd ? Number(it.qty||1) : (isSvc ? Number(it.qty||0) : 1);
      const mult = (isProd || isSvc) ? qtyVal : areaVal;
      const line = Number(it.rate||0) * mult; subtotal += line;
      const tr=$('<tr>');
      const tag = isSvc
        ? '<span class="badge text-bg-warning me-1">Svc</span>'
        : (it.cut_piece_id ? '<span class="badge text-bg-info me-1">Cut</span>' : (it.fp_id? '<span class="badge text-bg-secondary me-1">FP</span>' : ''));
      const unitSel = (isProd || isSvc)
        ? (isProd ? `<span class="badge text-bg-secondary">PCS</span>` : `<span class="badge text-bg-secondary">${String(it.unit||'ft').toUpperCase()}</span>`)
        : `<select class="form-select form-select-lg cart-unit" data-idx="${idx}"><option value="sqft" ${it.unit==='sqft'?'selected':''}>SQFT</option><option value="sqm" ${it.unit==='sqm'?'selected':''}>SQM</option></select>`;
      tr.append(`<td>${tag}${$('<div>').text(it.desc).html()}</td>`);
      tr.append(`<td>${unitSel}</td>`);
      const areaCell = (isProd || isSvc)
        ? `<span class="text-muted">-</span>`
        : `<span class="cart-area" data-idx="${idx}">${areaVal.toFixed(3)}</span>`;
      const qtyCell = (isProd || isSvc)
        ? `<input type="number" step="${isProd ? '1' : '0.001'}" min="${isProd ? '1' : '0'}" class="form-control form-control-lg text-end cart-qty" data-idx="${idx}" value="${qtyVal}" placeholder="Qty">`
        : `<span class="cart-qty-fixed">1</span>`;
      tr.append(`<td class="text-end fs-5">${areaCell}</td>`);
      tr.append(`<td class="text-end fs-5">${qtyCell}</td>`);
      tr.append(`<td class="text-end"><input type="number" step="any" min="0" inputmode="decimal" class="form-control form-control-lg text-end cart-rate" data-idx="${idx}" value="${it.rate||''}" placeholder="0.00"></td>`);
      tr.append(`<td class=\"text-end\"><span class=\"cart-line\" data-idx=\"${idx}\">${line.toFixed(2)}</span></td>`);
      tr.append(`<td><button type=\"button\" class=\"btn btn-sm btn-outline-danger cart-del\" data-idx=\"${idx}\"><i class=\"bi bi-x\"></i></button></td>`);
      $tableBody.append(tr);
    });
    if (subtotalOnlyEl) subtotalOnlyEl.text(fmt(subtotal));
    return subtotal;
  }

  // ===== Quick Pick (FP/Cut/Prod) =====
  let qpMode = null; // 'fp' | 'cut' | 'prod'
  function qpRenderHead(){
    const $h=$('#qp_head'); $h.empty();
    if (qpMode==='fp') $h.append('<th>Slab</th><th>Finish</th><th>H</th><th>L</th><th>Sq.Ft</th><th></th>');
    else if (qpMode==='cut') $h.append('<th>ID</th><th>Job</th><th>Slab</th><th>Piece</th><th>Size (mm)</th><th>Area</th><th></th>');
    else if (qpMode==='prod') $h.append('<th>ID</th><th>Name</th><th>Type</th><th>Finish</th><th>Qty</th><th>Avail</th><th></th>');
  }
  function qpLoad(){
    const q=$('#qp_search').val()||'';
    const $tb=$('#qp_table tbody'); $tb.empty();
    if (qpMode==='fp'){
      const params={ action:'list', sale_status:'available' }; if (q) params.q=q;
      $.get('api/final_products.php', params, function(res){
        (res.data||[]).forEach(r=>{
          const btn = `<button type="button" class="btn btn-sm btn-primary qp-sel" data-id="${r.id}" data-desc="Slab ${r.slab_no||''} (${r.final_height||''}x${r.final_length||''})" data-area="${Number(r.final_sq_ft||0)}">Select</button>`;
          const tr = `<tr><td>${r.slab_no||''}</td><td>${r.finish_name||''}</td><td>${r.final_height||''}</td><td>${r.final_length||''}</td><td>${r.final_sq_ft||''}</td><td>${btn}</td></tr>`;
          $tb.append(tr);
        });
      });
    } else if (qpMode==='cut'){
      const params={ action:'list', status:'usable', avail:'available' }; if (q) params.q=q;
      $.get('api/cut_pieces.php', params, function(res){
        (res.data||[]).forEach(r=>{
          const size=`${Number(r.length_mm||0).toFixed(0)} x ${Number(r.width_mm||0).toFixed(0)}`;
          const btn = `<button type="button" class="btn btn-sm btn-primary qp-sel" data-id="${r.id}" data-desc="Cut Piece #${r.id}" data-area="${Number(r.area_sq_ft||0)}">Select</button>`;
          const tr = `<tr><td>${r.id}</td><td>${r.job_id||''}</td><td>${r.slab_no||''}</td><td>${r.piece_no||''}</td><td>${size}</td><td>${Number(r.area_sq_ft||0).toFixed(3)}</td><td>${btn}</td></tr>`;
          $tb.append(tr);
        });
      });
    } else if (qpMode==='prod'){
      const params={ action:'list', availability:'available' }; if (q) params.q=q;
      $.get('api/production_items.php', params, function(res){
        (res.data||[]).forEach(r=>{
          const meta=[r.type_name,r.color_name,r.finish_name].filter(Boolean).join(', ');
          const name=(r.name||'');
          const desc = `Prod ${name}${meta?(' ('+meta+')'):''} ${r.length||''}x${r.width||''}x${r.thickness||''}`;
          const btn = `<button type="button" class="btn btn-sm btn-primary qp-sel" data-id="${r.id}" data-desc="${$('<div>').text(desc).html()}" data-qty="${Number(r.quantity||1)}">Select</button>`;
          const tr = `<tr><td>${r.id}</td><td>${name}</td><td>${r.type_name||''}</td><td>${r.finish_name||''}</td><td>${r.quantity||1}</td><td>${r.availability||''}</td><td>${btn}</td></tr>`;
          $tb.append(tr);
        });
      });
    }
  }
  $('#qp_btn_search').on('click', qpLoad);
  $(document).on('click','.qp-sel', function(){
    const id=$(this).data('id'); const desc=$(this).data('desc')||'';
    if (qpMode==='fp'){ $('#ivItemType').val('fp'); $('#ivItemFp').val(id); $('#ivItemCut').val(''); $('#ivItemProd').val(''); $('#ivItemDesc').val(desc); }
    if (qpMode==='cut'){ $('#ivItemType').val('cut'); $('#ivItemCut').val(id); $('#ivItemFp').val(''); $('#ivItemProd').val(''); if (!$('#ivItemDesc').val()) $('#ivItemDesc').val(desc); }
    if (qpMode==='prod'){ $('#ivItemType').val('prod'); $('#ivItemProd').val(id); $('#ivItemFp').val(''); $('#ivItemCut').val(''); if (!$('#ivItemDesc').val()) $('#ivItemDesc').val(desc); }
    $('#quickPickModal').modal('hide');
  });
  $('#btnPickFp').on('click', function(){ qpMode='fp'; $('#qp_title').text('Pick Final Product'); qpRenderHead(); $('#qp_search').val(''); $('#quickPickModal').modal('show'); qpLoad(); });
  $('#btnPickCut').on('click', function(){ qpMode='cut'; $('#qp_title').text('Pick Cut Piece'); qpRenderHead(); $('#qp_search').val(''); $('#quickPickModal').modal('show'); qpLoad(); });
  $('#btnPickProd').on('click', function(){ qpMode='prod'; $('#qp_title').text('Pick Production Item'); qpRenderHead(); $('#qp_search').val(''); $('#quickPickModal').modal('show'); qpLoad(); });

  // ===== Payments: Edit/Delete/Reverse =====
  // Render buttons next to payments after table rows are built
  function augmentPaymentRows(invStatus){
    $('#iv_payments tbody tr').each(function(){
      const $tr=$(this); if ($tr.find('.pay-actions').length) return;
      if ($tr.find('td').length<4) return; // skip empty message row
      const idx=$tr.index();
      const payType = $tr.attr('data-payment-type') || 'normal';
      const isReversed = $tr.attr('data-is-reversed') == '1';
      const isReversal = payType === 'reversal';
      let btns = '';
      // Only allow edit/delete for normal payments that haven't been reversed
      if (!isReversal && !isReversed) {
        btns += `<button type="button" class="btn btn-sm btn-outline-primary pay-edit" data-index="${idx}">Edit</button> `;
        btns += `<button type="button" class="btn btn-sm btn-outline-danger pay-del" data-index="${idx}">Delete</button> `;
        // Show reverse button for paid invoices with normal payments
        if (invStatus === 'paid') {
          btns += `<button type="button" class="btn btn-sm btn-outline-warning pay-reverse" data-index="${idx}">Reverse</button>`;
        }
      }
      if (btns) $tr.append(`<td><div class="pay-actions">${btns}</div></td>`);
    });
    // add header th if not exists
    const $thead=$('#iv_payments thead tr'); if ($thead.find('th').length===4){ $thead.append('<th></th>'); }
  }
  // Store invoice status globally for augmentPaymentRows
  let _currentInvoiceStatus = '';
  // handlers
  $(document).on('click','.pay-edit', function(){
    const idx=$(this).data('index'); const row=$('#iv_payments tbody tr').eq(idx);
    const invId=$('#btnIssueInvoice').data('id');
    // create a quick inline edit using the existing modal fields
    const payDate=row.find('td:eq(0)').text().replace(/\s*(Reversal|Reversed)/gi, '').trim();
    const method=row.find('td:eq(1)').text().trim();
    const ref=row.find('td:eq(2)').text().trim();
    const amt=row.find('td:eq(3)').text().replace(/[^0-9.]/g,'');
    // open Add Payment modal prefilled and submit as update
    $('#pay_invoice_id').val(invId);
    $('#pay_date').val(payDate);
    $('#pay_method').val(method);
    $('#pay_ref').val(ref);
    $('#pay_amount').val(amt);
    // Change modal title to indicate edit mode
    $('#paymentModal .modal-title').text('Edit Payment');
    // Store edit mode data on the form
    $('#paymentForm').data('edit-mode', true).data('edit-index', idx);
    $('#paymentModal').modal('show');
  });
  $(document).on('click','.pay-del', function(){
    if(!confirm('Delete this payment?')) return;
    const idx=$(this).data('index'); const invId=$('#btnIssueInvoice').data('id');
    $.get('api/invoices.php', { action:'get', id: invId }, function(res){
      const p=res.data.payments?.[idx]; if (!p) return;
      const fd=new FormData(); fd.append('csrf',$('#csrf').val()); fd.append('action','delete_payment'); fd.append('id', p.id);
      $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
        .done(()=>{ loadInvoices(); openInvoice(invId); })
        .fail(xhr=>alert((xhr.responseJSON&&xhr.responseJSON.message)||'Error'));
    });
  });

  // Reverse payment handler
  $(document).on('click','.pay-reverse', function(){
    const idx=$(this).data('index'); const invId=$('#btnIssueInvoice').data('id');
    $.get('api/invoices.php', { action:'get', id: invId }, function(res){
      const p=res.data.payments?.[idx]; if (!p) return;
      const reason = prompt('Enter reason for reversing this payment (optional):');
      if (reason === null) return; // user cancelled
      const fd=new FormData();
      fd.append('csrf',$('#csrf').val());
      fd.append('action','reverse_payment');
      fd.append('id', p.id);
      if (reason.trim()) fd.append('reason', reason.trim());
      $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
        .done(()=>{ loadInvoices(); openInvoice(invId); alert('Payment reversed successfully'); })
        .fail(xhr=>alert((xhr.responseJSON&&xhr.responseJSON.message)||'Error'));
    });
  });

  // ===== Invoice View: Item-wise CRUD =====
  // Add Item
  $(document).on('click','#btnAddItem', function(){
    const invId = $('#btnIssueInvoice').data('id');
    if (!invId) { alert('Open an invoice first'); return; }
    const frm = document.getElementById('ivItemForm'); if (frm) frm.reset();
    $('#ivItemId').val('');
    $('#ivItemInvoiceId').val(invId);
    $('#ivItemModal').modal('show');
  });

  // Edit Item
  $(document).on('click','.iv-item-edit', function(){
    const id = $(this).data('id');
    const row = $(this).closest('tr');
    const invId = $('#btnIssueInvoice').data('id');
    $('#ivItemId').val(id);
    $('#ivItemInvoiceId').val(invId);
    $('#ivItemDesc').val(row.find('td:eq(0)').text());
    $('#ivItemQty').val(row.find('td:eq(1)').text());
    $('#ivItemPrice').val(row.find('td:eq(2)').text().replace(/[^0-9.]/g,''));
    $('#ivItemModal').modal('show');
  });

  // Save Add/Edit Item
  $('#ivItemForm').on('submit', function(e){
    e.preventDefault();
    const id=$('#ivItemId').val();
    const invId=$('#ivItemInvoiceId').val();
    const type=$('#ivItemType').val();
    const fd=new FormData();
    fd.append('csrf',$('#csrf').val());
    if (id){ fd.append('action','update_item'); fd.append('id', id); }
    else { fd.append('action','add_item'); fd.append('invoice_id', invId); }
    const fp=$('#ivItemFp').val(); const cut=$('#ivItemCut').val(); const prod=$('#ivItemProd').val();
    if (type==='fp' && fp) fd.append('final_product_id', fp);
    if (type==='cut' && cut) fd.append('cut_piece_id', cut);
    if (type==='prod' && prod) fd.append('production_item_id', prod);
    fd.append('description',$('#ivItemDesc').val());
    fd.append('qty',$('#ivItemQty').val());
    fd.append('unit_price',$('#ivItemPrice').val());
    $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
      .done(()=>{ $('#ivItemModal').modal('hide'); openInvoice($('#btnIssueInvoice').data('id')); loadInvoices(); })
      .fail(xhr=>alert((xhr.responseJSON&&xhr.responseJSON.message)||'Error'));
  });

  // Delete Item
  $(document).on('click','.iv-item-del', function(){
    if(!confirm('Delete this item from invoice?')) return;
    const id=$(this).data('id'); const fd=new FormData();
    fd.append('csrf',$('#csrf').val()); fd.append('action','delete_item'); fd.append('id', id);
    $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
      .done(()=>{ openInvoice($('#btnIssueInvoice').data('id')); loadInvoices(); })
      .fail(xhr=>alert((xhr.responseJSON&&xhr.responseJSON.message)||'Error'));
  });

  // Return Item (modal)
  $(document).on('click','.iv-item-return', function(){
    const id=$(this).data('id'); const maxQty=Number($(this).data('qty')||0);
    $('#ret_item_id').val(id);
    $('#ret_qty').val('');
    $('#ret_qty').attr('max', maxQty);
    $('#ret_hint').text('Max returnable: '+maxQty);
    $('#ret_reason').val('');
    $('#returnItemModal').modal('show');
  });

  $('#returnItemForm').on('submit', function(e){
    e.preventDefault();
    const id=$('#ret_item_id').val();
    const qty=parseFloat($('#ret_qty').val()||'0');
    const max=parseFloat($('#ret_qty').attr('max')||'0');
    if(!(qty>0)) { alert('Enter return qty'); return; }
    if(qty>max){ alert('Qty exceeds remaining'); return; }
    const reason=$('#ret_reason').val();
    const fd=new FormData(); fd.append('csrf',$('#csrf').val()); fd.append('action','return_item'); fd.append('item_id', id); fd.append('qty', qty); fd.append('reason', reason||'');
    $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
      .done(()=>{ $('#returnItemModal').modal('hide'); openInvoice($('#btnIssueInvoice').data('id')); loadInvoices(); })
      .fail(xhr=>alert((xhr.responseJSON&&xhr.responseJSON.message)||'Error'));
  });

  // Delete cancelled invoice (superadmin only)
  $('#btnDeleteInvoice').on('click', function(){
    const id=$('#btnDeleteInvoice').data('id') || $('#btnIssueInvoice').data('id'); if(!id) return;
    if(!confirm('Delete this cancelled invoice? Items will be reverted to available status.')) return;
    const fd=new FormData(); fd.append('csrf',$('#csrf').val()); fd.append('action','delete'); fd.append('id', id);
    $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
      .done(()=>{ $('#invoiceViewModal').modal('hide'); loadInvoices(); })
      .fail(xhr=>alert((xhr.responseJSON&&xhr.responseJSON.message)||'Error'));
  });

  // -------- Production Items Picker --------
  function loadProdPickLookups(){
    $.get('api/production_items.php', { action:'lookups' }, function(res){
      const types = res.types||[]; const quals = res.qualities||[];
      const typeOpts = ['<option value="">All</option>'];
      types.forEach(t=>typeOpts.push(`<option value="${t.id}">${$('<div>').text(t.name).html()}</option>`));
      $('#prodPickType').html(typeOpts.join(''));
      const qualOpts = ['<option value="">All</option>'];
      quals.forEach(q=>qualOpts.push(`<option value="${q.id}">${$('<div>').text(q.name).html()}</option>`));
      $('#prodPickQuality').html(qualOpts.join(''));
    });
  }

  function loadProdPick(){
    const params = { action:'list' };
    const b = ($('#invBranchFilter').length ? ($('#invBranchFilter').val()||'').trim() : '');
    if (b) params.branch_id = b;
    const t=$('#prodPickType').val(); if (t) params.type_id=t;
    const q=$('#prodPickQuality').val(); if (q) params.quality_id=q;
    const av=$('#prodPickAvail').val(); if (av!==undefined && av!=='') params.availability=av;
    const s=$('#prodPickSearch').val(); if (s) params.q=s;
    $.get('api/production_items.php', params, function(res){
      const $tb=$('#prodPickTableM tbody'); $tb.empty();
      const rows = res.data||[]; if(!rows.length){ $tb.append('<tr><td colspan="12" class="text-center text-muted">No production items</td></tr>'); return; }
      rows.forEach(r=>{
        const tr=$('<tr>');
        tr.append(`<td><input type=\"checkbox\" class=\"prodPickChk\" data-id=\"${r.id}\" data-name=\"${$('<div>').text(r.name||'').html()}\" data-type=\"${$('<div>').text(r.type_name||'').html()}\" data-color=\"${$('<div>').text(r.color_name||'').html()}\" data-finish=\"${$('<div>').text(r.finish_name||'').html()}\" data-length=\"${r.length||0}\" data-width=\"${r.width||0}\" data-thick=\"${r.thickness||0}\" data-qty=\"${r.quantity||1}\"></td>`);
        tr.append(`<td>${r.id}</td>`);
        tr.append(`<td>${$('<div>').text(r.name||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.type_name||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.color_name||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.finish_name||'').html()}</td>`);
        tr.append(`<td class=\"text-end\">${Number(r.length||0).toFixed(2)}</td>`);
        tr.append(`<td class=\"text-end\">${Number(r.width||0).toFixed(2)}</td>`);
        tr.append(`<td class=\"text-end\">${Number(r.thickness||0).toFixed(2)}</td>`);
        tr.append(`<td class=\"text-end\">${Number(r.quantity||0)}</td>`);
        tr.append(`<td>${$('<div>').text(r.availability||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.notes||'').html()}</td>`);
        $tb.append(tr);
      });
    });
  }

  $(document).on('change', '#prodPickType,#prodPickQuality,#prodPickAvail', loadProdPick);
  $('#btnProdSearchM').on('click', function(){ loadProdPick(); });
  $('#btnReloadProdM').on('click', function(){ loadProdPick(); });
  $('#prodPickAllM').on('change', function(){ const ck=this.checked; $('.prodPickChk').prop('checked', ck); });
  $('#btnAddSelectedProdM').on('click', function(){
    const list=[]; $('.prodPickChk:checked').each(function(){
      list.push({ id: Number($(this).data('id')), name: $(this).data('name'), type: $(this).data('type'), color: $(this).data('color'), finish: $(this).data('finish'), length: $(this).data('length'), width: $(this).data('width'), thick: $(this).data('thick'), qty: Number($(this).data('qty')||1) });
    });
    if(!list.length){ alert('Please select at least one production item'); return; }
    list.forEach(it=>{
      if (cart.find(x=>x.production_item_id===it.id)) return;
      const nameTxt = it.name ? `${it.name}` : '';
      const meta = [it.type, it.color, it.finish].filter(Boolean).join(', ');
      const typeTxt = meta ? ` (${meta})` : '';
      const sizeTxt = `${it.length||''}x${it.width||''}x${it.thick||''}`;
      const desc = `Prod ${nameTxt}${typeTxt} ${sizeTxt}`;
      cart.push({ production_item_id: it.id, desc, unit: 'pcs', qty: Number(it.qty||1), rate: 0 });
    });
    refreshCart();
  });
  function refreshCart(){
    // render into modal cart table if present
    const $tbm = $('#cartm-table tbody'); const hasModalCart = $tbm.length>0;
    const subtotal = renderCartInto(hasModalCart?$tbm:$('#cart-table tbody'), hasModalCart?$('#cartmSubtotal'):$('#cartSubtotal'));
    if (hasModalCart){
      const taxp = Number($('#invTax').val()||0);
      const discP = Number($('#invDiscountP').val()||0);
      const discAmtInput = Number($('#invDiscount').val()||0);
      const transport = Number($('#invTransport').val()||0);
      const tax = +(subtotal * taxp / 100).toFixed(2);
      const discAmt = discP ? +(subtotal * discP / 100).toFixed(2) : +(discAmtInput||0);
      const total = Math.max(0, +(subtotal + tax + transport - discAmt).toFixed(2));
      const advance = Number($('#invAdvance').length ? ($('#invAdvance').val()||0) : 0);
      const balance = Math.max(0, +(total - advance).toFixed(2));
      $('#cartmTax').text(fmt(tax));
      $('#cartmTransport').text(fmt(transport));
      $('#cartmDisc').text(fmt(discAmt));
      $('#cartmTotal').text(fmt(total));
      if ($('#cartmAdvance').length) $('#cartmAdvance').text(fmt(advance));
      if ($('#cartmBalance').length) $('#cartmBalance').text(fmt(balance));
    }
  }
  // Update totals live on %/amount change
  $(document).on('input change', '#invTax,#invDiscountP,#invDiscount,#invTransport,#invAdvance', refreshCart);
  
  // Recompute only the totals without rebuilding the cart rows
  function recomputeTotalsOnly(){
    const $tbm = $('#cartm-table tbody'); const hasModalCart = $tbm.length>0;
    // compute subtotal from current cart
    let subtotal=0;
    cart.forEach(it=>{
      const isProd = !!it.production_item_id;
      const isSvc = !!it.service_id;
      if (isProd || isSvc){
        subtotal += Number(it.rate||0) * Number(it.qty||0);
      } else {
        const area = it.unit==='sqm' ? (Number(it.area||0)*0.09290304) : Number(it.area||0);
        subtotal += area * Number(it.rate||0);
      }
    });
    if (hasModalCart){
      const taxp = Number($('#invTax').val()||0);
      const discP = Number($('#invDiscountP').val()||0);
      const discAmtInput = Number($('#invDiscount').val()||0);
      const transport = Number($('#invTransport').val()||0);
      const tax = +(subtotal * taxp / 100).toFixed(2);
      const discAmt = discP ? +(subtotal * discP / 100).toFixed(2) : +(discAmtInput||0);
      const total = Math.max(0, +(subtotal + tax + transport - discAmt).toFixed(2));
      const advance = Number($('#invAdvance').length ? ($('#invAdvance').val()||0) : 0);
      const balance = Math.max(0, +(total - advance).toFixed(2));
      $('#cartmSubtotal').text(fmt(subtotal));
      $('#cartmTax').text(fmt(tax));
      $('#cartmTransport').text(fmt(transport));
      $('#cartmDisc').text(fmt(discAmt));
      $('#cartmTotal').text(fmt(total));
      if ($('#cartmAdvance').length) $('#cartmAdvance').text(fmt(advance));
      if ($('#cartmBalance').length) $('#cartmBalance').text(fmt(balance));
    }
  }

  // When typing rate, update model and only recalc the row + totals (no full rebuild)
  $(document).on('input', '.cart-rate', function(){
    const idx = Number($(this).data('idx'));
    if (Number.isNaN(idx) || !cart[idx]) return;
    cart[idx].rate = this.value === '' ? 0 : Number(this.value);
    const isProd = !!cart[idx].production_item_id;
    const area = isProd ? Number(cart[idx].qty||1) : (cart[idx].unit==='sqm' ? (Number(cart[idx].area||0)*0.09290304) : Number(cart[idx].area||0));
    const line = Number(cart[idx].rate||0) * area;
    // Update line cell text next to this input
    $(this).closest('tr').find('.cart-line').text(line.toFixed(2));
    // Update totals only
    recomputeTotalsOnly();
  });

  // Typing UX: auto-select on focus and Enter jumps to next rate field
  $(document).on('focus', '.cart-rate', function(){ this.select(); });
  $(document).on('keydown', '.cart-rate', function(e){
    if (e.key === 'Enter'){
      e.preventDefault();
      const $rates = $('#cartm-table .cart-rate');
      const i = $rates.index(this);
      if (i >= 0 && i < $rates.length - 1){
        $rates.eq(i+1).focus().select();
      }
    }
  });

  // When typing quantity for production items
  $(document).on('input', '.cart-qty', function(){
    const idx = Number($(this).data('idx'));
    if (Number.isNaN(idx) || !cart[idx]) return;
    const isProd = !!cart[idx].production_item_id;
    const q = isProd ? parseInt(this.value||'0',10) : parseFloat(this.value||'0');
    cart[idx].qty = (isProd ? (isNaN(q) || q<1 ? 1 : q) : (isNaN(q) || q<0 ? 0 : q));
    const mult = Number(cart[idx].qty||0);
    const line = Number(cart[idx].rate||0) * mult;
    $(this).closest('tr').find('.cart-line').text(line.toFixed(2));
    recomputeTotalsOnly();
  });

  $('#svcPickSelect').on('change', function(){
    const id = ($(this).val()||'').trim();
    const row = servicesCache.find(x=>String(x.id)===String(id));
    if (!row) return;
    const curDesc = ($('#svcPickDesc').val()||'').trim();
    if (curDesc === '') $('#svcPickDesc').val(row.name || 'Service');
  });
  $('#btnAddServiceM').on('click', function(){
    const id = ($('#svcPickSelect').val()||'').trim();
    if (!id) { alert('Select a service'); return; }
    const row = servicesCache.find(x=>String(x.id)===String(id));
    if (!row) { alert('Service not found'); return; }
    const unit = ($('#svcPickUnit').val()||'ft').trim();
    const qty = parseFloat($('#svcPickQty').val()||'0');
    if (!(qty > 0)) { alert('Enter quantity'); return; }
    const rate = parseFloat($('#svcPickRate').val()||'0');
    const desc = ($('#svcPickDesc').val()||row.name||'Service').trim();
    cart.push({ service_id: Number(row.id), desc, unit: unit, qty: qty, rate: isNaN(rate) ? 0 : rate });
    $('#svcPickQty').val('');
    refreshCart();
  });

  // Change unit without full rebuild; update area & line for the row
  $(document).on('change', '.cart-unit', function(){
    const idx = Number($(this).data('idx'));
    if (Number.isNaN(idx) || !cart[idx]) return;
    cart[idx].unit = this.value;
    const area = cart[idx].unit==='sqm' ? (Number(cart[idx].area||0)*0.09290304) : Number(cart[idx].area||0);
    const line = Number(cart[idx].rate||0) * area;
    const $tr = $(this).closest('tr');
    $tr.find('.cart-area').text(area.toFixed(3));
    $tr.find('.cart-line').text(line.toFixed(2));
    recomputeTotalsOnly();
  });

  // Toast helper
  function showToast(msg, type){
    const id = 'toast-'+Date.now();
    const bg = type==='error' ? 'bg-danger' : 'bg-success';
    const html = `<div id="${id}" class="toast align-items-center text-white ${bg} border-0 position-fixed" role="alert" aria-live="assertive" aria-atomic="true" style="top: 20px; right: 20px; z-index: 1080;">
      <div class="d-flex"><div class="toast-body">${$('<div>').text(msg).html()}</div>
      <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button></div></div>`;
    const $el = $(html).appendTo('body');
    if (window.bootstrap && bootstrap.Toast){ bootstrap.Toast.getOrCreateInstance($el[0],{delay:2500}).show(); }
    setTimeout(()=>{ $el.remove(); }, 3000);
  }

  // Load finishes into FP detail select
  function fpLoadFinishes(){
    $.get('api/materials.php', { action:'list_finishes' }, function(res){
      const opts=['<option value="">Select</option>'];
      (res.data||[]).forEach(f=>opts.push(`<option value="${f.id}">${$('<div>').text(f.name).html()}</option>`));
      $('#fp_finish').html(opts.join(''));
    });
  }

  function openFpDetail(id){
    fpLoadFinishes();
    $.get('api/final_products.php', { action:'detail', id }, function(res){
      const d=res.data||{};
      $('#fp_id').val(d.id);
      $('#fp_slab').text(d.slab_no||'');
      $('#fp_worker').text(d.worker_name||'');
      $('#fp_start').text(d.start_at||'');
      $('#fp_end').text(d.end_at||'');
      $('#fp_pre_h').text(d.pre_height ?? d.pre_height_raw ?? '');
      $('#fp_pre_l').text(d.pre_length ?? d.pre_length_raw ?? '');
      $('#fp_po').text(d.order_no||'');
      $('#fp_final_h').val(d.final_height||'');
      $('#fp_final_l').val(d.final_length||'');
      $('#fp_quality').val(d.quality || d.raw_quality || '');
      $('#fp_finish').val(d.finish_id||'');
      $('#fpDetailModal').modal('show');
    });
  }

  $(document).on('click', '.btn-fp-details', function(){ openFpDetail($(this).data('id')); });
  $('#fpDetailForm').on('submit', function(e){
    e.preventDefault(); const fd=new FormData(this); fd.append('action','update');
    $.ajax({ url:'api/final_products.php', method:'POST', data:fd, contentType:false, processData:false })
      .done(function(){ $('#fpDetailModal').modal('hide'); loadFP(); })
      .fail(function(xhr){ alert((xhr.responseJSON && xhr.responseJSON.message) || 'Error'); });
  });

  // Load available final products
  function loadFP(){
    const q=(($('#fpSearch').val())||'').trim();
    const status = $('.fp-filter.active').data('status')||'available';
    const params = { action:'list' };
    if (q) params.q=q; if (status) params.sale_status=status;
    $.get('api/final_products.php', params, function(res){
      const $tb = $('#fp-table tbody'); $tb.empty();
      const rows = res.data||[];
      if(!rows.length){ $tb.append('<tr><td colspan="8" class="text-center text-muted">No items</td></tr>'); return; }
      const urlParams = new URLSearchParams(window.location.search);
      const highlight = urlParams.get('highlight_fp');
      rows.forEach(r=>{
        const tr=$('<tr>').attr('data-id', r.id);
        tr.append(`<td>${$('<div>').text(r.slab_no||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.finish_name||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.type_name||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.color_name||'').html()}</td>`);
        tr.append(`<td>${r.final_height??''}</td>`);
        tr.append(`<td>${r.final_length??''}</td>`);
        tr.append(`<td>${r.final_sq_ft??''}</td>`);
        tr.append(`<td>${r.pre_height??''}</td>`);
        tr.append(`<td>${r.pre_length??''}</td>`);
        tr.append(`<td>${$('<div>').text(r.worker_name||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.quality||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.order_no||'').html()}</td>`);
        const btnDetails = `<button type="button" class="btn btn-sm btn-outline-secondary me-1 btn-fp-details" data-id="${r.id}" title="View" aria-label="View"><i class="bi bi-eye"></i></button>`;
        const areaSqft = Number(r.final_sq_ft||0);
        const btnAdd = `<button type="button" class="btn btn-sm btn-outline-primary btn-add-fp" data-id="${r.id}" data-desc="Slab ${r.slab_no||''} (${r.final_height||''}x${r.final_length||''})" data-area_sqft="${areaSqft}" title="Add to Invoice" aria-label="Add to Invoice"><i class="bi bi-plus-circle"></i></button>`;
        tr.append(`<td>${btnDetails}${btnAdd}</td>`);
        $tb.append(tr);
        if (String(highlight||'') === String(r.id)) { tr.addClass('table-success'); setTimeout(()=>{ tr[0]?.scrollIntoView({behavior:'smooth', block:'center'}); }, 100); }
      });
    });
  }

  // Modal FP picker load
  function loadFPModal(){
    const q=(($('#fpModalSearch').val())||'').trim();
    const params={ action:'list', sale_status:'available' };
    const b = ($('#invBranchFilter').val()||'').trim();
    if (b) params.branch_id = b;
    if (q) params.q=q;
    $.get('api/final_products.php', params, function(res){
      const $tb=$('#fpModalTable tbody'); $tb.empty(); const rows=res.data||[];
      if(!rows.length){ $tb.append('<tr><td colspan="10" class="text-center text-muted">No items</td></tr>'); return; }
      rows.forEach(r=>{
        const tr=$('<tr>');
        tr.append(`<td>${$('<div>').text(r.order_no||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.slab_no||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.finish_name||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.type_name||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.color_name||'').html()}</td>`);
        tr.append(`<td>${r.final_height??''}</td>`);
        tr.append(`<td>${r.final_length??''}</td>`);
        tr.append(`<td>${r.final_sq_ft??''}</td>`);
        const areaSqft=Number(r.final_sq_ft||0);
        const poLabel = r.order_no ? `PO ${r.order_no} - ` : '';
        const desc = `${poLabel}Slab ${r.slab_no||''} (${r.final_height||''}x${r.final_length||''})`;
        const btnAdd = `<button type="button" class="btn btn-sm btn-outline-primary btn-add-fp" data-id="${r.id}" data-desc="${$('<div>').text(desc).html()}" data-area_sqft="${areaSqft}">Add</button>`;
        tr.append(`<td>${btnAdd}</td>`);
        $tb.append(tr);
      });
    });
  }
  $('#btnFpModalSearch').on('click', loadFPModal);
  $('#fpModalSearch').on('keypress', function(e){ if(e.which===13) loadFPModal(); });
  $('#invBranchFilter').on('change', loadFPModal);

  // Modal cut pieces picker
  function loadCutPiecesModal(){
    const params={ action:'list', status:'usable', avail: 'available' };
    const b = ($('#invBranchFilter').length ? ($('#invBranchFilter').val()||'').trim() : '');
    if (b) params.branch_id = b;
    const q = ($('#cutSearch').val()||'').trim(); if (q) params.q=q;
    const slab_q = ($('#cutSlabSearch').val()||'').trim(); if (slab_q) params.slab_q=slab_q;
    const lenMin = ($('#cutLenMin').val()||''); if (lenMin!=='') params.len_min=lenMin;
    const lenMax = ($('#cutLenMax').val()||''); if (lenMax!=='') params.len_max=lenMax;
    const widMin = ($('#cutWidMin').val()||''); if (widMin!=='') params.wid_min=widMin;
    const widMax = ($('#cutWidMax').val()||''); if (widMax!=='') params.wid_max=widMax;
    $.get('api/cut_pieces.php', params, function(res){
      const $tb=$('#cutPickTableM tbody'); $tb.empty(); const rows=res.data||[];
      if(!rows.length){ $tb.append('<tr><td colspan="8" class="text-center text-muted">No cut pieces</td></tr>'); return; }
      rows.forEach(r=>{
        const size=`${Number(r.length_mm||0).toFixed(0)} x ${Number(r.width_mm||0).toFixed(0)}`;
        const tr=$('<tr>');
        tr.append(`<td><input type="checkbox" class="cutPickChkM" data-id="${r.id}" data-area="${Number(r.area_sq_ft||0)}" data-po="${$('<div>').text(r.po_no||'').html()}" data-slab="${$('<div>').text(r.slab_no||'').html()}"></td>`);
        tr.append(`<td>${r.id}</td>`);
        tr.append(`<td>${r.job_id}</td>`);
        tr.append(`<td>${r.piece_no}</td>`);
        tr.append(`<td>${$('<div>').text(r.slab_no||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(r.po_no||'').html()}</td>`);
        tr.append(`<td>${size}</td>`);
        tr.append(`<td>${Number(r.area_sq_ft||0).toFixed(3)}</td>`);
        $tb.append(tr);
      });
    });
  }
  $('#btnReloadCutPiecesM').on('click', loadCutPiecesModal);
  $('#cutPickAllM').on('change', function(){ const ck=this.checked; $('.cutPickChkM').prop('checked', ck); });
  $('#btnCutSearch').on('click', loadCutPiecesModal);
  $('#cutSearch,#cutSlabSearch,#cutLenMin,#cutLenMax,#cutWidMin,#cutWidMax').on('keypress', function(e){ if(e.which===13) loadCutPiecesModal(); });
  $('#btnAddSelectedCutM').on('click', function(){
    const list=[]; $('.cutPickChkM:checked').each(function(){
      list.push({
        id: $(this).data('id'),
        area: Number($(this).data('area')||0),
        po: String($(this).data('po')||''),
        slab: String($(this).data('slab')||'')
      });
    });
    if(!list.length){ alert('Please select at least one cut piece'); return; }
    list.forEach(it=>{
      if (cart.find(x=>x.cut_piece_id===it.id)) return;
      const poLabel = it.po ? `PO ${it.po} - ` : '';
      const slabLabel = it.slab ? `Slab ${it.slab} - ` : '';
      const desc = `${poLabel}${slabLabel}Cut Piece #${it.id}`;
      cart.push({ cut_piece_id: it.id, desc, unit:'sqft', area: it.area, rate: 0 });
    });
    refreshCart();
  });

  // ===== Cut Pieces Picker =====
  function loadCutPieces(){
    const params={ action:'list', status:'usable', avail: 'available' };
    $.get('api/cut_pieces.php', params, function(res){
      const $tb=$('#cutPickTable tbody').empty(); const rows=res.data||[];
      if(!rows.length){ $tb.append('<tr><td colspan="6" class="text-center text-muted">No cut pieces</td></tr>'); return; }
      rows.forEach(r=>{
        const size=`${Number(r.length_mm||0).toFixed(0)} x ${Number(r.width_mm||0).toFixed(0)}`;
        const tr=$('<tr>').attr('data-id',r.id).attr('data-area', Number(r.area_sq_ft||0));
        tr.append(`<td><input type="checkbox" class="cutPickChk" data-id="${r.id}" data-area="${Number(r.area_sq_ft||0)}"></td>`);
        tr.append(`<td>${r.id}</td>`);
        tr.append(`<td>${r.job_id}</td>`);
        tr.append(`<td>${r.piece_no}</td>`);
        tr.append(`<td>${size}</td>`);
        tr.append(`<td>${Number(r.area_sq_ft||0).toFixed(3)}</td>`);
        $tb.append(tr);
      });
    });
  }
  $('#btnAddCutPiece').on('click', function(){ loadCutPieces(); $('#cutPickModal').modal('show'); });
  $('#btnReloadCutPieces').on('click', loadCutPieces);
  $('#cutPickAll').on('change', function(){ const ck=this.checked; $('.cutPickChk').prop('checked', ck); });
  $('#btnAddSelectedCut').on('click', function(){
    const list=[]; $('.cutPickChk:checked').each(function(){ list.push({ id: $(this).data('id'), area: Number($(this).data('area')||0) }); });
    if(!list.length){ alert('Please select at least one cut piece'); return; }
    list.forEach(it=>{
      if (cart.find(x=>x.cut_piece_id===it.id)) return;
      cart.push({ cut_piece_id: it.id, desc: `Cut Piece #${it.id}`, unit:'sqft', area: it.area, rate: 0 });
    });
    refreshCart();
    $('#cutPickModal').modal('hide');
  });

  // Load invoices
  function loadInvoices(){
    const isAdmin = $('#isAdmin').val() === '1';
    const userBranchId = $('#userBranchId').val();
    const status = $('.inv-filter.active').data('status')||'';
    const q = ($('#invSearch').val()||'').trim();
    const dateFrom = ($('#invDateFrom').val()||'').trim();
    const dateTo = ($('#invDateTo').val()||'').trim();
    const payt = ($('#invPayTermList').val()||'').trim();
    const customerId = ($('#invCustomerFilterId').val()||'').trim();
    // For non-admin users, always use their assigned branch; for admin, use the filter value
    const branchId = isAdmin ? ($('#invBranchFilter').val()||'') : userBranchId;

    function loadSalesKpis(){
      const kparams = { action:'sales_kpis' };
      if (status) kparams.status=status;
      if (q) kparams.q=q;
      if (payt) kparams.payment_term=payt;
      if (customerId) kparams.customer_id=customerId;
      if (dateFrom) kparams.date_from=dateFrom;
      if (dateTo) kparams.date_to=dateTo;
      if (branchId) kparams.branch_id=branchId;
      $.get('api/reports.php', kparams, function(res){
        const d = res.data || {};
        $('#sk_qty').text(Number(d.sales_qty||0).toLocaleString());
        $('#sk_value').text(fmt(d.sales_value||0));
        $('#sk_paid').text(fmt(d.paid_amount||0));
        $('#sk_outstanding').text(fmt(d.outstanding_amount||0));
      });
    }
    loadSalesKpis();

    const params = { action:'list' };
    if (status) params.status=status;
    if (q) params.q=q;
    if (payt) params.payment_term=payt;
    if (customerId) params.customer_id=customerId;
    if (dateFrom) params.date_from=dateFrom;
    if (dateTo) params.date_to=dateTo;
    if (branchId) params.branch_id=branchId;
    $.get('api/invoices.php', params, function(res){
      const $tb=$('#invoices-table tbody'); $tb.empty();
      const rows=res.data||[]; if(!rows.length){ $tb.append('<tr><td colspan="8" class="text-center text-muted">No invoices</td></tr>'); return; }
      rows.forEach(r=>{
        const tr=$('<tr>');
        tr.append(`<td>${r.invoice_no}</td>`);
        tr.append(`<td>${r.invoice_date}</td>`);
        tr.append(`<td>${$('<div>').text(r.customer_name).html()}</td>`);
        tr.append(`<td><span class="badge bg-secondary text-capitalize">${r.status}</span></td>`);
        tr.append(`<td>${$('<div>').text(r.payment_term||'').html()}</td>`);
        tr.append(`<td class="text-end">${fmt(r.grand_total)}</td>`);
        tr.append(`<td class="text-end">${fmt(r.balance||0)}</td>`);
        const printHref = <?php echo json_encode(url_for("pages/invoice_print.php")); ?> + '?id=' + encodeURIComponent(r.id);
        const btnView = `<button class=\"btn btn-sm btn-outline-secondary btn-view-invoice\" data-id=\"${r.id}\" title=\"View\" aria-label=\"View\"><i class=\"bi bi-eye\"></i></button>`;
        const btnEdit = (r.status==='draft') ? `<button class=\"btn btn-sm btn-outline-primary btn-edit-invoice\" data-id=\"${r.id}\" title=\"Edit\" aria-label=\"Edit\"><i class=\"bi bi-pencil\"></i></button>` : '';
        const btnPrint = `<a class=\"btn btn-sm btn-outline-secondary\" href=\"${printHref}\" target=\"_blank\" title=\"Print\" aria-label=\"Print\"><i class=\"bi bi-printer\"></i></a>`;
        const canCancel = (r.status!=='cancelled' && r.status!=='paid');
        const btnCancel = canCancel ? `<button class=\"btn btn-sm btn-outline-danger inv-cancel\" data-id=\"${r.id}\" title=\"Cancel\" aria-label=\"Cancel\"><i class=\"bi bi-x-circle\"></i></button>` : '';
        tr.append(`<td class=\"d-flex gap-1\">${btnView}${btnEdit}${btnPrint}${btnCancel}</td>`);
        $tb.append(tr);
      });
    });
  }

  // Load customers (for select and table)
  function loadCustomers(done){
    $.get('api/customers.php', { action:'list' }, function(res){
      const list=res.data||[];
      // select
      const opts=['<option value="">Select Customer</option>'];
      list.forEach(c=>opts.push(`<option value="${c.id}">${$('<div>').text(c.name).html()}</option>`));
      $('#invCustomer').html(opts.join(''));
      // invoices filter select
      const dlist=[];
      list.forEach(c=>dlist.push(`<option value="${$('<div>').text(c.name).html()}" data-id="${c.id}"></option>`));
      $('#invCustomerFilterList').html(dlist.join(''));
      // table
      const $tb=$('#cust-table tbody'); $tb.empty();
      if(!list.length){ $tb.append('<tr><td colspan="4" class="text-center text-muted">No customers</td></tr>'); return; }
      list.forEach(c=>{
        const act=[
          `<button class=\"btn btn-sm btn-outline-primary me-1 cust-edit\" data-id=\"${c.id}\" title=\"Edit\"><i class=\"bi bi-pencil\"></i></button>`,
          `<button class=\"btn btn-sm btn-outline-danger cust-del\" data-id=\"${c.id}\" title=\"Delete\"><i class=\"bi bi-trash\"></i></button>`
        ];
        $tb.append(`<tr data-id="${c.id}"><td>${$('<div>').text(c.name).html()}</td><td>${$('<div>').text(c.phone||'').html()}</td><td>${$('<div>').text(c.email||'').html()}</td><td>${act.join('')}</td></tr>`);
      });
      if (typeof done === 'function') done();
    });
  }

  // Utility: robust modal open (supports Bootstrap 5 without jQuery plugin)
  function openModalById(mid){
    var $m = $('#'+mid);
    if ($m.modal) { $m.modal('show'); return; }
    if (window.bootstrap && bootstrap.Modal) {
      var inst = bootstrap.Modal.getOrCreateInstance(document.getElementById(mid));
      inst.show();
    }
  }

  function hideModalById(mid){
    var el = document.getElementById(mid);
    if (!el) return;
    if (window.bootstrap && bootstrap.Modal) {
      var inst = bootstrap.Modal.getOrCreateInstance(el);
      inst.hide();
      return;
    }
    var $m = $('#'+mid); if ($m.modal) { $m.modal('hide'); }
  }

  // Events: filters and search
  $('#btnFpSearch').on('click', loadFP);
  $('#fpSearch').on('keypress', function(e){ if(e.which===13) loadFP(); });
  $('.fp-filter').on('click', function(){ $('.fp-filter').removeClass('active'); $(this).addClass('active'); loadFP(); });
  $('.inv-filter').on('click', function(){ $('.inv-filter').removeClass('active'); $(this).addClass('active'); loadInvoices(); });
  $('#btnInvSearchGo').on('click', loadInvoices);
  $('#invSearch').on('keypress', function(e){ if(e.which===13) loadInvoices(); });
  $('#invPayTermList').on('change', loadInvoices);
  $('#invBranchFilter').on('change', loadInvoices);
  $('#invDatePreset').on('change', function(){
    const v = ($(this).val()||'custom');
    if (v !== 'custom') {
      setDatePreset(v);
      loadInvoices();
    }
  });
  function syncInvCustomerFilter(){
    const txt = ($('#invCustomerFilterText').val() || '').trim();
    if (!txt){
      $('#invCustomerFilterId').val('');
      return;
    }
    const opt = document.querySelector('#invCustomerFilterList option[value="'+ CSS.escape(txt) +'"]');
    if (opt && opt.dataset && opt.dataset.id){
      $('#invCustomerFilterId').val(opt.dataset.id);
    } else {
      $('#invCustomerFilterId').val('');
    }
  }
  $('#invCustomerFilterText').on('input', function(){ syncInvCustomerFilter(); loadInvoices(); });
  $('#invCustomerFilterText').on('change blur', function(){ syncInvCustomerFilter(); loadInvoices(); });
  $('#invDateFrom,#invDateTo').on('change', function(){ $('#invDatePreset').val('custom'); loadInvoices(); });

  // Load branches for filter (admin only)
  function loadInvoiceBranches(){
    const isAdmin = $('#isAdmin').val() === '1';
    const userBranchId = $('#userBranchId').val();
    if (!isAdmin) {
      // Hide branch filter for non-admin users
      $('#invBranchFilter').hide();
      return;
    }
    $.get('api/branches.php', { action:'list' }, function(res){
      const branches=(res.data||[]).filter(b=>parseInt(b.is_active));
      const opts=['<option value="">All Branches</option>'];
      branches.forEach(b=>opts.push(`<option value="${b.id}">${$('<div>').text(b.name).html()}</option>`));
      $('#invBranchFilter').html(opts.join(''));
    });
  }
  loadInvoiceBranches();
  $(document).on('click', '.inv-cancel', function(){
    const id=$(this).data('id'); if(!id) return;
    if(!confirm('Cancel this invoice? This will unreserve any reserved items.')) return;
    const fd=new FormData();
    fd.append('csrf',$('#csrf').val());
    fd.append('id', id);
    fd.append('action','cancel');
    $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
      .done(function(){ loadInvoices(); })
      .fail(function(xhr){ alert((xhr.responseJSON && xhr.responseJSON.message) || 'Failed to cancel'); });
  });
  document.getElementById('tab-fp-btn')?.addEventListener('shown.bs.tab', loadFP);
  document.getElementById('tab-invoices-btn')?.addEventListener('shown.bs.tab', loadInvoices);
  document.getElementById('tab-fp-btn')?.addEventListener('shown.bs.tab', loadFP);

  // Initial loads when page opens (Final Products tab is default active)
  $('#invDatePreset').val('monthly');
  setDatePreset('monthly');
  loadFP();
  loadInvoices();
  loadCustomers();

  // Add FP to cart (uses final_sq_ft if present; otherwise compute from mm -> sqft)
  $(document).on('click', '.btn-add-fp', function(){
    const id=$(this).data('id'); const desc=$(this).data('desc');
    const areaSqft = Number($(this).data('area_sqft')||0) || 0;
    if (cart.find(x=>x.fp_id===id)) return; // prevent duplicate
    cart.push({ fp_id: id, desc, unit:'sqft', area: areaSqft, rate: 0 });
    refreshCart();
  });
  $(document).on('change', '.cart-unit', function(){ const idx=$(this).data('idx'); cart[idx].unit=this.value; refreshCart(); });
  $(document).on('click', '.cart-del', function(){
    const idx=$(this).data('idx');
    const item = cart[idx];
    cart.splice(idx,1);
    refreshCart();
    // If it's a reserved cut piece, unreserve it
    if (item && item.cut_piece_id){
      const csrf=$('#csrf').val();
      $.post('api/slab_cutting.php?action=unreserve_piece', { id: item.cut_piece_id, csrf });
    }
  });

  // Create invoice
  $('#btnCreateInvoice').on('click', function(){
    // Open even if cart is empty; validation happens on submit
    $('#invoiceForm')[0].reset();
    $('#invAction').val('create');
    $('#invId').val('');
    $('#invoiceModal .modal-title').text('Create Invoice');
    $('#invDate').val(new Date().toISOString().slice(0,10));
    // Load invoice number preview
    $.get('api/invoices.php', { action:'generate_no' }, function(res){
      $('#invNoPreview').text(res.invoice_no || 'N/A');
    }).fail(function(){ $('#invNoPreview').text('N/A'); });
    loadCustomers();
    // load modal pickers
    loadFPModal();
    loadCutPiecesModal();
    loadProdPickLookups();
    loadProdPick();
    loadServicesPick();
    // Load payment terms from payment_terms table
    $.get('api/payment_terms.php', { action: 'list' }, function(res){
      const sel = $('#invPayTerm').empty();
      sel.append('<option value=""></option>');
      (res.data || []).forEach(function(x){
        const nm = $('<div>').text(x.name || '').html();
        sel.append(`<option value="${nm}">${nm}</option>`);
      });
    });
    // Pre-load bank accounts and trigger term-based visibility
    loadBankAccounts(function(banks){ populateBankSelect($('#invBankAccountId'), banks); updateInvBankRow(); });
    $('#invBankAccountTopRow').hide();
    // Admin: populate branch filter options
    if ($('#invBranchFilter').length){
      $.get('api/branches.php',{ action:'list' }, function(res){
        const sel = $('#invBranchFilter');
        const rows = res.data || [];
        sel.empty();
        sel.append('<option value="">All Branches</option>');
        rows.forEach(b=>{ if (parseInt(b.is_active)) sel.append(`<option value="${b.id}">${$('<div>').text(b.name||'').html()}</option>`); });
        // default to current session branch if available
        const cur = <?php echo json_encode((int)($_SESSION['branch_id'] ?? 0)); ?>;
        if (cur) sel.val(String(cur));
        // refresh list to respect selected branch
        loadFPModal();
      });
    }
    (function(){
      const el = document.getElementById('invoiceModal');
      if (el && window.bootstrap && bootstrap.Modal) {
        bootstrap.Modal.getOrCreateInstance(el).show();
      } else if (window.jQuery && typeof jQuery.fn.modal === 'function') {
        $('#invoiceModal').modal('show');
      } else {
        // hard fallback
        $('#invoiceModal').show();
      }
    })();
    setTimeout(refreshCart,0);
  });

  function parseDescUnit(desc){
    const m = String(desc||'').match(/\s\[([A-Za-z]+)\]\s*$/);
    if (!m) return { clean: String(desc||''), unit: '' };
    const unit = String(m[1]||'').toLowerCase();
    const clean = String(desc||'').replace(/\s\[[A-Za-z]+\]\s*$/,'').trim();
    return { clean, unit };
  }

  function openInvoiceEdit(id){
    $.get('api/invoices.php', { action:'get', id }, function(res){
      const d = res.data || {}; const inv = d.invoice || {}; const items = d.items || [];
      if (!inv || !inv.id) return;
      if (String(inv.status||'') !== 'draft') { alert('Only Draft invoices can be edited'); return; }

      $('#invoiceForm')[0].reset();
      $('#invAction').val('update');
      $('#invId').val(inv.id);
      $('#invoiceModal .modal-title').text('Edit Invoice');
      // Show actual invoice number when editing
      $('#invNoPreview').text(inv.invoice_no || 'N/A');

      // Load select options then set values
      loadCustomers(function(){
        $('#invCustomer').val(String(inv.customer_id||''));
      });
      $('#invDate').val(inv.invoice_date||new Date().toISOString().slice(0,10));

      // Payment terms
      $.get('api/payment_terms.php', { action: 'list' }, function(ptRes){
        const sel = $('#invPayTerm').empty();
        sel.append('<option value=""></option>');
        (ptRes.data || []).forEach(function(x){
          const nm = $('<div>').text(x.name || '').html();
          sel.append(`<option value="${nm}">${nm}</option>`);
        });
        $('#invPayTerm').val(inv.payment_term||'');
      });

      // Status
      $('#invStatus').val(inv.status||'draft');

      $('#invTax').val(inv.tax_percent ?? 0);
      $('#invDiscountP').val(inv.discount_percent ?? 0);
      $('#invDiscount').val(inv.discount ?? 0);
      $('#invTransport').val(inv.transport_charges ?? 0);
      $('#invAdvance').val('0');
      $('#invNotes').val(inv.notes ?? '');

      // Rebuild cart from invoice items
      cart = (items||[]).map(function(it){
        const parsed = parseDescUnit(it.description||'');
        const u = parsed.unit;
        const cleanDesc = parsed.clean || '';
        if (it.service_id || u === 'ft') {
          return {
            service_id: it.service_id ? Number(it.service_id) : null,
            desc: cleanDesc,
            unit: 'ft',
            qty: Number(it.length_ft ?? it.qty ?? 0),
            rate: Number(it.unit_price||0)
          };
        }
        if (u === 'pcs') {
          return {
            production_item_id: it.production_item_id ? Number(it.production_item_id) : null,
            desc: cleanDesc,
            qty: Number(it.qty||1),
            rate: Number(it.unit_price||0)
          };
        }
        const unit = (u === 'sqm') ? 'sqm' : 'sqft';
        return {
          fp_id: it.final_product_id ? Number(it.final_product_id) : null,
          cut_piece_id: it.cut_piece_id ? Number(it.cut_piece_id) : null,
          production_item_id: null,
          desc: cleanDesc,
          unit: unit,
          area: Number(it.qty||0),
          rate: Number(it.unit_price||0)
        };
      });
      refreshCart();

      // load modal pickers (so user can add more)
      loadFPModal();
      loadCutPiecesModal();
      loadProdPickLookups();
      loadProdPick();
      loadServicesPick();

      (function(){
        const el = document.getElementById('invoiceModal');
        if (el && window.bootstrap && bootstrap.Modal) {
          bootstrap.Modal.getOrCreateInstance(el).show();
        } else if (window.jQuery && typeof jQuery.fn.modal === 'function') {
          $('#invoiceModal').modal('show');
        } else {
          $('#invoiceModal').show();
        }
      })();
    });
  }
  $('#invoiceForm').on('submit', function(e){
    e.preventDefault();
    const $form = $(this);
    if ($form.data('submitting')) return;
    const customer_id=$('#invCustomer').val(); if(!customer_id){ alert('Select customer'); return; }
    const payload=new FormData(this);
    if (!cart.length){ alert('Please add at least one item to the invoice cart.'); return; }
    const items = cart.map(it=>{
      const isProd = !!it.production_item_id;
      const isSvc = !!it.service_id;
      const qty = isProd ? Number(it.qty||1) : (isSvc ? Number(it.qty||0) : (it.unit==='sqm' ? (Number(it.area||0)*0.09290304) : Number(it.area||0)));
      const unitLabel = isProd ? 'PCS' : (isSvc ? String(it.unit||'ft').toUpperCase() : it.unit.toUpperCase());
      const desc = `${it.desc} [${unitLabel}]`;
      return {
        final_product_id: it.fp_id,
        cut_piece_id: it.cut_piece_id,
        production_item_id: it.production_item_id,
        service_id: it.service_id,
        description: desc,
        qty: qty,
        length_ft: (isSvc && String(it.unit||'')==='ft') ? qty : null,
        unit_price: Number(it.rate||0)
      };
    });
    payload.append('items_json', JSON.stringify(items));
    const mode = ($('#invAction').val()==='update') ? 'update' : 'create';
    payload.append('action', mode);
    if (mode==='update') { payload.append('id', $('#invId').val()); }
    const $btn = $form.find('button[type="submit"]');
    const oldTxt = $btn.text();
    $form.data('submitting', true);
    $btn.prop('disabled', true).text('Saving...');
    $.ajax({ url:'api/invoices.php', method:'POST', data:payload, contentType:false, processData:false })
      .done(function(){
        $('#invoiceModal').modal('hide');
        cart=[]; refreshCart(); loadInvoices();
        var tabEl = document.getElementById('tab-invoices-btn');
        if (tabEl && window.bootstrap && bootstrap.Tab) { new bootstrap.Tab(tabEl).show(); }
      })
      .fail(function(xhr){ alert((xhr.responseJSON && xhr.responseJSON.message) || 'Error'); })
      .always(function(){
        $form.data('submitting', false);
        $btn.prop('disabled', false).text(oldTxt);
      });
  });

  // Customer CRUD: open add
  $(document).on('click', '#btnAddCustomer', function(){
    const frm = document.getElementById('customerForm'); if (frm) frm.reset();
    $('#custId').val('');
    openModalById('customerModal');
  });
  $('#customerForm').on('submit', function(e){
    e.preventDefault();
    const fd = new FormData(this);
    const isUpdate = !!$('#custId').val();
    const act = isUpdate ? 'update' : 'create';
    $('#custAction').val(act);
    fd.append('action', act);
    const $btn = $('#customerForm button[type="submit"]'); const oldTxt = $btn.text(); $btn.prop('disabled', true).text('Saving...');
    // Basic client-side validation
    if (!($('#custName').val()||'').trim()) { $btn.prop('disabled', false).text(oldTxt); showToast('Customer Name is required','error'); return; }
    $.ajax({ url:'api/customers.php', method:'POST', data:fd, contentType:false, processData:false })
      .done(function(){ hideModalById('customerModal'); document.getElementById('customerForm').reset(); loadCustomers(); showToast('Customer saved','success'); })
      .fail(function(xhr){ const msg=(xhr.responseJSON&&xhr.responseJSON.message)||'Error'; showToast(msg,'error'); })
      .always(function(){ $btn.prop('disabled', false).text(oldTxt); });
  });

  // Edit customer open
  $(document).on('click','.cust-edit', function(){
    const id=$(this).data('id');
    $.get('api/customers.php', { action:'get', id }, function(res){
      const c=res.data||{};
      $('#custId').val(c.id);
      $('#custName').val(c.name||'');
      $('#custCompany').val(c.company_name||'');
      $('#custEmail').val(c.email||'');
      $('#custPhone').val(c.phone||'');
      $('#custAddress').val(c.address||'');
      $('#custCity').val(c.city||'');
      $('#custState').val(c.state||'');
      $('#custCountry').val(c.country||'');
      $('#custGST').val(c.gst_no||'');
      $('#customerModal').modal('show');
    });
  });

  // Delete customer
  $(document).on('click','.cust-del', function(){
    if(!confirm('Delete this customer?')) return;
    const id=$(this).data('id');
    const fd=new FormData(); fd.append('csrf',$('#customerForm [name="csrf"]').val()); fd.append('action','delete'); fd.append('id', id);
    $.ajax({ url:'api/customers.php', method:'POST', data:fd, contentType:false, processData:false })
      .done(()=>loadCustomers())
      .fail(xhr=>alert((xhr.responseJSON&&xhr.responseJSON.message)||'Error'));
  });

  // -------- Invoice View & Payments --------
  function openInvoice(id){
    $.get('api/invoices.php', { action:'get', id }, function(res){
      const d = res.data || {}; const inv = d.invoice || {}; const items = d.items || []; const pays = d.payments || [];
      _currentInvoiceStatus = inv.status || '';
      $('#iv_no').text(inv.invoice_no||'');
      $('#iv_date').text(inv.invoice_date||'');
      $('#iv_status').text(inv.status||'');
      $('#iv_customer').text(inv.customer_name||'');
      $('#iv_address').text(inv.address||'');
      $('#iv_contact').text([inv.phone, inv.email].filter(Boolean).join(' | '));
      $('#iv_taxp').text(inv.tax_percent||0);
      $('#iv_subtotal').text(fmt(inv.subtotal||0));
      $('#iv_tax').text(fmt(inv.tax_amount||0));
      $('#iv_disc').text(fmt(inv.discount||0));
      $('#iv_total').text(fmt(inv.grand_total||0));
      const $itb = $('#iv_items tbody'); $itb.empty();
      items.forEach(it=>{
        const tr = $('<tr>');
        tr.append(`<td>${$('<div>').text(it.description||'').html()}</td>`);
        tr.append(`<td class="text-end">${it.qty??1}</td>`);
        tr.append(`<td class="text-end">${fmt(it.unit_price||0)}</td>`);
        tr.append(`<td class="text-end">${fmt(it.line_total||0)}</td>`);
        const remaining = Math.max(0, Number(it.qty||0) - Number(it.returned_qty||0));
        const btns = [
          `<button type="button" class="btn btn-sm btn-outline-primary iv-item-edit" data-id="${it.id}"><i class="bi bi-pencil"></i></button>`,
          `<button type="button" class="btn btn-sm btn-outline-danger iv-item-del" data-id="${it.id}"><i class="bi bi-trash"></i></button>`,
          `<button type="button" class="btn btn-sm btn-outline-warning iv-item-return" data-id="${it.id}" data-qty="${remaining}" title="Return"><i class="bi bi-arrow-counterclockwise"></i></button>`
        ].join(' ');
        tr.append(`<td>${btns}</td>`);
        $itb.append(tr);
      });
      const $ptb=$('#iv_payments tbody'); $ptb.empty();
      if(!pays.length){ $ptb.append('<tr><td colspan="4" class="text-center text-muted">No payments</td></tr>'); }
      pays.forEach(p=>{
        const tr=$('<tr>');
        tr.attr('data-payment-id', p.id);
        tr.attr('data-payment-type', p.payment_type || 'normal');
        tr.attr('data-is-reversed', p.is_reversed || 0);
        const isReversal = (p.payment_type === 'reversal');
        const isReversed = (p.is_reversed == 1);
        const rowClass = isReversal ? 'table-warning' : (isReversed ? 'table-secondary' : '');
        if (rowClass) tr.addClass(rowClass);
        tr.append(`<td>${p.pay_date||''}${isReversal ? ' <span class="badge bg-warning text-dark">Reversal</span>' : ''}${isReversed ? ' <span class="badge bg-secondary">Reversed</span>' : ''}</td>`);
        tr.append(`<td>${$('<div>').text(p.method||'').html()}</td>`);
        tr.append(`<td>${$('<div>').text(p.reference_no||'').html()}</td>`);
        tr.append(`<td class="text-end">${fmt(p.amount||0)}</td>`);
        $ptb.append(tr);
      });
      const paidTotal = (pays||[]).reduce((s,p)=> s + Number(p.amount||0), 0);
      $('#iv_paid').text(fmt(paidTotal));
      const balance = Math.max(0, Number(inv.grand_total||0) - paidTotal);
      $('#iv_balance').text(fmt(balance));
      $('#btnIssueInvoice').toggle(inv.status==='draft').data('id', inv.id);
      // allow delete only for cancelled invoices and only for superadmin
      const isSuperAdmin = $('#isSuperAdmin').val() === '1';
      $('#btnDeleteInvoice').toggle(inv.status==='cancelled' && isSuperAdmin).data('id', inv.id);
      // optional cancel (keep existing if needed)
      $('#btnCancelInvoice').toggle(inv.status!=='cancelled' && inv.status!=='paid').data('id', inv.id).off('click').on('click', function(){
        const id=$(this).data('id'); if(!id) return;
        const fd = new FormData();
        fd.append('csrf', $('#invoiceForm [name="csrf"]').val());
        fd.append('id', id);
        fd.append('action','cancel');
        $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
          .done(function(){ loadInvoices(); openInvoice(id); })
          .fail(function(xhr){ alert((xhr.responseJSON && xhr.responseJSON.message) || 'Error'); });
      });
      const disablePay = (balance<=0) || (inv.status==='draft') || (inv.status==='cancelled');
      $('#btnAddPaymentOpen').prop('disabled', disablePay).off('click').on('click', function(){
        $('#pay_invoice_id').val(inv.id);
        $('#pay_date').val(new Date().toISOString().slice(0,10));
        // Set balance info and cap amount
        $('#pay_balance').text(fmt(balance));
        const $amt = $('#pay_amount');
        $amt.attr('max', balance.toFixed(2));
        const cur = parseFloat($amt.val()||'0');
        if (!(cur>0) || cur>balance) { $amt.val(balance>0 ? balance.toFixed(2) : ''); }
        loadBankAccounts(function(banks){
          populateBankSelect($('#pay_bank_account_id'), banks);
          updatePayBankRow();
        });
        $('#paymentModal').modal('show');
      });
      // Set print link to standalone page (no app header/sidebar)
      var __printBase = <?php echo json_encode(url_for("pages/invoice_print.php")); ?>;
      $('#btnPrintInvoice').attr('href', __printBase + '?id=' + encodeURIComponent(inv.id));
      $('#invoiceViewModal').modal('show');
      // Add action buttons to payment rows
      augmentPaymentRows(_currentInvoiceStatus);
    });
  }

  $(document).on('click', '.btn-view-invoice', function(){ openInvoice($(this).data('id')); });
  $(document).on('click', '.btn-edit-invoice', function(){ openInvoiceEdit($(this).data('id')); });
  $('#btnIssueInvoice').on('click', function(){
    const id = $(this).data('id'); if(!id) return;
    const fd = new FormData();
    fd.append('csrf', $('#invoiceForm [name="csrf"]').val());
    fd.append('id', id);
    fd.append('action','issue');
    $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
      .done(function(){ loadInvoices(); openInvoice(id); })
      .fail(function(xhr){ alert((xhr.responseJSON && xhr.responseJSON.message) || 'Error'); });
  });

  $('#paymentForm').on('submit', function(e){
    e.preventDefault();
    // Basic validation to avoid server 'Invalid input'
    const invId = ($('#pay_invoice_id').val()||'').trim();
    const amt = parseFloat($('#pay_amount').val()||'0');
    if (!invId) { alert('Missing invoice. Please reopen the invoice and try again.'); return; }
    if (!(amt>0)) { alert('Amount must be greater than 0'); return; }
    const fd = new FormData(this);
    const isEditMode = $('#paymentForm').data('edit-mode');
    const editIdx = $('#paymentForm').data('edit-index');
    if (isEditMode && editIdx !== undefined) {
      // Update existing payment
      $.get('api/invoices.php', { action:'get', id: invId }, function(res){
        const pays=res.data.payments||[];
        const p=pays[editIdx]; if (!p) { alert('Payment not found'); return; }
        fd.append('action','update_payment');
        fd.append('id', p.id);
        $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
          .done(()=>{
            $('#paymentModal').modal('hide');
            $('#paymentForm').data('edit-mode', false).removeData('edit-index');
            $('#paymentModal .modal-title').text('Add Payment');
            loadInvoices();
            openInvoice(invId);
          })
          .fail(xhr=>{ alert((xhr.responseJSON && xhr.responseJSON.message) || 'Error'); });
      });
    } else {
      // Add new payment
      fd.append('action','add_payment');
      $.ajax({ url:'api/invoices.php', method:'POST', data:fd, contentType:false, processData:false })
        .done(()=>{ $('#paymentModal').modal('hide'); loadInvoices(); openInvoice($('#pay_invoice_id').val()); })
        .fail(xhr=>{ alert((xhr.responseJSON && xhr.responseJSON.message) || 'Error'); });
    }
  });

});
})(window.jQuery);
</script>
