// ── Admin page logic ──────────────────────────────────────────────────────────

// ── Toast ─────────────────────────────────────────────────────────────────────

function showToast(msg, type = 'success') {
  const el = document.createElement('div');
  el.className = `toast align-items-center text-bg-${type} border-0 show`;
  el.innerHTML = `<div class="d-flex"><div class="toast-body">${msg}</div>
    <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button></div>`;
  document.getElementById('toastContainer').appendChild(el);
  setTimeout(() => el.remove(), 4000);
}

// ══ USERS TAB ════════════════════════════════════════════════════════════════

async function loadUsers() {
  try {
    const users = await apiGet('/users/admin/');
    document.getElementById('usersSpinner').classList.add('d-none');
    document.getElementById('usersTableWrap').classList.remove('d-none');
    renderUsers(users);
  } catch(e) {
    document.getElementById('usersSpinner').innerHTML =
      '<p class="text-danger">Failed to load users.</p>';
  }
}

function renderUsers(users) {
  document.getElementById('usersBody').innerHTML = users.map(u => `
    <tr>
      <td class="fw-semibold">${u.username}</td>
      <td>${u.email}</td>
      <td>${[u.first_name, u.last_name].filter(Boolean).join(' ') || '—'}</td>
      <td>${u.is_staff ? '<span class="badge bg-warning text-dark">Staff</span>' : ''}</td>
      <td>
        <div class="form-check form-switch mb-0">
          <input class="form-check-input" type="checkbox" ${u.is_active ? 'checked' : ''}
                 onchange="toggleUserActive(${u.id}, this.checked)" title="Active">
        </div>
      </td>
      <td class="text-muted small">${u.date_joined ? u.date_joined.slice(0,10) : '—'}</td>
      <td>
        <button class="btn btn-sm ${u.is_staff ? 'btn-outline-secondary' : 'btn-outline-warning'}"
                onclick="toggleUserStaff(${u.id}, ${!u.is_staff})" title="${u.is_staff ? 'Remove staff' : 'Make staff'}">
          <i class="bi bi-${u.is_staff ? 'person-dash' : 'person-up'}"></i>
        </button>
      </td>
    </tr>
  `).join('');
}

async function toggleUserActive(id, active) {
  try {
    await apiPatch(`/users/admin/${id}/`, { is_active: active });
    showToast(`User ${active ? 'activated' : 'deactivated'}.`);
  } catch(e) {
    showToast('Failed to update user.', 'danger');
    loadUsers();
  }
}

async function toggleUserStaff(id, staff) {
  if (!confirm(`${staff ? 'Grant' : 'Revoke'} staff rights for this user?`)) return;
  try {
    await apiPatch(`/users/admin/${id}/`, { is_staff: staff });
    showToast(`Staff rights ${staff ? 'granted' : 'revoked'}.`);
    loadUsers();
  } catch(e) {
    showToast('Failed to update user.', 'danger');
  }
}

// ══ GEAR CATALOG TAB ═════════════════════════════════════════════════════════

const GEAR_ENDPOINTS = {
  firearm:    '/gears/firearms/',
  scope:      '/gears/scopes/',
  suppressor: '/gears/suppressors/',
  bipod:      '/gears/bipods/',
  magazine:   '/gears/magazines/',
};

const CATALOG_PAGE_SIZE = 50;
let allCatalogItems = [];
let catalogTotalCount = 0;
let catalogSearchTerm = '';
let catalogPage = 1;
let catalogHasNext = false;

async function loadCatalog(status, page) {
  if (status === undefined) status = document.getElementById('catalogStatusFilter').value;
  if (page === undefined) page = 1;
  catalogPage = page;

  const spinnerEl = document.getElementById('catalogSpinner');
  spinnerEl.innerHTML = '<div class="spinner-border text-primary"></div>';
  spinnerEl.classList.remove('d-none');
  document.getElementById('catalogTableWrap').classList.add('d-none');

  const statusParam = (status && status !== 'all') ? `&status=${status}` : '';
  const searchParam = catalogSearchTerm ? `&search=${encodeURIComponent(catalogSearchTerm)}` : '';
  const pageParam   = page > 1 ? `&page=${page}` : '';

  try {
    const results = await Promise.all(
      Object.entries(GEAR_ENDPOINTS).map(([type, url]) =>
        apiFetch(`${url}?page_size=${CATALOG_PAGE_SIZE}${statusParam}${searchParam}${pageParam}`)
          .then(r => { if (!r.ok) throw new Error(r.status); return r.json(); })
          .then(data => ({
            type,
            items: (data.results || []).map(g => ({ ...g, gear_type: type })),
            count: data.count || 0,
            hasNext: !!data.next,
          }))
      )
    );
    allCatalogItems  = results.flatMap(r => r.items);
    catalogTotalCount = results.reduce((s, r) => s + r.count, 0);
    catalogHasNext   = results.some(r => r.hasNext);

    spinnerEl.classList.add('d-none');
    document.getElementById('catalogTableWrap').classList.remove('d-none');
    renderCatalog();
  } catch(e) {
    spinnerEl.innerHTML = `<p class="text-danger">Failed to load catalog: ${e.message}</p>`;
  }
}

function renderCatalog() {
  const typeFilter = document.getElementById('catalogTypeFilter').value;

  let items = allCatalogItems;
  if (typeFilter !== 'all') items = items.filter(g => g.gear_type === typeFilter);

  const statusBadge = s => ({
    PENDING:  '<span class="badge bg-warning text-dark">Pending</span>',
    VERIFIED: '<span class="badge bg-success">Verified</span>',
    REJECTED: '<span class="badge bg-danger">Rejected</span>',
  }[s] || `<span class="badge bg-secondary">${s}</span>`);

  // Count line
  const showing = items.length;
  const countEl = document.getElementById('catalogCount');
  if (countEl) {
    const pageDesc = catalogHasNext || catalogPage > 1
      ? ` — page ${catalogPage}` : '';
    countEl.textContent = `${showing} item${showing !== 1 ? 's' : ''} shown (${catalogTotalCount} total${pageDesc})`;
  }

  // Table rows
  document.getElementById('catalogBody').innerHTML = items.map(g => `
    <tr>
      <td><span class="badge bg-secondary">${g.gear_type}</span></td>
      <td>${esc(g.brand)}</td>
      <td>${esc(g.model_name)}</td>
      <td>${esc(g.caliber_detail?.name || '—')}</td>
      <td>${statusBadge(g.status)}</td>
      <td class="text-end">
        ${g.status === 'PENDING' ? `
          <button class="btn btn-sm btn-outline-success me-1"
                  onclick="verifyGear('${g.gear_type}', ${g.id})" title="Verify">
            <i class="bi bi-check-lg"></i>
          </button>
          <button class="btn btn-sm btn-outline-danger me-1"
                  onclick="rejectGear('${g.gear_type}', ${g.id})" title="Reject">
            <i class="bi bi-x-lg"></i>
          </button>` : ''}
        <button class="btn btn-sm btn-outline-danger"
                onclick="deleteGear('${g.gear_type}', ${g.id})" title="Delete">
          <i class="bi bi-trash"></i>
        </button>
      </td>
    </tr>
  `).join('') || '<tr><td colspan="6" class="text-muted text-center">No items.</td></tr>';

  // Pagination controls
  document.getElementById('catalogPagination').innerHTML = (catalogPage > 1 || catalogHasNext) ? `
    <nav class="d-flex justify-content-between align-items-center mt-2">
      <button class="btn btn-sm btn-outline-secondary" ${catalogPage <= 1 ? 'disabled' : ''}
              onclick="loadCatalog(undefined, ${catalogPage - 1})">
        <i class="bi bi-chevron-left"></i> Prev
      </button>
      <span class="small text-muted">Page ${catalogPage}</span>
      <button class="btn btn-sm btn-outline-secondary" ${!catalogHasNext ? 'disabled' : ''}
              onclick="loadCatalog(undefined, ${catalogPage + 1})">
        Next <i class="bi bi-chevron-right"></i>
      </button>
    </nav>` : '';
}

document.getElementById('catalogTypeFilter').addEventListener('change', renderCatalog);
document.getElementById('catalogStatusFilter').addEventListener('change', () => loadCatalog());

async function verifyGear(type, id) {
  try {
    await apiPost(`/gears/${type}s/${id}/verify/`, {});
    const item = allCatalogItems.find(g => g.gear_type === type && g.id === id);
    if (item) item.status = 'VERIFIED';
    renderCatalog();
    showToast('Gear verified.');
  } catch(e) { showToast('Failed to verify.', 'danger'); }
}

async function rejectGear(type, id) {
  try {
    await apiPost(`/gears/${type}s/${id}/reject/`, {});
    const item = allCatalogItems.find(g => g.gear_type === type && g.id === id);
    if (item) item.status = 'REJECTED';
    renderCatalog();
    showToast('Gear rejected.');
  } catch(e) { showToast('Failed to reject.', 'danger'); }
}

async function deleteGear(type, id) {
  if (!confirm('Delete this gear item from the catalog?')) return;
  try {
    await apiDelete(`/gears/${type}s/${id}/`);
    allCatalogItems = allCatalogItems.filter(g => !(g.gear_type === type && g.id === id));
    renderCatalog();
    showToast('Gear deleted.');
  } catch(e) { showToast('Failed to delete.', 'danger'); }
}

// Add gear form — show/hide type-specific fields
document.getElementById('addGearType').addEventListener('change', function() {
  ['Firearm','Scope','Suppressor','Bipod','Magazine'].forEach(t =>
    document.getElementById(`fields${t}`).classList.add('d-none'));
  if (this.value) {
    const key = this.value.charAt(0).toUpperCase() + this.value.slice(1);
    document.getElementById(`fields${key}`)?.classList.remove('d-none');
    document.getElementById('addGearSubmit').disabled = false;
    // Load calibers into the newly-visible caliber select
    const calSelectId = { firearm: 'addFirearmCaliber', suppressor: 'addSuppCaliber', magazine: 'addMagCaliber' }[this.value];
    if (calSelectId) {
      const sel = document.getElementById(calSelectId);
      if (sel && (!sel.options.length || sel.options[0].text === 'Loading…')) {
        loadCalibersIntoSelect(sel);
      }
    }
  } else {
    document.getElementById('addGearSubmit').disabled = true;
  }
});

document.getElementById('addGearSubmit').addEventListener('click', async () => {
  const type    = document.getElementById('addGearType').value;
  const alertEl = document.getElementById('addGearAlert');
  alertEl.classList.add('d-none');
  if (!type) return;

  const payload = {
    brand:      document.getElementById('addGearBrand').value.trim(),
    model_name: document.getElementById('addGearModel').value.trim(),
    description:document.getElementById('addGearDesc').value.trim(),
    status:     'VERIFIED',
  };

  if (!payload.brand || !payload.model_name) {
    alertEl.textContent = 'Brand and model are required.';
    alertEl.classList.remove('d-none');
    return;
  }

  if (type === 'firearm') {
    payload.firearm_type = document.getElementById('addFirearmType').value;
    const fc = document.getElementById('addFirearmCaliber').value;
    if (fc) payload.caliber = parseInt(fc);
    const bl = document.getElementById('addFirearmBarrel').value;
    const mc = document.getElementById('addFirearmMag').value;
    if (bl) payload.barrel_length_mm   = parseFloat(bl);
    if (mc) payload.magazine_capacity  = parseInt(mc);
  } else if (type === 'scope') {
    const mn = document.getElementById('addScopeMagMin').value;
    const mx = document.getElementById('addScopeMagMax').value;
    const ob = document.getElementById('addScopeObj').value;
    const tu = document.getElementById('addScopeTube').value;
    const rt = document.getElementById('addScopeReticle').value;
    const au = document.getElementById('addScopeAdj').value;
    const fp = document.getElementById('addScopeFP').value;
    if (rt) payload.reticle_type = rt;
    if (mn) payload.magnification_min      = parseFloat(mn);
    if (mx) payload.magnification_max      = parseFloat(mx);
    if (ob) payload.objective_diameter_mm  = parseFloat(ob);
    if (tu) payload.tube_diameter_mm       = parseFloat(tu);
    if (au) payload.adjustment_unit = au;
    if (fp) payload.focal_plane     = fp;
  } else if (type === 'suppressor') {
    const sc = document.getElementById('addSuppCaliber').value;
    if (sc) payload.max_caliber = parseInt(sc);
    payload.thread_pitch = document.getElementById('addSuppThread').value.trim();
    const ln = document.getElementById('addSuppLength').value;
    const wt = document.getElementById('addSuppWeight').value;
    if (ln) payload.length_mm = parseFloat(ln);
    if (wt) payload.weight_g  = parseFloat(wt);
  } else if (type === 'bipod') {
    const mn = document.getElementById('addBipodMin').value;
    const mx = document.getElementById('addBipodMax').value;
    payload.attachment_type = document.getElementById('addBipodAttach').value.trim();
    if (mn) payload.min_height_mm = parseFloat(mn);
    if (mx) payload.max_height_mm = parseFloat(mx);
  } else if (type === 'magazine') {
    const mc = document.getElementById('addMagCaliber').value;
    if (mc) payload.caliber = parseInt(mc);
    const cap = document.getElementById('addMagCapacity').value;
    if (cap) payload.capacity = parseInt(cap);
  }

  try {
    const created = await apiPost(`/gears/${type}s/`, payload);
    allCatalogItems.push({ ...created, gear_type: type });
    renderCatalog();
    // Reset form
    ['addGearBrand','addGearModel','addGearDesc','addFirearmAction',
     'addFirearmBarrel','addFirearmMag','addScopeMagMin','addScopeMagMax','addScopeObj',
     'addScopeTube','addScopeReticle','addScopeAdj','addScopeFP',
     'addSuppThread','addSuppLength',
     'addSuppWeight','addBipodMin','addBipodMax','addBipodAttach',
     'addMagCapacity'].forEach(id => { const el = document.getElementById(id); if(el) el.value=''; });
    // Reset caliber selects to first option
    ['addFirearmCaliber','addSuppCaliber','addMagCaliber'].forEach(id => {
      const el = document.getElementById(id); if (el) el.selectedIndex = 0;
    });
    showToast('Gear added to catalog!');
  } catch(e) {
    alertEl.textContent = formatErrors(e.data) || 'Failed to add gear.';
    alertEl.classList.remove('d-none');
  }
});

// ══ RELOAD COMPONENTS TAB ═════════════════════════════════════════════════════

function compStatusBadge(s) {
  return s === 'PENDING'  ? '<span class="badge bg-warning text-dark">Pending</span>'
       : s === 'REJECTED' ? '<span class="badge bg-danger">Rejected</span>'
       : '<span class="badge bg-success">Verified</span>';
}

const COMP_CONFIG = {
  primers: {
    title: 'primer',
    endpoint: '/gears/components/primers/',
    headers: ['Brand', 'Name', 'Size', 'Status', ''],
    row: c => `<td>${c.brand}</td><td>${c.name}</td><td>${c.size}</td><td>${compStatusBadge(c.status)}</td>`,
    form: () => `
      <div class="mb-2"><input type="text" class="form-control form-control-sm" id="cBrand" placeholder="Brand *"></div>
      <div class="mb-2"><input type="text" class="form-control form-control-sm" id="cName"  placeholder="Name *"></div>
      <div class="mb-2">
        <select class="form-select form-select-sm" id="cSize">
          <option value="SP">Small Pistol</option><option value="LP">Large Pistol</option>
          <option value="SR">Small Rifle</option><option value="LR" selected>Large Rifle</option>
          <option value="LRM">Large Rifle Magnum</option>
        </select>
      </div>`,
    payload: () => ({ brand: v('cBrand'), name: v('cName'), size: v('cSize') }),
  },
  brass: {
    title: 'brass',
    endpoint: '/gears/components/brass/',
    headers: ['Brand', 'Caliber', 'Pocket', 'Status', ''],
    row: c => `<td>${c.brand}</td><td>${c.caliber_detail?.name || '—'}</td><td>${c.primer_pocket || '—'}</td><td>${compStatusBadge(c.status)}</td>`,
    form: () => `
      <div class="mb-2"><input type="text" class="form-control form-control-sm" id="cBrand" placeholder="Brand *"></div>
      <div class="mb-2">
        <select class="form-select form-select-sm" id="cCaliber"><option value="">Loading calibers…</option></select>
      </div>
      <div class="mb-2">
        <select class="form-select form-select-sm" id="cPocket">
          <option value="">Primer pocket (optional)</option>
          <option value="SP">Small Pistol</option><option value="LP">Large Pistol</option>
          <option value="SR">Small Rifle</option><option value="LR">Large Rifle</option>
          <option value="LRM">Large Rifle Magnum</option>
        </select>
      </div>`,
    payload: () => {
      const cal = v('cCaliber');
      return { brand: v('cBrand'), caliber: cal ? parseInt(cal) : undefined, primer_pocket: v('cPocket') || undefined };
    },
  },
  bullets: {
    title: 'bullet',
    endpoint: '/gears/components/bullets/',
    headers: ['Brand', 'Model', 'Weight', 'Type', 'Status', ''],
    row: c => `<td>${c.brand}</td><td>${c.model_name}</td><td>${c.weight_gr} gr</td><td>${c.bullet_type}</td><td>${compStatusBadge(c.status)}</td>`,
    form: () => `
      <div class="mb-2"><input type="text"   class="form-control form-control-sm" id="cBrand"  placeholder="Brand *"></div>
      <div class="mb-2"><input type="text"   class="form-control form-control-sm" id="cModel"  placeholder="Model name *"></div>
      <div class="mb-2"><input type="number" class="form-control form-control-sm" id="cWeight" placeholder="Weight (gr) *" step="0.1"></div>
      <div class="mb-2">
        <select class="form-select form-select-sm" id="cBType">
          <option value="FMJ">FMJ</option><option value="HP">HP</option>
          <option value="BTHP">BTHP</option><option value="SP">SP</option>
          <option value="HPBT" selected>HPBT</option><option value="SMK">SMK</option>
          <option value="A_TIP">A-Tip</option><option value="MONO">Monolithic</option>
        </select>
      </div>
      <div class="mb-2"><input type="number" class="form-control form-control-sm" id="cDiam" placeholder="Diameter mm (opt)" step="0.001"></div>`,
    payload: () => {
      const p = { brand: v('cBrand'), model_name: v('cModel'), weight_gr: v('cWeight'), bullet_type: v('cBType') };
      const d = v('cDiam'); if (d) p.diameter_mm = d;
      return p;
    },
  },
  powders: {
    title: 'powder',
    endpoint: '/gears/components/powders/',
    headers: ['Brand', 'Name', 'Type', 'Burn idx', 'Status', ''],
    row: c => `<td>${c.brand}</td><td>${c.name}</td><td>${c.powder_type || '—'}</td><td>${c.burn_rate_index ?? '—'}</td><td>${compStatusBadge(c.status)}</td>`,
    form: () => `
      <div class="mb-2"><input type="text" class="form-control form-control-sm" id="cBrand" placeholder="Brand *"></div>
      <div class="mb-2"><input type="text" class="form-control form-control-sm" id="cName"  placeholder="Name *"></div>
      <div class="mb-2">
        <select class="form-select form-select-sm" id="cPType">
          <option value="">Type (optional)</option>
          <option value="BALL">Ball/Spherical</option>
          <option value="EXTRUDED">Extruded/Stick</option>
          <option value="FLAKE">Flake</option>
        </select>
      </div>
      <div class="mb-2"><input type="number" class="form-control form-control-sm" id="cBurn" placeholder="Burn rate index (opt)"></div>`,
    payload: () => {
      const p = { brand: v('cBrand'), name: v('cName') };
      const t = v('cPType'); if (t) p.powder_type = t;
      const b = v('cBurn');  if (b) p.burn_rate_index = parseInt(b);
      return p;
    },
  },
};

let currentComp = 'primers';
let compData = {};

function v(id) { return document.getElementById(id)?.value?.trim() || ''; }

async function loadComp(type) {
  currentComp = type;
  const cfg = COMP_CONFIG[type];
  const spinner = document.getElementById('compSpinner');
  const wrap    = document.getElementById('compTableWrap');
  spinner.classList.remove('d-none');
  wrap.classList.add('d-none');

  document.getElementById('addCompTitle').textContent = `Add ${cfg.title}`;
  document.getElementById('addCompForm').innerHTML = cfg.form();
  document.getElementById('addCompAlert').classList.add('d-none');
  // Load calibers into brass form select
  if (type === 'brass') {
    const sel = document.getElementById('cCaliber');
    if (sel) loadCalibersIntoSelect(sel);
  }

  try {
    compData[type] = await apiGetAll(cfg.endpoint + '?page_size=1000');
    renderComp(type);
  } catch(e) {
    spinner.innerHTML = '<p class="text-danger">Failed to load.</p>';
  }
}

function renderComp(type) {
  const cfg  = COMP_CONFIG[type];
  const items = compData[type] || [];
  document.getElementById('compSpinner').classList.add('d-none');
  document.getElementById('compTableWrap').classList.remove('d-none');

  document.getElementById('compTableHead').innerHTML =
    cfg.headers.map(h => `<th>${h}</th>`).join('');

  document.getElementById('compBody').innerHTML = items.length
    ? items.map(c => `
        <tr>
          ${cfg.row(c)}
          <td class="text-end">
            ${c.status === 'PENDING' ? `
              <button class="btn btn-sm btn-outline-success me-1"
                      onclick="verifyComp('${type}', ${c.id})" title="Verify">
                <i class="bi bi-check-lg"></i>
              </button>
              <button class="btn btn-sm btn-outline-warning me-1"
                      onclick="rejectComp('${type}', ${c.id})" title="Reject">
                <i class="bi bi-x-lg"></i>
              </button>` : ''}
            <button class="btn btn-sm btn-outline-danger"
                    onclick="deleteComp('${type}', ${c.id})">
              <i class="bi bi-trash"></i>
            </button>
          </td>
        </tr>`).join('')
    : `<tr><td colspan="${cfg.headers.length}" class="text-muted text-center">No entries.</td></tr>`;
}

document.getElementById('addCompSubmit').addEventListener('click', async () => {
  const cfg     = COMP_CONFIG[currentComp];
  const alertEl = document.getElementById('addCompAlert');
  alertEl.classList.add('d-none');
  try {
    const payload = cfg.payload();
    const created = await apiPost(cfg.endpoint, payload);
    if (!compData[currentComp]) compData[currentComp] = [];
    compData[currentComp].push(created);
    renderComp(currentComp);
    document.getElementById('addCompForm').innerHTML = cfg.form();
    if (currentComp === 'brass') {
      const sel = document.getElementById('cCaliber');
      if (sel) loadCalibersIntoSelect(sel);
    }
    showToast(`${cfg.title} added!`);
  } catch(e) {
    alertEl.textContent = formatErrors(e.data) || 'Failed to add.';
    alertEl.classList.remove('d-none');
  }
});

async function verifyComp(type, id) {
  const cfg = COMP_CONFIG[type];
  try {
    await apiPost(`${cfg.endpoint}${id}/verify/`, {});
    const item = (compData[type] || []).find(c => c.id === id);
    if (item) item.status = 'VERIFIED';
    renderComp(type);
    showToast('Component verified.');
  } catch(e) { showToast('Failed to verify.', 'danger'); }
}

async function rejectComp(type, id) {
  const cfg = COMP_CONFIG[type];
  try {
    await apiPost(`${cfg.endpoint}${id}/reject/`, {});
    const item = (compData[type] || []).find(c => c.id === id);
    if (item) item.status = 'REJECTED';
    renderComp(type);
    showToast('Component rejected.');
  } catch(e) { showToast('Failed to reject.', 'danger'); }
}

async function deleteComp(type, id) {
  if (!confirm('Delete this component?')) return;
  const cfg = COMP_CONFIG[type];
  try {
    await apiDelete(`${cfg.endpoint}${id}/`);
    compData[type] = compData[type].filter(c => c.id !== id);
    renderComp(type);
    showToast('Deleted.');
  } catch(e) { showToast('Failed to delete.', 'danger'); }
}

// Pill switcher
document.getElementById('compPills').addEventListener('click', e => {
  const btn = e.target.closest('[data-comp]');
  if (!btn) return;
  document.querySelectorAll('#compPills .nav-link').forEach(b => b.classList.remove('active'));
  btn.classList.add('active');
  loadComp(btn.dataset.comp);
});

// ── Tab activation → lazy load ─────────────────────────────────────────────

document.querySelectorAll('#adminTabs button').forEach(btn => {
  btn.addEventListener('shown.bs.tab', e => {
    const target = e.target.dataset.bsTarget;
    if (target === '#usersTab'     && !document.getElementById('usersBody').innerHTML) loadUsers();
    if (target === '#catalogTab'   && !allCatalogItems.length) loadCatalog();
    if (target === '#componentsTab' && !compData.primers) loadComp('primers');
    if (target === '#calibersTab'  && !caliberData.length) loadCalibersAdmin();
  });
});

document.addEventListener('DOMContentLoaded', () => {
  document.getElementById('catalogSearch')?.addEventListener('keydown', e => {
    if (e.key === 'Enter') {
      catalogSearchTerm = e.target.value.trim();
      loadCatalog(undefined, 1);
    }
  });
});

// ══ CALIBERS TAB ═════════════════════════════════════════════════════════════

let caliberData = [];

async function loadCalibersAdmin() {
  try {
    caliberData = await apiGetAll('/calibers/?page_size=1000');
    document.getElementById('calibersSpinner').classList.add('d-none');
    document.getElementById('calibersTableWrap').classList.remove('d-none');
    renderCalibersAdmin();
  } catch(e) {
    document.getElementById('calibersSpinner').innerHTML = '<p class="text-danger">Failed to load.</p>';
  }
}

function renderCalibersAdmin() {
  const statusBadge = s => ({
    PENDING:  '<span class="badge bg-warning text-dark">Pending</span>',
    VERIFIED: '<span class="badge bg-success">Verified</span>',
    REJECTED: '<span class="badge bg-danger">Rejected</span>',
  }[s] || `<span class="badge bg-secondary">${s}</span>`);

  document.getElementById('calibersBody').innerHTML = caliberData.length
    ? caliberData.map(c => `
        <tr>
          <td><strong>${c.name}</strong></td>
          <td class="text-muted">${c.short_name || '—'}</td>
          <td>${c.case_length_mm ?? '—'}</td>
          <td>${c.max_pressure_mpa ?? '—'}</td>
          <td>${statusBadge(c.status)}</td>
          <td class="text-end">
            ${c.status === 'PENDING' ? `
              <button class="btn btn-sm btn-outline-success me-1" onclick="verifyCaliber(${c.id})" title="Verify">
                <i class="bi bi-check-lg"></i>
              </button>
              <button class="btn btn-sm btn-outline-danger me-1" onclick="rejectCaliber(${c.id})" title="Reject">
                <i class="bi bi-x-lg"></i>
              </button>` : ''}
            <button class="btn btn-sm btn-outline-danger" onclick="deleteCaliber(${c.id})" title="Delete">
              <i class="bi bi-trash"></i>
            </button>
          </td>
        </tr>`).join('')
    : '<tr><td colspan="6" class="text-muted text-center">No calibers yet.</td></tr>';
}

async function verifyCaliber(id) {
  try {
    await apiPost(`/calibers/${id}/verify/`, {});
    const item = caliberData.find(c => c.id === id);
    if (item) item.status = 'VERIFIED';
    renderCalibersAdmin();
    showToast('Caliber verified.');
  } catch(e) { showToast('Failed to verify.', 'danger'); }
}

async function rejectCaliber(id) {
  try {
    await apiPost(`/calibers/${id}/reject/`, {});
    const item = caliberData.find(c => c.id === id);
    if (item) item.status = 'REJECTED';
    renderCalibersAdmin();
    showToast('Caliber rejected.');
  } catch(e) { showToast('Failed to reject.', 'danger'); }
}

async function deleteCaliber(id) {
  if (!confirm('Delete this caliber?')) return;
  try {
    await apiDelete(`/calibers/${id}/`);
    caliberData = caliberData.filter(c => c.id !== id);
    renderCalibersAdmin();
    showToast('Deleted.');
  } catch(e) { showToast('Failed to delete.', 'danger'); }
}

document.getElementById('calibersAddBtn').addEventListener('click', async () => {
  const alertEl = document.getElementById('calibersAddAlert');
  alertEl.classList.add('d-none');
  const name = document.getElementById('calName').value.trim();
  if (!name) {
    alertEl.textContent = 'Name is required.';
    alertEl.classList.remove('d-none');
    return;
  }
  const payload = { name };
  const short = document.getElementById('calShort').value.trim();
  if (short) payload.short_name = short;
  const caseLen  = document.getElementById('calCase').value;
  const oal      = document.getElementById('calOAL').value;
  const bulDia   = document.getElementById('calBulletDia').value;
  const pressure = document.getElementById('calPressure').value;
  if (caseLen)  payload.case_length_mm    = parseFloat(caseLen);
  if (oal)      payload.overall_length_mm = parseFloat(oal);
  if (bulDia)   payload.bullet_diameter_mm = parseFloat(bulDia);
  if (pressure) payload.max_pressure_mpa  = parseFloat(pressure);
  try {
    // Admin creates calibers directly as verified via the verify action after creation
    const created = await apiPost('/calibers/', payload);
    await apiPost(`/calibers/${created.id}/verify/`, {});
    created.status = 'VERIFIED';
    caliberData.push(created);
    renderCalibersAdmin();
    ['calName','calShort','calCase','calOAL','calBulletDia','calPressure'].forEach(id => {
      const el = document.getElementById(id); if (el) el.value = '';
    });
    showToast('Caliber added.');
  } catch(e) {
    alertEl.textContent = formatErrors(e.data) || 'Failed to add.';
    alertEl.classList.remove('d-none');
  }
});

// ══ CREATE USER ══════════════════════════════════════════════════════════════

document.getElementById('createUserBtn').addEventListener('click', () => {
  const panel = document.getElementById('createUserPanel');
  panel.classList.toggle('d-none');
  if (!panel.classList.contains('d-none')) {
    document.getElementById('newUsername').focus();
  }
});

document.getElementById('cancelCreateUserBtn').addEventListener('click', () => {
  document.getElementById('createUserPanel').classList.add('d-none');
  document.getElementById('createUserAlert').classList.add('d-none');
});

document.getElementById('saveCreateUserBtn').addEventListener('click', async () => {
  const alertEl = document.getElementById('createUserAlert');
  alertEl.classList.add('d-none');

  const username   = document.getElementById('newUsername').value.trim();
  const email      = document.getElementById('newEmail').value.trim();
  const password   = document.getElementById('newPassword').value;
  const first_name = document.getElementById('newFirstName').value.trim();
  const last_name  = document.getElementById('newLastName').value.trim();
  const is_staff   = document.getElementById('newIsStaff').checked;

  if (!username || !email || !password) {
    alertEl.textContent = 'Username, email and password are required.';
    alertEl.classList.remove('d-none');
    return;
  }

  try {
    const user = await apiPost('/users/admin/', { username, email, password, first_name, last_name, is_staff });
    await loadUsers();
    document.getElementById('createUserPanel').classList.add('d-none');
    ['newUsername','newEmail','newPassword','newFirstName','newLastName'].forEach(id => {
      document.getElementById(id).value = '';
    });
    document.getElementById('newIsStaff').checked = false;
    showToast(`User "${user.username}" created.`);
  } catch(e) {
    alertEl.textContent = formatErrors(e.data) || 'Failed to create user.';
    alertEl.classList.remove('d-none');
  }
});

// ── Init: load users tab (active by default) ──────────────────────────────
loadUsers();
