{{ define "content" }}
<div class="page-head">
  <h1>{{ T "nav.catalog" }}</h1>
  <div style="display:flex; gap:.5rem; align-items:center">
    <a class="btn secondary" href="/import">{{ T "import.title" }}</a>
    <a class="btn secondary" href="/api/catalog/export" download>{{ T "import.export_btn" }}</a>
    <input type="search" id="catalog-search" placeholder="{{ T "catalog.search_placeholder" }}" autocomplete="off">
  </div>
</div>

{{ if .SyncPrimary }}
<div class="sync-banner">⚠ {{ T "sync.banner_replica" }}
  <a href="{{ .SyncPrimary }}/catalog" target="_blank" rel="noopener">{{ T "sync.banner_open_primary" }}</a></div>
{{ end }}

{{ template "catalog_lookups" . }}

<div class="catalog-layout">
  <div class="catalog-list">
    {{ template "catalog_table" . }}
  </div>

  <div class="card catalog-form">
    <div class="catalog-form-head">
      <h3 id="item-form-title">{{ T "catalog.new_item" }}</h3>
      <button class="btn secondary" type="button" id="item-form-reset" hidden>{{ T "catalog.plus_new" }}</button>
    </div>
    <form id="item-form" autocomplete="off">
      <input type="hidden" name="id" id="item-id">
      <input type="hidden" name="price" id="item-price-minor">
      <input type="hidden" name="imageUrl" id="item-image-url">
      <div class="field-pair">
        <label>{{ T "catalog.barcode" }} <input type="text" name="barcode" id="item-barcode" inputmode="numeric" placeholder="{{ T "catalog.autofill_placeholder" }}"></label>
        <button class="btn secondary" type="button" id="autofill-btn" style="align-self:end">{{ T "catalog.autofill" }}</button>
      </div>
      <div id="autofill-msg" class="muted" aria-live="polite" style="min-height:1.2rem"></div>
      <label>{{ T "catalog.col.name" }} <input type="text" name="name" id="item-name" required></label>
      <div class="field-pair">
        <label>{{ T "catalog.col.price" }} ({{ currency.Display }}) <input type="number" id="item-price" min="0" step="{{ if eq currency.Decimals 0 }}1{{ else }}0.01{{ end }}" placeholder="{{ if eq currency.Decimals 0 }}0{{ else }}0.00{{ end }}" required></label>
        <label>{{ T "catalog.col.sku" }} <input type="text" name="sku" id="item-sku" placeholder="{{ T "catalog.auto_if_blank" }}"></label>
      </div>
      <label>{{ T "catalog.description" }} <input type="text" name="description" id="item-description"></label>
      <div class="field-pair">
        <label>{{ T "catalog.col.unit" }} <input type="text" name="unit" id="item-unit" value="each"></label>
        <label>{{ T "catalog.tax_code" }} <input type="text" name="taxCode" id="item-tax" list="taxcodes-list" placeholder="tax_std"></label>
      </div>
      <div class="field-pair">
        <label>{{ T "catalog.category" }} <input type="text" name="categoryId" id="item-category" list="categories-list"></label>
        <label>{{ T "catalog.brand" }} <input type="text" name="brandId" id="item-brand" list="brands-list"></label>
      </div>
      <div class="field-checks">
        <label><input type="checkbox" name="isWeighed" id="item-weighed" value="1"> {{ T "catalog.sold_by_weight" }}</label>
        <label><input type="checkbox" name="isActive" id="item-active" value="1" checked> {{ T "catalog.active" }}</label>
      </div>
      <button class="btn primary" type="submit" id="item-form-submit" style="width:100%">{{ T "catalog.create_item" }}</button>
      <div id="item-form-msg" class="muted" aria-live="polite" style="min-height:1.3rem; margin-top:.4rem"></div>
    </form>

    <details class="catalog-extra">
      <summary>{{ T "catalog.item_image" }}</summary>
      <form id="image-form" enctype="multipart/form-data">
        <label>{{ T "basket.col.item" }} <input type="text" class="pick-item" id="image-item-label" readonly placeholder="{{ T "catalog.pick_row" }}"></label>
        <input type="hidden" id="image-item-id">
        <label>{{ T "catalog.image_types" }} <input type="file" id="image-file" accept="image/png,image/jpeg" required></label>
        <button class="btn" type="submit">{{ T "catalog.upload_image" }}</button>
        <div id="image-msg" class="muted" style="min-height:1.2rem"></div>
      </form>
    </details>

    <details class="catalog-extra">
      <summary>{{ T "catalog.labels" }}</summary>
      <form hx-post="/api/print/labels" hx-target="#labels-msg" hx-swap="innerHTML">
        <label>{{ T "basket.col.item" }} <input type="text" class="pick-item" id="labels-item-label" readonly placeholder="{{ T "catalog.pick_row" }}"></label>
        <input type="hidden" name="item_id" id="labels-item-id">
        <label>{{ T "catalog.labels.copies" }} <input type="number" name="copies" value="1" min="1" max="50"></label>
        <button class="btn" type="submit">{{ T "catalog.labels.print" }}</button>
        <div id="labels-msg" class="muted" aria-live="polite" style="min-height:1.2rem"></div>
      </form>
    </details>

    <details class="catalog-extra">
      <summary>{{ T "catalog.variants" }}</summary>
      <form hx-post="/api/catalog/variant" hx-target="#catalog-table" hx-swap="outerHTML">
        <input type="hidden" name="id">
        <label>{{ T "basket.col.item" }} <input type="text" name="itemId" class="pick-item" required placeholder="{{ T "catalog.pick_row" }}"></label>
        <label>{{ T "catalog.col.name" }} <input type="text" name="name" required></label>
        <div class="field-pair">
          <label>{{ T "catalog.col.sku" }} <input type="text" name="sku"></label>
          <label>{{ T "catalog.price_minor" }} <input type="number" name="price" required min="0" step="1"></label>
        </div>
        <input type="hidden" name="isActive" value="1">
        <button class="btn" type="submit">{{ T "catalog.save_variant" }}</button>
      </form>
    </details>

    <details class="catalog-extra">
      <summary>{{ T "catalog.barcodes" }}</summary>
      <form hx-post="/api/catalog/barcode" hx-target="#catalog-table" hx-swap="outerHTML">
        <label>{{ T "catalog.barcode" }} <input type="text" name="barcode" required></label>
        <label>{{ T "basket.col.item" }} <input type="text" name="itemId" class="pick-item" placeholder="{{ T "catalog.pick_row" }}"></label>
        <label><input type="checkbox" name="isPrimary" value="1"> {{ T "catalog.primary" }}</label>
        <button class="btn" type="submit">{{ T "catalog.attach_barcode" }}</button>
      </form>
    </details>
  </div>
</div>

<script>
(function () {
  var form = document.getElementById('item-form');
  var title = document.getElementById('item-form-title');
  var submit = document.getElementById('item-form-submit');
  var resetBtn = document.getElementById('item-form-reset');
  var msg = document.getElementById('item-form-msg');

  function setMode(editing, name) {
    title.textContent = editing ? 'Edit: ' + name : 'New Item';
    submit.textContent = editing ? 'Save Changes' : 'Create Item';
    resetBtn.hidden = !editing;
  }

  function clearForm() {
    form.reset();
    document.getElementById('item-id').value = '';
    document.getElementById('item-image-url').value = '';
    setMode(false);
    msg.textContent = '';
    document.getElementById('autofill-msg').textContent = '';
  }
  resetBtn.addEventListener('click', clearForm);

  // Barcode auto-fill from open product databases (G15 increment 1).
  var autofillMsg = document.getElementById('autofill-msg');
  var barcodeInput = document.getElementById('item-barcode');
  var AUTOFILL_MSG = {
    searching: "{{ T "catalog.autofill_searching" }}",
    found: "{{ T "catalog.autofill_found" }}",
    notFound: "{{ T "catalog.autofill_not_found" }}",
    failed: "{{ T "catalog.autofill_failed" }}"
  };
  function runAutofill() {
    var code = (barcodeInput.value || '').trim();
    if (!code) { barcodeInput.focus(); return; }
    autofillMsg.textContent = '⏳ ' + AUTOFILL_MSG.searching;
    fetch('/api/catalog/lookup?barcode=' + encodeURIComponent(code))
      .then(function (res) {
        return res.json().then(function (body) { return { ok: res.ok, status: res.status, body: body }; });
      })
      .then(function (r) {
        if (!r.ok) {
          autofillMsg.textContent = '✗ ' + (r.status === 404 ? AUTOFILL_MSG.notFound
            : (r.body && r.body.error) || AUTOFILL_MSG.failed);
          return;
        }
        var p = r.body.data;
        document.getElementById('item-name').value = p.name;
        var bits = [];
        if (p.description && p.description.toLowerCase() !== p.name.toLowerCase()) bits.push(p.description);
        if (p.brand) bits.push(p.brand);
        if (p.quantity) bits.push(p.quantity);
        document.getElementById('item-description').value = bits.join(' · ');
        document.getElementById('item-image-url').value = p.image_url || '';
        if (p.brand) {
          document.querySelectorAll('#brands-list option').forEach(function (opt) {
            if (opt.textContent.trim().toLowerCase() === p.brand.toLowerCase()) {
              document.getElementById('item-brand').value = opt.value;
            }
          });
        }
        autofillMsg.textContent = '✓ ' + AUTOFILL_MSG.found + ' (' + p.source + ')';
        document.getElementById('item-price').focus();
      })
      .catch(function () { autofillMsg.textContent = '✗ ' + AUTOFILL_MSG.failed; });
  }
  document.getElementById('autofill-btn').addEventListener('click', runAutofill);
  // Barcode scanners terminate with Enter — scan straight into a lookup
  // instead of submitting the half-empty form.
  barcodeInput.addEventListener('keydown', function (ev) {
    if (ev.key === 'Enter') { ev.preventDefault(); runAutofill(); }
  });

  // Row click fills the form; the table partial is re-rendered by the server
  // after every mutation, so delegate from the document.
  document.addEventListener('click', function (ev) {
    var row = ev.target.closest('.catalog-row');
    if (!row) return;
    if (ev.target.closest('.btn') && !ev.target.classList.contains('catalog-edit')) return;
    document.getElementById('item-id').value = row.dataset.id;
    document.getElementById('item-barcode').value = '';
    document.getElementById('item-image-url').value = '';
    document.getElementById('autofill-msg').textContent = '';
    document.getElementById('item-name').value = row.dataset.name;
    document.getElementById('item-sku').value = row.dataset.sku;
    document.getElementById('item-description').value = row.dataset.description;
    document.getElementById('item-unit').value = row.dataset.unit || 'each';
    document.getElementById('item-category').value = row.dataset.category;
    document.getElementById('item-brand').value = row.dataset.brand;
    document.getElementById('item-tax').value = row.dataset.tax;
    document.getElementById('item-weighed').checked = row.dataset.weighed === '1';
    document.getElementById('item-active').checked = true;
    document.getElementById('item-price').value = window.utCurrency.toMajor(parseInt(row.dataset.price || '0', 10));
    setMode(true, row.dataset.name);
    document.querySelectorAll('.pick-item').forEach(function (el) { el.value = row.dataset.id; });
    var imgLabel = document.getElementById('image-item-label');
    if (imgLabel) { imgLabel.value = row.dataset.name; document.getElementById('image-item-id').value = row.dataset.id; }
    var lblLabel = document.getElementById('labels-item-label');
    if (lblLabel) { lblLabel.value = row.dataset.name; document.getElementById('labels-item-id').value = row.dataset.id; }
  });

  form.addEventListener('submit', function (ev) {
    ev.preventDefault();
    document.getElementById('item-price-minor').value = window.utCurrency.toMinor(document.getElementById('item-price').value || '0');
    var editing = document.getElementById('item-id').value !== '';
    var url = editing ? '/api/catalog/item/update' : '/api/catalog/item';
    msg.textContent = '⏳ saving…';
    htmx.ajax('POST', url, { source: '#item-form', target: '#catalog-table', swap: 'outerHTML' })
      .then(function () { msg.textContent = '✓ saved'; if (!editing) clearForm(); filterRows(); });
  });
  document.body.addEventListener('htmx:responseError', function (ev) {
    msg.textContent = '✗ ' + (ev.detail.xhr.responseText || 'error');
  });

  var imageForm = document.getElementById('image-form');
  imageForm.addEventListener('submit', function (ev) {
    ev.preventDefault();
    var id = document.getElementById('image-item-id').value;
    var f = document.getElementById('image-file').files[0];
    var imsg = document.getElementById('image-msg');
    if (!id) { imsg.textContent = '✗ pick an item first (click a row)'; return; }
    if (!f) { imsg.textContent = '✗ choose an image'; return; }
    var fd = new FormData();
    fd.append('item_id', id);
    fd.append('image', f);
    imsg.textContent = '⏳ uploading…';
    fetch('/api/catalog/item/image', { method: 'POST', body: fd }).then(function (res) {
      if (!res.ok) { return res.text().then(function (t) { imsg.textContent = '✗ ' + t; }); }
      return res.text().then(function (html) {
        var table = document.getElementById('catalog-table');
        table.outerHTML = html;
        htmx.process(document.getElementById('catalog-table'));
        imsg.textContent = '✓ image updated';
        filterRows();
      });
    }).catch(function (e) { imsg.textContent = '✗ ' + e; });
  });

  // Client-side search over the (server-rendered) table; reapplied after swaps.
  var search = document.getElementById('catalog-search');
  function filterRows() {
    var q = (search.value || '').toLowerCase();
    document.querySelectorAll('.catalog-row').forEach(function (row) {
      var hay = (row.dataset.name + ' ' + row.dataset.sku).toLowerCase();
      row.hidden = q !== '' && hay.indexOf(q) === -1;
    });
  }
  search.addEventListener('input', filterRows);
  document.body.addEventListener('htmx:afterSwap', function (ev) {
    if (ev.detail.target && ev.detail.target.id === 'catalog-table') filterRows();
  });
})();
</script>
{{ end }}
