<?php
// view: pages/sales/invoice_form
$invoice = $invoice ?? [];
$lines = $lines ?? [];
$warehouses = $warehouses ?? [];
$customer = $customer ?? null;
$party = $customer;
$cashboxes = $cashboxes ?? [];
$isEdit = (bool)($isEdit ?? false);

if (!$lines) {
  $lines = [[
    'item_id'=>0,
    'item_name'=>'',
    'qty'=>1,
    'price'=>0,
    'line_total'=>0,
  ]];
}
?>

<div class="page-actions-bar sales-invoice-page__actions">
  <a class="btn btn-outline-dark btn-back" data-shortcut="back" href="<?= e(url($sales_invoices_url ?? '/sales/invoices')) ?>">رجوع</a>
</div>

<form method="post" id="saleForm" class="form-shell sales-invoice-page" novalidate>
  <?= csrf_field() ?>

  <section class="sales-invoice-hero card p-3 p-lg-4">
    <div class="sales-invoice-hero__head">
      <div>
        <div class="sales-invoice-hero__eyebrow">فاتورة مبيعات</div>
        <h2 class="sales-invoice-hero__title mb-1"><?= $isEdit ? 'تعديل فاتورة بيع' : 'إنشاء فاتورة بيع' ?></h2>
        <div class="sales-invoice-hero__hint">ابدأ ببيانات الفاتورة ثم أضف الأصناف، وسيتم تحديث الإجماليات والدفع تلقائيًا.</div>
      </div>
      <div class="sales-invoice-hero__quick-summary">
        <div class="sales-invoice-pill">
          <span>العميل</span>
          <strong id="customer_preview_label"><?= e((string)($invoice['party_label'] ?? $invoice['customer_label'] ?? ($party ? ($party['name'].' ('.$party['code'].')') : 'غير محدد'))) ?></strong>
        </div>
        <div class="sales-invoice-pill">
          <span>المخزن</span>
          <strong id="warehouse_preview_label"><?= e((string)($warehouses[0]['name'] ?? '—')) ?></strong>
        </div>
        <div class="sales-invoice-pill sales-invoice-pill--accent">
          <span>الإجمالي الحالي</span>
          <strong id="hero_grand_total">0</strong>
        </div>
      </div>
    </div>

    <div class="row g-3 mt-1">
      <div class="col-lg-2 col-md-3">
        <label class="form-label">التاريخ</label>
        <input type="date" class="form-control" name="invoice_date" value="<?= e(substr((string)$invoice['invoice_date'],0,10)) ?>">
      </div>
      <div class="col-lg-3 col-md-3">
        <label class="form-label">المخزن</label>
        <select class="form-select" name="warehouse_id" id="warehouse_id">
          <?php foreach ($warehouses as $w): ?>
            <option value="<?= (int)$w['id'] ?>" <?= ((int)($invoice['warehouse_id'] ?? 0)===(int)$w['id'])?'selected':'' ?>><?= e($w['name']) ?></option>
          <?php endforeach; ?>
        </select>
      </div>
      <div class="col-lg-7 col-md-6">
        <label class="form-label">الطرف / العميل</label>
        <div class="sales-customer-box position-relative">
          <input type="hidden" name="party_id" id="party_id" value="<?= (int)($invoice['party_id'] ?? $invoice['customer_id'] ?? 0) ?>">
          <input type="hidden" name="customer_id" id="customer_id" value="<?= (int)($invoice['party_id'] ?? $invoice['customer_id'] ?? 0) ?>">
          <input type="hidden" name="party_label" id="party_label" value="<?= e((string)($invoice['party_label'] ?? $invoice['customer_label'] ?? ($party ? ($party['name'].' ('.$party['code'].')') : ''))) ?>">
          <input type="hidden" name="customer_label" id="customer_label" value="<?= e((string)($invoice['party_label'] ?? $invoice['customer_label'] ?? ($party ? ($party['name'].' ('.$party['code'].')') : ''))) ?>">
          <input type="text" class="form-control sales-customer-box__input" id="customer_search" placeholder="ابحث بالاسم / الكود / الموبايل" value="<?= e((string)($invoice['party_label'] ?? $invoice['customer_label'] ?? ($party ? ($party['name'].' ('.$party['code'].')') : ''))) ?>" autocomplete="off">
          <div class="sales-autocomplete sales-autocomplete--customer" id="customer_results" hidden></div>
        </div>
        <div class="form-text">يفضل اختيار العميل من القائمة لضمان الربط الصحيح مع المديونية وكشف الحساب.</div>
      </div>
    </div>
  </section>

  <div class="sales-invoice-grid">
    <section class="sales-lines-card card p-3 p-lg-4">
      <div class="sales-section-head">
        <div>
          <div class="sales-section-head__title">الأصناف</div>
          <div class="sales-section-head__meta">ابحث بالاسم أو الكود أو الباركود. Enter للاختيار و F2 لإضافة سطر جديد.</div>
        </div>
        <button type="button" class="btn btn-primary sales-add-line-btn" id="addLineBtn">F2 إضافة صنف</button>
      </div>

      <div class="sales-lines-wrap">
        <table class="table sales-lines-table align-middle mb-0" id="linesTable">
          <thead>
            <tr>
              <th style="width:48%">الصنف</th>
              <th style="width:12%" class="text-end">الكمية</th>
              <th style="width:14%" class="text-end">السعر</th>
              <th style="width:16%" class="text-end">الإجمالي</th>
              <th style="width:10%" class="text-center">إجراءات</th>
            </tr>
          </thead>
          <tbody>
            <?php foreach ($lines as $idx => $ln): ?>
              <tr class="sales-line-row">
                <td>
                  <div class="sales-item-field">
                    <input type="hidden" name="item_id[]" class="item-id" value="<?= (int)($ln['item_id'] ?? 0) ?>">
                    <input type="text" class="form-control item-search" name="item_name[]" value="<?= e(($ln['item_name'] ?? '') ?: '') ?>" placeholder="ابحث عن الصنف أو الباركود" autocomplete="off">
                    <div class="sales-autocomplete item-results" hidden></div>
                  </div>
                </td>
                <td><input type="number" step="1" min="1" inputmode="numeric" name="qty[]" class="form-control text-end qty" value="<?= e((string)($ln['qty'] ?? 1)) ?>"></td>
                <td><input type="number" step="0.01" min="0" name="price[]" class="form-control text-end price" value="<?= e((string)($ln['price'] ?? 0)) ?>"></td>
                <td>
                  <div class="sales-line-total-box text-end">
                    <span class="line-total">0</span>
                  </div>
                </td>
                <td>
                  <div class="sales-line-actions">
                    <button type="button" class="btn btn-outline-primary btn-sm sales-line-action sales-line-add">+</button>
                    <button type="button" class="btn btn-outline-danger btn-sm sales-line-action del-line">×</button>
                  </div>
                </td>
              </tr>
            <?php endforeach; ?>
          </tbody>
        </table>
      </div>
    </section>

    <aside class="sales-side-panel">
      <div class="card sales-side-card p-3">
        <div class="sales-side-card__title">السداد</div>
        <div class="row g-2">
          <div class="col-12">
            <label class="form-label">نوع السداد</label>
            <select class="form-select" name="payment_mode" id="payment_mode">
              <option value="cash" <?= (($invoice['payment_mode'] ?? 'credit')==='cash')?'selected':'' ?>>نقدي</option>
              <option value="credit" <?= (($invoice['payment_mode'] ?? 'credit')==='credit')?'selected':'' ?>>آجل</option>
              <option value="partial" <?= (($invoice['payment_mode'] ?? 'credit')==='partial')?'selected':'' ?>>جزئي</option>
            </select>
          </div>
          <div class="col-12" id="paid_amount_group">
            <label class="form-label">المدفوع الآن</label>
            <input type="number" step="0.01" min="0" class="form-control" name="paid_amount" id="paid_amount" value="<?= e((string)($invoice['paid_amount'] ?? 0)) ?>">
          </div>
          <div class="col-12">
            <label class="form-label">الخزنة</label>
            <select class="form-select" name="cashbox_id" id="cashbox_id">
              <option value="0">-- بدون --</option>
              <?php foreach ($cashboxes as $cb): ?>
                <option value="<?= (int)$cb['id'] ?>" <?= ((int)($invoice['cashbox_id'] ?? 0)===(int)$cb['id'])?'selected':'' ?>><?= e($cb['name']) ?></option>
              <?php endforeach; ?>
            </select>
          </div>
          <div class="col-12">
            <label class="form-label">ملاحظة التحصيل</label>
            <input type="text" class="form-control" name="collection_note" id="collection_note" value="<?= e((string)($invoice['collection_note'] ?? '')) ?>" placeholder="تظهر في قيد التحصيل وحركة الخزنة">
          </div>
          <div class="col-12 small text-muted">النقدي = كامل الفاتورة، الآجل = بدون تحصيل، الجزئي = جزء للخزنة والباقي مديونية.</div>
        </div>
      </div>

      <div class="card sales-side-card p-3">
        <div class="sales-side-card__title">الخصم والضريبة</div>
        <div class="row g-2">
          <div class="col-5">
            <label class="form-label">نوع الخصم</label>
            <select class="form-select" name="discount_type" id="discount_type">
              <option value="PERCENT" <?= (strtoupper((string)($invoice['discount_type'] ?? ''))==='PERCENT')?'selected':'' ?>>%</option>
              <option value="VALUE" <?= (strtoupper((string)($invoice['discount_type'] ?? ''))==='VALUE')?'selected':'' ?>>قيمة</option>
            </select>
          </div>
          <div class="col-7">
            <label class="form-label">قيمة الخصم</label>
            <input type="number" step="0.01" min="0" class="form-control" name="discount_value" id="discount_value" value="<?= e((string)($invoice['discount_value'] ?? 0)) ?>">
          </div>
          <div class="col-12">
            <label class="form-label">ملاحظات الخصم</label>
            <input type="text" class="form-control" name="discount_note" value="<?= e((string)($invoice['discount_note'] ?? '')) ?>">
          </div>
          <div class="col-6 d-flex align-items-center">
            <div class="form-check mt-3">
              <input class="form-check-input" type="checkbox" name="vat_enabled" id="vat_enabled" <?= !empty($invoice['vat_enabled'])?'checked':'' ?>>
              <label class="form-check-label" for="vat_enabled">تفعيل VAT</label>
            </div>
          </div>
          <div class="col-6">
            <label class="form-label">نسبة VAT %</label>
            <input type="number" step="0.01" min="0" class="form-control" name="vat_rate" id="vat_rate" value="<?= e((string)($invoice['vat_rate'] ?? 0)) ?>">
          </div>
        </div>
      </div>

      <div class="card sales-side-card sales-side-card--totals p-3">
        <div class="sales-side-card__title">الإجماليات</div>
        <div class="sales-total-row"><span>الإجمالي قبل الخصم</span><strong id="subtotal">0</strong></div>
        <div class="sales-total-row"><span>قيمة الخصم</span><strong id="discount_amount">0</strong></div>
        <div class="sales-total-row"><span>الصافي بعد الخصم</span><strong id="net">0</strong></div>
        <div class="sales-total-row"><span>VAT</span><strong id="vat_amount">0</strong></div>
        <div class="sales-total-divider"></div>
        <div class="sales-total-row sales-total-row--grand"><span>الإجمالي</span><strong id="grand">0</strong></div>
        <div class="sales-total-row"><span>المدفوع الآن</span><strong id="paid_preview">0</strong></div>
        <div class="sales-total-row sales-total-row--due"><span>المتبقي</span><strong id="due_preview">0</strong></div>
      </div>
    </aside>
  </div>

  <section class="card sales-notes-card p-3 p-lg-4">
    <label class="form-label">ملاحظات</label>
    <textarea class="form-control" name="notes" rows="3" placeholder="أي ملاحظات إضافية على الفاتورة أو التسليم"><?= e((string)($invoice['notes'] ?? '')) ?></textarea>
  </section>

  <div class="sales-submit-bar">
    <input type="hidden" name="action" id="sales_submit_action" value="save">
    <button class="btn btn-outline-dark" type="submit" data-submit-action="save">حفظ كمسودة</button>
    <button class="btn btn-primary" type="submit" data-submit-action="post">حفظ وترحيل</button>
  </div>
</form>

<script>
(function(){
  const form = document.getElementById('saleForm');
  const tableBody = document.querySelector('#linesTable tbody');
  const addLineBtn = document.getElementById('addLineBtn');
  const paymentModeEl = document.getElementById('payment_mode');
  const paidAmountEl = document.getElementById('paid_amount');
  const paidAmountGroup = document.getElementById('paid_amount_group');
  const cashboxEl = document.getElementById('cashbox_id');
  const customerSearch = document.getElementById('customer_search');
  const customerResults = document.getElementById('customer_results');
  const discountTypeEl = document.getElementById('discount_type');
  const discountValueEl = document.getElementById('discount_value');
  const vatEnabledEl = document.getElementById('vat_enabled');
  const vatRateEl = document.getElementById('vat_rate');
  const warehouseEl = document.getElementById('warehouse_id');
  const customerPreviewLabel = document.getElementById('customer_preview_label');
  const warehousePreviewLabel = document.getElementById('warehouse_preview_label');
  const heroGrandTotal = document.getElementById('hero_grand_total');
  let submitLocked = false;

  function parseNumber(value){
    const cleaned = String(value ?? '').replace(/,/g, '').trim();
    const n = Number(cleaned);
    return Number.isFinite(n) ? n : 0;
  }

  function formatNumber(value, decimals = 2){
    const n = Number(value || 0);
    const fixed = n.toFixed(decimals);
    return fixed.replace(/\.0+$/, '').replace(/(\.\d*?)0+$/, '$1');
  }

  function normalizeInput(input, decimals){
    if (!input) return;
    input.value = formatNumber(Math.max(0, parseNumber(input.value)), decimals);
  }

  function parseQty(value){
    const n = Math.trunc(Math.max(0, parseNumber(value)));
    return Number.isFinite(n) ? n : 0;
  }

  function normalizeQtyInput(input, allowEmpty = false){
    if (!input) return;
    const raw = String(input.value ?? '').trim();
    if (raw === '') {
      input.value = allowEmpty ? '' : '1';
      return;
    }
    const qty = parseQty(raw);
    input.value = String(Math.max(1, qty));
  }

  function currentRows(){
    return Array.from(tableBody.querySelectorAll('tr'));
  }

  function ensureOneEmptyRow(){
    if (!currentRows().length) addRow();
  }

  function getSelectedItemIds(exceptRow = null){
    return currentRows().filter(row => row !== exceptRow).map(row => Number(row.querySelector('.item-id')?.value || 0)).filter(Boolean);
  }

  function closeBox(box){
    if (!box) return;
    box.hidden = true;
    box.innerHTML = '';
  }

  function updateHeroLabels(){
    if (warehousePreviewLabel && warehouseEl) {
      warehousePreviewLabel.textContent = warehouseEl.options[warehouseEl.selectedIndex]?.text || '—';
    }
    if (customerPreviewLabel) {
      customerPreviewLabel.textContent = customerSearch?.value?.trim() || 'غير محدد';
    }
  }

  function recalc(){
    let subtotal = 0;
    currentRows().forEach(row => {
      const qty = Math.max(0, parseQty(row.querySelector('.qty')?.value));
      const price = Math.max(0, parseNumber(row.querySelector('.price')?.value));
      const lineTotal = qty * price;
      const lineTotalEl = row.querySelector('.line-total');
      if (lineTotalEl) lineTotalEl.textContent = formatNumber(lineTotal, 2);
      subtotal += lineTotal;
    });

    const discountType = String(discountTypeEl?.value || 'PERCENT').toUpperCase();
    const discountValue = Math.max(0, parseNumber(discountValueEl?.value));
    let discountAmount = discountType === 'VALUE' ? discountValue : subtotal * (discountValue / 100);
    if (discountAmount > subtotal) discountAmount = subtotal;
    const net = subtotal - discountAmount;
    const vatRate = Math.max(0, parseNumber(vatRateEl?.value));
    const vatAmount = vatEnabledEl?.checked ? net * (vatRate / 100) : 0;
    const grand = net + vatAmount;

    const paymentMode = String(paymentModeEl?.value || 'credit').toLowerCase();
    let paid = Math.max(0, parseNumber(paidAmountEl?.value));
    if (paymentMode === 'cash') {
      paid = grand;
      if (paidAmountEl) {
        paidAmountEl.value = formatNumber(paid, 2);
        paidAmountEl.readOnly = true;
        paidAmountEl.setAttribute('tabindex', '-1');
      }
      paidAmountGroup?.classList.add('d-none');
      if (cashboxEl && parseNumber(cashboxEl.value) <= 0 && cashboxEl.options.length > 1) cashboxEl.selectedIndex = 1;
    } else if (paymentMode === 'credit') {
      paid = 0;
      if (paidAmountEl) {
        paidAmountEl.value = '0';
        paidAmountEl.readOnly = true;
        paidAmountEl.setAttribute('tabindex', '-1');
      }
      paidAmountGroup?.classList.add('d-none');
    } else {
      paidAmountGroup?.classList.remove('d-none');
      if (paidAmountEl) {
        paidAmountEl.readOnly = false;
        paidAmountEl.removeAttribute('tabindex');
      }
      if (paid > grand) {
        paid = grand;
        if (paidAmountEl) paidAmountEl.value = formatNumber(paid, 2);
      }
    }

    const due = Math.max(0, grand - paid);
    document.getElementById('subtotal').textContent = formatNumber(subtotal, 2);
    document.getElementById('discount_amount').textContent = formatNumber(discountAmount, 2);
    document.getElementById('net').textContent = formatNumber(net, 2);
    document.getElementById('vat_amount').textContent = formatNumber(vatAmount, 2);
    document.getElementById('grand').textContent = formatNumber(grand, 2);
    document.getElementById('paid_preview').textContent = formatNumber(paid, 2);
    document.getElementById('due_preview').textContent = formatNumber(due, 2);
    if (heroGrandTotal) heroGrandTotal.textContent = formatNumber(grand, 2);
    updateHeroLabels();
  }

  function resultLabel(item){
    const code = item.code || ('I' + String(item.id).padStart(5, '0'));
    const barcode = item.barcode ? ' — ' + item.barcode : '';
    return `${item.name} (${code})${barcode}`;
  }

  async function fetchItems(query){
    const response = await fetch(<?= json_encode(url('/ajax/items/search')) ?> + '?q=' + encodeURIComponent(query));
    const data = await response.json();
    return Array.isArray(data) ? data : [];
  }

  function setAutocompleteContent(box, rows, activeIndex, mapper){
    box.innerHTML = rows.map((row, idx) => mapper(row, idx === activeIndex)).join('');
    box.hidden = rows.length === 0;
  }

  function attachCustomerAutocomplete(){
    if (!customerSearch || !customerResults) return;
    let timer = null;
    let rows = [];
    let activeIndex = -1;

    function close(){
      closeBox(customerResults);
      rows = [];
      activeIndex = -1;
    }

    function choose(row){
      document.getElementById('customer_id').value = row.id;
      document.getElementById('party_id').value = row.id;
      customerSearch.value = `${row.name} (${row.code})`;
      document.getElementById('customer_label').value = customerSearch.value;
      document.getElementById('party_label').value = customerSearch.value;
      updateHeroLabels();
      close();
    }

    function render(){
      setAutocompleteContent(customerResults, rows, activeIndex, (row, isActive) => `
        <button type="button" class="sales-autocomplete__item${isActive ? ' is-active' : ''}" data-id="${row.id}">
          <span class="sales-autocomplete__title">${row.name}</span>
          <span class="sales-autocomplete__meta">${row.code || ''}</span>
        </button>`);
    }

    customerSearch.addEventListener('input', () => {
      clearTimeout(timer);
      const q = customerSearch.value.trim();
      if (!q) {
        document.getElementById('customer_id').value = '0';
        document.getElementById('party_id').value = '0';
        document.getElementById('customer_label').value = '';
        document.getElementById('party_label').value = '';
        updateHeroLabels();
        close();
        return;
      }
      document.getElementById('customer_id').value = '0';
      document.getElementById('party_id').value = '0';
      timer = setTimeout(async () => {
        try {
          const response = await fetch(<?= json_encode(url('/ajax/customers/search')) ?> + '?q=' + encodeURIComponent(q));
          const data = await response.json();
          rows = Array.isArray(data) ? data.slice(0, 12) : [];
          activeIndex = rows.length ? 0 : -1;
          render();
        } catch (_) {
          close();
        }
      }, 180);
    });

    customerSearch.addEventListener('keydown', (e) => {
      if (customerResults.hidden || !rows.length) {
        if (e.key === 'Enter' && Number(document.getElementById('party_id').value || 0) <= 0 && customerSearch.value.trim() !== '') {
          e.preventDefault();
        }
        return;
      }
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        activeIndex = (activeIndex + 1) % rows.length;
        render();
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        activeIndex = (activeIndex - 1 + rows.length) % rows.length;
        render();
      } else if (e.key === 'Enter') {
        e.preventDefault();
        if (rows[activeIndex]) choose(rows[activeIndex]);
      } else if (e.key === 'Escape') {
        close();
      }
    });

    customerResults.addEventListener('mousedown', (e) => {
      const item = e.target.closest('[data-id]');
      if (!item) return;
      e.preventDefault();
      const row = rows.find(entry => Number(entry.id) === Number(item.dataset.id));
      if (row) choose(row);
    });

    customerSearch.addEventListener('change', () => {
      document.getElementById('customer_label').value = customerSearch.value.trim();
      document.getElementById('party_label').value = customerSearch.value.trim();
      updateHeroLabels();
    });

    document.addEventListener('click', (e) => {
      if (!customerResults.contains(e.target) && e.target !== customerSearch) close();
    });
  }

  function bindRow(row){
    const search = row.querySelector('.item-search');
    const results = row.querySelector('.item-results');
    const itemIdInput = row.querySelector('.item-id');
    const qtyInput = row.querySelector('.qty');
    const priceInput = row.querySelector('.price');
    const deleteBtn = row.querySelector('.del-line');
    const plusBtn = row.querySelector('.sales-line-add');
    if (!search || !results || !itemIdInput || !qtyInput || !priceInput || !deleteBtn) return;
    if (Number(itemIdInput.value || 0) > 0 && search.value.trim() !== '') search.dataset.selectedLabel = search.value.trim();

    let timer = null;
    let items = [];
    let activeIndex = -1;

    function close(){
      closeBox(results);
      items = [];
      activeIndex = -1;
    }

    function render(){
      setAutocompleteContent(results, items, activeIndex, (item, isActive) => `
        <button type="button" class="sales-autocomplete__item${isActive ? ' is-active' : ''}" data-id="${item.id}">
          <span class="sales-autocomplete__title">${item.name}</span>
          <span class="sales-autocomplete__meta">${item.code || ''}${item.barcode ? ' • ' + item.barcode : ''}</span>
        </button>`);
    }

    function pick(item){
      if (getSelectedItemIds(row).includes(Number(item.id))) {
        alert('هذا الصنف موجود بالفعل داخل الفاتورة. عدّل الكمية في السطر الحالي بدل تكراره.');
        close();
        search.focus();
        return;
      }
      itemIdInput.value = item.id;
      search.value = item.name;
      search.dataset.selectedLabel = item.name;
      if (parseNumber(priceInput.value) <= 0) priceInput.value = formatNumber(item.price ?? 0, 2);
      if (parseQty(qtyInput.value) <= 0) qtyInput.value = '1';
      else normalizeQtyInput(qtyInput);
      close();
      recalc();
      qtyInput.focus();
      qtyInput.select?.();
    }

    search.addEventListener('input', () => {
      clearTimeout(timer);
      const q = search.value.trim();
      if (search.dataset.selectedLabel && q !== search.dataset.selectedLabel) itemIdInput.value = '0';
      if (!q) {
        itemIdInput.value = '0';
        close();
        return;
      }
      timer = setTimeout(async () => {
        try {
          items = (await fetchItems(q)).slice(0, 12);
          if (items.length === 1) {
            const single = items[0];
            if ((single.barcode && String(single.barcode).trim() === q) || (single.code && String(single.code).trim() === q)) {
              pick(single);
              return;
            }
          }
          activeIndex = items.length ? 0 : -1;
          render();
        } catch (_) {
          close();
        }
      }, 120);
    });

    search.addEventListener('keydown', (e) => {
      const visible = !results.hidden && items.length > 0;
      if (e.key === 'Enter') {
        e.preventDefault();
        e.stopImmediatePropagation();
        if (visible && items[activeIndex]) {
          pick(items[activeIndex]);
        } else if (search.value.trim() !== '' && Number(itemIdInput.value || 0) <= 0) {
          alert('اختر الصنف من القائمة أو امسح السطر قبل الحفظ.');
        } else {
          qtyInput.focus();
          qtyInput.select?.();
        }
        return;
      }
      if (!visible) return;
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        activeIndex = (activeIndex + 1) % items.length;
        render();
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        activeIndex = (activeIndex - 1 + items.length) % items.length;
        render();
      } else if (e.key === 'Escape') {
        e.preventDefault();
        close();
      }
    });

    results.addEventListener('mousedown', (e) => {
      const item = e.target.closest('[data-id]');
      if (!item) return;
      e.preventDefault();
      const picked = items.find(entry => Number(entry.id) === Number(item.dataset.id));
      if (picked) pick(picked);
    });

    qtyInput.addEventListener('input', () => {
      qtyInput.value = qtyInput.value.replace(/[^\d]/g, '');
      recalc();
    });
    qtyInput.addEventListener('blur', () => {
      normalizeQtyInput(qtyInput);
      recalc();
    });
    qtyInput.addEventListener('keydown', (e) => {
      if (['.', ',', 'e', 'E', '+', '-'].includes(e.key)) {
        e.preventDefault();
        return;
      }
      if (e.key === 'Enter') {
        e.preventDefault();
        priceInput.focus();
        priceInput.select?.();
      }
    });

    priceInput.addEventListener('input', recalc);
    priceInput.addEventListener('blur', () => {
      normalizeInput(priceInput, 2);
      recalc();
    });
    priceInput.addEventListener('keydown', (e) => {
      if (e.key === 'Enter') {
        e.preventDefault();
        const nextRow = row.nextElementSibling;
        if (nextRow) nextRow.querySelector('.item-search')?.focus();
        else addRow();
      }
    });

    deleteBtn.addEventListener('click', () => {
      const nextFocus = row.nextElementSibling?.querySelector('.item-search') || row.previousElementSibling?.querySelector('.item-search');
      row.remove();
      ensureOneEmptyRow();
      recalc();
      nextFocus?.focus();
    });

    plusBtn?.addEventListener('click', () => addRow(row));
  }

  function addRow(afterRow = null){
    const tr = document.createElement('tr');
    tr.className = 'sales-line-row';
    tr.innerHTML = `
      <td>
        <div class="sales-item-field">
          <input type="hidden" name="item_id[]" class="item-id" value="0">
          <input type="text" class="form-control item-search" name="item_name[]" placeholder="ابحث عن الصنف أو الباركود" autocomplete="off">
          <div class="sales-autocomplete item-results" hidden></div>
        </div>
      </td>
      <td><input type="number" step="1" min="1" inputmode="numeric" name="qty[]" class="form-control text-end qty" value="1"></td>
      <td><input type="number" step="0.01" min="0" name="price[]" class="form-control text-end price" value="0"></td>
      <td><div class="sales-line-total-box text-end"><span class="line-total">0</span></div></td>
      <td><div class="sales-line-actions"><button type="button" class="btn btn-outline-primary btn-sm sales-line-action sales-line-add">+</button><button type="button" class="btn btn-outline-danger btn-sm sales-line-action del-line">×</button></div></td>`;
    if (afterRow && afterRow.parentNode === tableBody) tableBody.insertBefore(tr, afterRow.nextSibling);
    else tableBody.appendChild(tr);
    bindRow(tr);
    tr.querySelector('.item-search')?.focus();
  }

  function validateBeforeSubmit(){
    const rows = currentRows();
    const filledRows = rows.filter(row => {
      const label = String(row.querySelector('.item-search')?.value || '').trim();
      const id = Number(row.querySelector('.item-id')?.value || 0);
      const qty = parseQty(row.querySelector('.qty')?.value);
      const price = parseNumber(row.querySelector('.price')?.value);
      return label !== '' || id > 0 || qty > 0 || price > 0;
    });

    if (!filledRows.length) {
      alert('أضف صنفًا واحدًا صحيحًا على الأقل قبل الحفظ.');
      rows[0]?.querySelector('.item-search')?.focus();
      return false;
    }

    const ids = [];
    for (const row of filledRows) {
      const label = String(row.querySelector('.item-search')?.value || '').trim();
      const id = Number(row.querySelector('.item-id')?.value || 0);
      const qty = parseQty(row.querySelector('.qty')?.value);
      const price = parseNumber(row.querySelector('.price')?.value);
      if (label !== '' && id <= 0) {
        alert('يوجد سطر به صنف غير صحيح أو لم يتم اختياره من القائمة.');
        row.querySelector('.item-search')?.focus();
        return false;
      }
      if (id <= 0) {
        alert('يوجد سطر فارغ أو غير مكتمل داخل الفاتورة. احذفه أو اختر الصنف بشكل صحيح.');
        row.querySelector('.item-search')?.focus();
        return false;
      }
      if (qty <= 0) {
        alert('الكمية يجب أن تكون رقمًا صحيحًا أكبر من صفر في كل سطر.');
        row.querySelector('.qty')?.focus();
        return false;
      }
      if (price < 0) {
        alert('السعر غير صالح.');
        row.querySelector('.price')?.focus();
        return false;
      }
      ids.push(id);
    }

    if (new Set(ids).size !== ids.length) {
      alert('لا يمكن تكرار نفس الصنف أكثر من مرة داخل نفس الفاتورة.');
      return false;
    }

    const paymentMode = String(paymentModeEl?.value || 'credit').toLowerCase();
    const paid = parseNumber(paidAmountEl?.value);
    const grand = parseNumber(document.getElementById('grand')?.textContent || '0');
    if (paymentMode === 'partial' && (paid <= 0 || paid >= grand)) {
      alert('في الدفع الجزئي يجب أن يكون المدفوع أكبر من صفر وأقل من إجمالي الفاتورة.');
      paidAmountEl?.focus();
      return false;
    }
    if ((paymentMode === 'cash' || paymentMode === 'partial') && parseNumber(cashboxEl?.value) <= 0) {
      alert('اختر الخزنة المحصل عليها قبل الحفظ.');
      cashboxEl?.focus();
      return false;
    }
    if (Number(document.getElementById('party_id')?.value || 0) <= 0) {
      alert('اختر العميل أولاً.');
      customerSearch?.focus();
      return false;
    }
    return true;
  }

  addLineBtn?.setAttribute('data-shortcut', 'add-line');
  const submitActionInput = document.getElementById('sales_submit_action');

  form?.querySelectorAll('[data-submit-action]').forEach(btn => {
    btn.addEventListener('click', () => {
      if (submitActionInput) submitActionInput.value = btn.dataset.submitAction || 'save';
    });
  });

  addLineBtn?.addEventListener('click', () => addRow());
  warehouseEl?.addEventListener('change', updateHeroLabels);

  document.addEventListener('keydown', (e) => {
    if (e.key === 'F2') {
      const target = e.target;
      const typing = target && /input|textarea|select/i.test(target.tagName);
      if (form?.contains(target) || !typing) {
        e.preventDefault();
        e.stopImmediatePropagation();
        addRow();
      }
    }
  }, true);

  currentRows().forEach(bindRow);
  attachCustomerAutocomplete();
  discountTypeEl?.addEventListener('change', recalc);
  discountValueEl?.addEventListener('input', recalc);
  discountValueEl?.addEventListener('blur', () => normalizeInput(discountValueEl, 2));
  vatEnabledEl?.addEventListener('change', recalc);
  vatRateEl?.addEventListener('input', recalc);
  vatRateEl?.addEventListener('blur', () => normalizeInput(vatRateEl, 2));
  paymentModeEl?.addEventListener('change', () => {
    recalc();
    if (String(paymentModeEl.value || '').toLowerCase() === 'partial') {
      setTimeout(() => {
        paidAmountEl?.focus();
        paidAmountEl?.select?.();
      }, 40);
    }
  });
  paidAmountEl?.addEventListener('input', recalc);
  paidAmountEl?.addEventListener('blur', () => normalizeInput(paidAmountEl, 2));

  form?.addEventListener('submit', (e) => {
    if (submitLocked) {
      e.preventDefault();
      return false;
    }

    const submitter = e.submitter || document.activeElement;
    if (submitActionInput) {
      submitActionInput.value = submitter?.dataset?.submitAction || submitActionInput.value || 'save';
    }

    if (!validateBeforeSubmit()) {
      e.preventDefault();
      return false;
    }
    submitLocked = true;
    form.querySelectorAll('button[type="submit"]').forEach(btn => {
      btn.disabled = true;
      btn.innerHTML = btn.dataset.submitAction === 'post' ? 'جارٍ الترحيل...' : 'جارٍ الحفظ...';
    });
  });

  recalc();
})();
</script>
