<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>Item Locations — Stock Locator</title>
<link rel="stylesheet" href="/static/css/style.css"/>
</head>
<body>
<div class="topbar">
  <div class="brand">Stock Locator</div>
  <a href="/purchase">Upload Purchase</a>
  <a href="/locations" class="active">Item Locations</a>
</div>

<div class="wrap">
  <div class="card">
    <h1>Import your item → location list</h1>
    <p class="sub">Upload once from Excel, CSV, Word (.docx) or an old DBF export. You can re-upload anytime to add more — it updates existing items and adds new ones, never removes what's already there.</p>
    <div class="dropzone" id="dropzone" onclick="document.getElementById('fileInput').click()">
      <div id="dzText">📋 Click or drop your location list here (.xlsx / .xls / .csv / .docx / .dbf)</div>
      <input type="file" id="fileInput" accept=".xlsx,.xls,.csv,.docx,.dbf"/>
    </div>
  </div>

  <div class="card" id="previewCard" style="display:none;">
    <h2>Preview</h2>
    <p class="sub" id="previewSummary"></p>
    <table>
      <thead><tr><th>Item</th><th>Location</th></tr></thead>
      <tbody id="previewBody"></tbody>
    </table>
    <div style="margin-top:14px;display:flex;gap:10px;">
      <button class="btn" onclick="commitImport()">Import all rows</button>
      <button class="btn secondary" onclick="cancelPreview()">Cancel</button>
    </div>
  </div>

  <div class="card">
    <h2>Add / edit a single item</h2>
    <div style="display:flex;gap:10px;flex-wrap:wrap;">
      <input class="input" style="flex:2;min-width:200px;" id="newName" placeholder="Item name"/>
      <input class="input" style="flex:1;min-width:100px;" id="newLoc" placeholder="Location, e.g. A14"/>
      <button class="btn" onclick="addOne()">Save</button>
    </div>
  </div>

  <div class="card">
    <h2>Search item locations (<span id="totalCount">0</span> total)</h2>
    <input class="input" id="searchBox" placeholder="Search by item name…" oninput="debouncedSearch()"/>
    <table style="margin-top:12px;">
      <thead><tr><th>Item</th><th>Location</th><th></th></tr></thead>
      <tbody id="listBody"></tbody>
    </table>
    <div style="margin-top:10px;display:flex;gap:8px;justify-content:center;">
      <button class="btn small secondary" onclick="changePage(-1)">Prev</button>
      <span id="pageLabel" style="align-self:center;font-size:.85rem;color:var(--muted);"></span>
      <button class="btn small secondary" onclick="changePage(1)">Next</button>
    </div>
  </div>
</div>

<div class="toast" id="toast"></div>
<script>
const dz = document.getElementById('dropzone');
const fileInput = document.getElementById('fileInput');
dz.addEventListener('dragover', e => { e.preventDefault(); dz.classList.add('drag'); });
dz.addEventListener('dragleave', () => dz.classList.remove('drag'));
dz.addEventListener('drop', e => {
  e.preventDefault(); dz.classList.remove('drag');
  if(e.dataTransfer.files.length){ fileInput.files = e.dataTransfer.files; handleFile(); }
});
fileInput.addEventListener('change', handleFile);

let previewToken = null;

async function handleFile(){
  const f = fileInput.files[0];
  if(!f) return;
  document.getElementById('dzText').textContent = `Reading "${f.name}"…`;
  const fd = new FormData();
  fd.append('file', f);
  try{
    const r = await fetch('/api/locations/import/preview', {method:'POST', body: fd});
    const d = await r.json();
    if(!r.ok || d.error){ showToast(d.error || 'Could not read file', true); resetDz(); return; }
    previewToken = d.token;
    document.getElementById('previewSummary').textContent =
      `${d.format} — ${d.total_rows} rows found, ${d.with_location} already have a location.`;
    document.getElementById('previewBody').innerHTML = d.sample.map(it =>
      `<tr><td data-label="Item">${escapeHtml(it.name)}</td><td data-label="Location">${escapeHtml(it.location || '—')}</td></tr>`
    ).join('');
    document.getElementById('previewCard').style.display = 'block';
    resetDz();
  }catch(e){ showToast('Upload failed: ' + e, true); resetDz(); }
}
function resetDz(){ document.getElementById('dzText').textContent = '📋 Click or drop your location list here (.xlsx / .xls / .csv / .docx / .dbf)'; fileInput.value = ''; }

async function commitImport(){
  if(!previewToken) return;
  const r = await fetch('/api/locations/import/commit', {method:'POST', headers:{'Content-Type':'application/json'},
    body: JSON.stringify({token: previewToken})});
  const d = await r.json();
  if(!r.ok || d.error){ showToast(d.error || 'Import failed', true); return; }
  showToast(`Imported: ${d.created} new, ${d.updated} updated`);
  cancelPreview();
  loadList();
}
function cancelPreview(){ previewToken = null; document.getElementById('previewCard').style.display = 'none'; }

async function addOne(){
  const name = document.getElementById('newName').value.trim();
  const location = document.getElementById('newLoc').value.trim();
  if(!name){ showToast('Item name required', true); return; }
  const r = await fetch('/api/locations', {method:'POST', headers:{'Content-Type':'application/json'},
    body: JSON.stringify({name, location})});
  const d = await r.json();
  if(!r.ok || d.error){ showToast(d.error || 'Save failed', true); return; }
  showToast('Saved');
  document.getElementById('newName').value = ''; document.getElementById('newLoc').value = '';
  loadList();
}

let page = 1;
function changePage(delta){ page = Math.max(1, page + delta); loadList(); }
let searchTimer;
function debouncedSearch(){ clearTimeout(searchTimer); searchTimer = setTimeout(() => { page = 1; loadList(); }, 300); }

async function loadList(){
  const q = document.getElementById('searchBox').value.trim();
  const r = await fetch(`/api/locations?q=${encodeURIComponent(q)}&page=${page}`);
  const d = await r.json();
  document.getElementById('totalCount').textContent = d.total;
  document.getElementById('pageLabel').textContent = `Page ${d.page} of ${Math.max(1, Math.ceil(d.total / d.per_page))}`;
  document.getElementById('listBody').innerHTML = d.items.map(it => `
    <tr data-id="${it.id}">
      <td data-label="Item">${escapeHtml(it.name)}</td>
      <td data-label="Location"><input class="input" style="width:auto;" value="${escapeHtml(it.location || '')}"
        onchange="editLoc(${it.id}, this.value)"/></td>
      <td></td>
    </tr>`).join('') || '<tr><td colspan="3" style="text-align:center;color:var(--muted);">No items yet — import a list above.</td></tr>';
}
async function editLoc(id, location){
  const r = await fetch(`/api/locations/${id}`, {method:'PUT', headers:{'Content-Type':'application/json'},
    body: JSON.stringify({location})});
  if(r.ok) showToast('Updated'); else showToast('Update failed', true);
}
function escapeHtml(s){
  return String(s == null ? '' : s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
}
function showToast(msg, err){
  const t = document.getElementById('toast');
  t.textContent = msg; t.classList.toggle('err', !!err); t.classList.add('show');
  setTimeout(() => t.classList.remove('show'), 2500);
}
loadList();
</script>
</body>
</html>
