// ── Reloads page logic ────────────────────────────────────────────────────────

let recipes   = [];
let components = { primers: [], brass: [], bullets: [], powders: [] };
let currentRecipe = null;

// showToast, renderPublicToggle → utils.js

// ── Load components (for selects) ─────────────────────────────────────────────

async function loadComponents() {
  const errOption = name => `<option value="">Failed to load ${name} — check console</option>`;
  let primers = [], brass = [], bullets = [], powders = [];

  try {
    [primers, brass, bullets, powders] = await Promise.all([
      apiGetAll('/gears/components/primers/?page_size=1000'),
      apiGetAll('/gears/components/brass/?page_size=1000'),
      apiGetAll('/gears/components/bullets/?page_size=1000'),
      apiGetAll('/gears/components/powders/?page_size=1000'),
    ]);
  } catch(e) {
    console.error('loadComponents failed:', e);
    ['recipePrimer','recipeBrass','recipeBullet','batchPowder'].forEach(id => {
      document.getElementById(id).innerHTML = errOption(id);
    });
    showToast('Failed to load components. Are the component tables populated?', 'danger');
    return;
  }

  components = { primers, brass, bullets, powders };

  // Populate recipe selects
  document.getElementById('recipePrimer').innerHTML =
    '<option value="">Select primer…</option>' +
    (primers.length ? primers.map(p => `<option value="${p.id}">${p.brand} ${p.name} (${p.size})</option>`).join('')
                    : '<option disabled>No primers in database</option>');

  document.getElementById('recipeBrass').innerHTML =
    '<option value="">Select brass…</option>' +
    (brass.length ? brass.map(b => `<option value="${b.id}">${b.brand} ${b.caliber_detail?.name || '?'}</option>`).join('')
                  : '<option disabled>No brass in database</option>');

  document.getElementById('recipeBullet').innerHTML =
    '<option value="">Select bullet…</option>' +
    (bullets.length ? bullets.map(b => `<option value="${b.id}">${b.brand} ${b.model_name} ${b.weight_gr}gr (${b.bullet_type})</option>`).join('')
                    : '<option disabled>No bullets in database</option>');

  // Populate batch powder select
  document.getElementById('batchPowder').innerHTML =
    '<option value="">Select powder…</option>' +
    powders.map(p => `<option value="${p.id}">${p.brand} ${p.name}${p.powder_type ? ' – ' + p.powder_type : ''}</option>`).join('');
}

// ── Recipes sidebar ───────────────────────────────────────────────────────────

function renderRecipesList() {
  const list   = document.getElementById('recipesList');
  const empty  = document.getElementById('recipesEmpty');
  const spinner = document.getElementById('recipesSpinner');
  spinner.classList.add('d-none');

  if (!recipes.length) {
    empty.classList.remove('d-none');
    list.innerHTML = '';
    return;
  }
  empty.classList.add('d-none');

  list.innerHTML = recipes.map(r => `
    <div class="recipe-item p-2 rounded mb-1 ${currentRecipe?.id === r.id ? 'active' : ''}"
         onclick="selectRecipe(${r.id})">
      <div class="fw-semibold small">${r.name}</div>
      <div class="text-muted" style="font-size:.75rem;">
        ${r.caliber_detail?.name || '—'} · ${r.batches.length} batch${r.batches.length === 1 ? '' : 'es'}
      </div>
    </div>
  `).join('');
}

async function loadRecipes() {
  try {
    recipes = await apiGetAll('/reloading/recipes/');
    renderRecipesList();
  } catch(e) {
    document.getElementById('recipesSpinner').classList.add('d-none');
    showToast('Failed to load recipes', 'danger');
  }
}

function selectRecipe(id) {
  currentRecipe = recipes.find(r => r.id === id);
  if (!currentRecipe) return;
  renderRecipesList();
  renderRecipeDetail();
  loadBatches(id);
}

function renderRecipeDetail() {
  const r = currentRecipe;
  document.getElementById('noRecipeMsg').classList.add('d-none');
  document.getElementById('recipeDetail').classList.remove('d-none');
  document.getElementById('detailName').textContent    = r.name;
  document.getElementById('detailCaliber').textContent = r.caliber_detail?.name || '—';
  document.getElementById('detailPrimer').textContent  =
    `${r.primer_detail.brand} ${r.primer_detail.name} (${r.primer_detail.size})`;
  document.getElementById('detailBrass').textContent   =
    `${r.brass_detail.brand} ${r.brass_detail.caliber_detail?.name || '?'}`;
  document.getElementById('detailBullet').textContent  =
    `${r.bullet_detail.brand} ${r.bullet_detail.model_name} ${r.bullet_detail.weight_gr}gr`;
  document.getElementById('detailNotes').textContent   = r.notes || '—';
  renderPublicToggle(r.is_public);
}

// renderPublicToggle → utils.js

document.getElementById('togglePublicBtn').addEventListener('click', async () => {
  if (!currentRecipe) return;
  const newVal = !currentRecipe.is_public;
  try {
    await apiPatch(`/reloading/recipes/${currentRecipe.id}/`, { is_public: newVal });
    currentRecipe.is_public = newVal;
    const idx = recipes.findIndex(r => r.id === currentRecipe.id);
    if (idx >= 0) recipes[idx].is_public = newVal;
    renderPublicToggle(newVal);
    showToast(newVal ? 'Recipe is now public.' : 'Recipe is now private.');
  } catch(e) {
    showToast('Failed to update visibility.', 'danger');
  }
});

// ── Edit / delete recipe ──────────────────────────────────────────────────────

const recipeModal = new bootstrap.Modal('#recipeModal');

document.getElementById('newRecipeBtn').addEventListener('click', async () => {
  document.getElementById('recipeId').value   = '';
  document.getElementById('recipeName').value = '';
  document.getElementById('recipeNotes').value   = '';
  document.getElementById('recipePrimer').value  = '';
  document.getElementById('recipeBrass').value   = '';
  document.getElementById('recipeBullet').value  = '';
  document.getElementById('recipeModalTitle').textContent = 'New recipe';
  document.getElementById('recipeModalAlert').classList.add('d-none');
  const calSel = document.getElementById('recipeCaliber');
  if (calSel && (!calSel.options.length || calSel.options[0].text === 'Loading…')) {
    await loadCalibersIntoSelect(calSel);
  }
  recipeModal.show();
});

document.getElementById('editRecipeBtn').addEventListener('click', async () => {
  if (!currentRecipe) return;
  const r = currentRecipe;
  document.getElementById('recipeId').value      = r.id;
  document.getElementById('recipeName').value    = r.name;
  document.getElementById('recipeNotes').value   = r.notes || '';
  document.getElementById('recipePrimer').value  = r.primer;
  document.getElementById('recipeBrass').value   = r.brass;
  document.getElementById('recipeBullet').value  = r.bullet;
  document.getElementById('recipeModalTitle').textContent = 'Edit recipe';
  document.getElementById('recipeModalAlert').classList.add('d-none');
  const calSel = document.getElementById('recipeCaliber');
  if (calSel && (!calSel.options.length || calSel.options[0].text === 'Loading…')) {
    await loadCalibersIntoSelect(calSel);
  }
  // Set after options are loaded
  calSel.value = r.caliber || '';
  recipeModal.show();
});

document.getElementById('saveRecipeBtn').addEventListener('click', async () => {
  const id      = document.getElementById('recipeId').value;
  const alertEl = document.getElementById('recipeModalAlert');
  alertEl.classList.add('d-none');

  const calVal = document.getElementById('recipeCaliber').value;
  const payload = {
    name:    document.getElementById('recipeName').value.trim(),
    caliber: calVal ? parseInt(calVal) : null,
    primer:  parseInt(document.getElementById('recipePrimer').value),
    brass:   parseInt(document.getElementById('recipeBrass').value),
    bullet:  parseInt(document.getElementById('recipeBullet').value),
    notes:   document.getElementById('recipeNotes').value.trim(),
  };

  if (!payload.name || !payload.caliber || !payload.primer || !payload.brass || !payload.bullet) {
    alertEl.textContent = 'Name, caliber, primer, brass and bullet are required.';
    alertEl.classList.remove('d-none');
    return;
  }

  try {
    if (id) {
      const updated = await apiPatch(`/reloading/recipes/${id}/`, {
        name: payload.name, caliber: payload.caliber || null, notes: payload.notes,
      });
      const idx = recipes.findIndex(r => r.id === parseInt(id));
      if (idx >= 0) recipes[idx] = { ...recipes[idx], ...updated };
      currentRecipe = recipes[idx];
      renderRecipeDetail();
    } else {
      const created = await apiPost('/reloading/recipes/', payload);
      recipes.push(created);
      currentRecipe = created;
      renderRecipeDetail();
      document.getElementById('batchesBody').innerHTML = '';
      document.getElementById('batchesEmpty').classList.remove('d-none');
      document.getElementById('batchesTableWrap').classList.add('d-none');
      document.getElementById('noRecipeMsg').classList.add('d-none');
      document.getElementById('recipeDetail').classList.remove('d-none');
    }
    renderRecipesList();
    recipeModal.hide();
    showToast(id ? 'Recipe updated!' : 'Recipe created!');
  } catch(e) {
    alertEl.textContent = formatErrors(e.data);
    alertEl.classList.remove('d-none');
  }
});

document.getElementById('deleteRecipeBtn').addEventListener('click', async () => {
  if (!currentRecipe) return;
  if (!confirm(`Delete recipe "${currentRecipe.name}"? All its batches will be deleted too.`)) return;
  try {
    await apiDelete(`/reloading/recipes/${currentRecipe.id}/`);
    recipes = recipes.filter(r => r.id !== currentRecipe.id);
    currentRecipe = null;
    renderRecipesList();
    document.getElementById('recipeDetail').classList.add('d-none');
    document.getElementById('noRecipeMsg').classList.remove('d-none');
    showToast('Recipe deleted.');
  } catch(e) {
    showToast('Failed to delete recipe.', 'danger');
  }
});

// ── Batches ───────────────────────────────────────────────────────────────────

let batches = [];

function renderBatches() {
  const tbody = document.getElementById('batchesBody');
  const wrap  = document.getElementById('batchesTableWrap');
  const empty = document.getElementById('batchesEmpty');
  document.getElementById('batchesSpinner').classList.add('d-none');

  if (!batches.length) {
    empty.classList.remove('d-none');
    wrap.classList.add('d-none');
    return;
  }
  empty.classList.add('d-none');
  wrap.classList.remove('d-none');

  tbody.innerHTML = batches.map(b => `
    <tr>
      <td>${b.powder_detail.brand} ${b.powder_detail.name}</td>
      <td><strong>${b.powder_charge_gr}</strong></td>
      <td>${b.quantity ?? '—'}</td>
      <td>${b.oal_mm ?? '—'}</td>
      <td><span class="badge bg-secondary">${b.crimp}</span></td>
      <td>${b.loaded_at ?? '—'}</td>
      <td class="text-end">
        <button class="btn btn-sm btn-outline-secondary me-1" onclick="openEditBatch(${b.id})">
          <i class="bi bi-pencil"></i>
        </button>
        <button class="btn btn-sm btn-outline-danger" onclick="deleteBatch(${b.id})">
          <i class="bi bi-trash"></i>
        </button>
      </td>
    </tr>
  `).join('');
}

async function loadBatches(recipeId) {
  const spinner = document.getElementById('batchesSpinner');
  spinner.classList.remove('d-none');
  document.getElementById('batchesEmpty').classList.add('d-none');
  document.getElementById('batchesTableWrap').classList.add('d-none');
  try {
    batches = await apiGet(`/reloading/batches/?recipe=${recipeId}`);
    renderBatches();
  } catch(e) {
    spinner.classList.add('d-none');
    showToast('Failed to load batches', 'danger');
  }
}

// Create / Edit Batch modal
const batchModal = new bootstrap.Modal('#batchModal');

document.getElementById('newBatchBtn').addEventListener('click', () => {
  document.getElementById('batchId').value     = '';
  document.getElementById('batchCharge').value = '';
  document.getElementById('batchQty').value    = '';
  document.getElementById('batchOal').value    = '';
  document.getElementById('batchCoal').value   = '';
  document.getElementById('batchCrimp').value  = 'NONE';
  document.getElementById('batchLoaded').value = '';
  document.getElementById('batchCasePrep').value = '';
  document.getElementById('batchNotes').value  = '';
  document.getElementById('batchPowder').value = '';
  document.getElementById('batchModalTitle').textContent = 'New batch';
  document.getElementById('batchModalAlert').classList.add('d-none');
  batchModal.show();
});

function openEditBatch(id) {
  const b = batches.find(x => x.id === id);
  if (!b) return;
  document.getElementById('batchId').value       = id;
  document.getElementById('batchPowder').value   = b.powder;
  document.getElementById('batchCharge').value   = b.powder_charge_gr;
  document.getElementById('batchQty').value      = b.quantity ?? '';
  document.getElementById('batchOal').value      = b.oal_mm ?? '';
  document.getElementById('batchCoal').value     = b.coal_mm ?? '';
  document.getElementById('batchCrimp').value    = b.crimp || 'NONE';
  document.getElementById('batchLoaded').value   = b.loaded_at ?? '';
  document.getElementById('batchCasePrep').value = b.case_prep_notes ?? '';
  document.getElementById('batchNotes').value    = b.notes ?? '';
  document.getElementById('batchModalTitle').textContent = 'Edit batch';
  document.getElementById('batchModalAlert').classList.add('d-none');
  batchModal.show();
}

document.getElementById('saveBatchBtn').addEventListener('click', async () => {
  if (!currentRecipe) return;
  const id      = document.getElementById('batchId').value;
  const alertEl = document.getElementById('batchModalAlert');
  alertEl.classList.add('d-none');

  const payload = {
    recipe:            currentRecipe.id,
    powder:            parseInt(document.getElementById('batchPowder').value),
    powder_charge_gr:  document.getElementById('batchCharge').value,
    crimp:             document.getElementById('batchCrimp').value,
  };
  const qty   = document.getElementById('batchQty').value;
  const oal   = document.getElementById('batchOal').value;
  const coal  = document.getElementById('batchCoal').value;
  const loaded = document.getElementById('batchLoaded').value;
  const casePrep = document.getElementById('batchCasePrep').value.trim();
  const notes = document.getElementById('batchNotes').value.trim();
  if (qty)      payload.quantity       = parseInt(qty);
  if (oal)      payload.oal_mm         = oal;
  if (coal)     payload.coal_mm        = coal;
  if (loaded)   payload.loaded_at      = loaded;
  if (casePrep) payload.case_prep_notes = casePrep;
  if (notes)    payload.notes          = notes;

  if (!payload.powder || !payload.powder_charge_gr) {
    alertEl.textContent = 'Powder and charge are required.';
    alertEl.classList.remove('d-none');
    return;
  }

  try {
    if (id) {
      const updated = await apiPatch(`/reloading/batches/${id}/`, payload);
      const idx = batches.findIndex(b => b.id === parseInt(id));
      if (idx >= 0) batches[idx] = updated;
    } else {
      const created = await apiPost('/reloading/batches/', payload);
      batches.push(created);
      // Update recipe batch count
      const ri = recipes.findIndex(r => r.id === currentRecipe.id);
      if (ri >= 0) recipes[ri].batches = batches;
      renderRecipesList();
    }
    renderBatches();
    batchModal.hide();
    showToast(id ? 'Batch updated!' : 'Batch created!');
  } catch(e) {
    alertEl.textContent = formatErrors(e.data);
    alertEl.classList.remove('d-none');
  }
});

async function deleteBatch(id) {
  if (!confirm('Delete this batch?')) return;
  try {
    await apiDelete(`/reloading/batches/${id}/`);
    batches = batches.filter(b => b.id !== id);
    renderBatches();
    // Update recipe batch count
    const ri = recipes.findIndex(r => r.id === currentRecipe?.id);
    if (ri >= 0) recipes[ri].batches = batches;
    renderRecipesList();
    showToast('Batch deleted.');
  } catch(e) {
    showToast('Failed to delete batch.', 'danger');
  }
}

// ── Suggest component (user submission) ──────────────────────────────────────

const COMP_SUGGEST_FORMS = {
  primers: {
    endpoint: '/gears/components/primers/',
    selectId: 'recipePrimer',
    html: `
      <div class="card bg-light border-0 p-2 small">
        <p class="text-muted mb-1"><i class="bi bi-info-circle me-1"></i>Pending admin approval. Usable by you immediately.</p>
        <input type="text" class="form-control form-control-sm mb-1" data-field="brand" placeholder="Brand *">
        <input type="text" class="form-control form-control-sm mb-1" data-field="name"  placeholder="Name *">
        <select class="form-select form-select-sm mb-1" data-field="size">
          <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 class="comp-suggest-alert alert alert-danger d-none py-1 mb-1"></div>
        <button class="btn btn-xs btn-primary btn-sm w-100 comp-suggest-submit">Submit</button>
      </div>`,
    payload: (box) => ({
      brand: box.querySelector('[data-field=brand]').value.trim(),
      name:  box.querySelector('[data-field=name]').value.trim(),
      size:  box.querySelector('[data-field=size]').value,
    }),
    label: (c) => `${c.brand} ${c.name} (${c.size}) [pending]`,
  },
  brass: {
    endpoint: '/gears/components/brass/',
    selectId: 'recipeBrass',
    html: `
      <div class="card bg-light border-0 p-2 small">
        <p class="text-muted mb-1"><i class="bi bi-info-circle me-1"></i>Pending admin approval. Usable by you immediately.</p>
        <input type="text" class="form-control form-control-sm mb-1" data-field="brand" placeholder="Brand *">
        <select class="form-select form-select-sm mb-1" data-field="caliber"><option value="">Loading calibers…</option></select>
        <div class="comp-suggest-alert alert alert-danger d-none py-1 mb-1"></div>
        <button class="btn btn-sm btn-primary w-100 comp-suggest-submit">Submit</button>
      </div>`,
    payload: (box) => {
      const cal = box.querySelector('[data-field=caliber]').value;
      return { brand: box.querySelector('[data-field=brand]').value.trim(), caliber: cal ? parseInt(cal) : undefined };
    },
    label: (c) => `${c.brand} ${c.caliber_detail?.name || '?'} [pending]`,
  },
  bullets: {
    endpoint: '/gears/components/bullets/',
    selectId: 'recipeBullet',
    html: `
      <div class="card bg-light border-0 p-2 small">
        <p class="text-muted mb-1"><i class="bi bi-info-circle me-1"></i>Pending admin approval. Usable by you immediately.</p>
        <input type="text"   class="form-control form-control-sm mb-1" data-field="brand"      placeholder="Brand *">
        <input type="text"   class="form-control form-control-sm mb-1" data-field="model_name" placeholder="Model name *">
        <input type="number" class="form-control form-control-sm mb-1" data-field="weight_gr"  placeholder="Weight (gr) *" step="0.1">
        <select class="form-select form-select-sm mb-1" data-field="bullet_type">
          <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 class="comp-suggest-alert alert alert-danger d-none py-1 mb-1"></div>
        <button class="btn btn-sm btn-primary w-100 comp-suggest-submit">Submit</button>
      </div>`,
    payload: (box) => ({
      brand:       box.querySelector('[data-field=brand]').value.trim(),
      model_name:  box.querySelector('[data-field=model_name]').value.trim(),
      weight_gr:   box.querySelector('[data-field=weight_gr]').value,
      bullet_type: box.querySelector('[data-field=bullet_type]').value,
    }),
    label: (c) => `${c.brand} ${c.model_name} ${c.weight_gr}gr (${c.bullet_type}) [pending]`,
  },
  powders: {
    endpoint: '/gears/components/powders/',
    selectId: 'batchPowder',
    html: `
      <div class="card bg-light border-0 p-2 small">
        <p class="text-muted mb-1"><i class="bi bi-info-circle me-1"></i>Pending admin approval. Usable by you immediately.</p>
        <input type="text" class="form-control form-control-sm mb-1" data-field="brand" placeholder="Brand *">
        <input type="text" class="form-control form-control-sm mb-1" data-field="name"  placeholder="Name *">
        <select class="form-select form-select-sm mb-1" data-field="powder_type">
          <option value="">Type (optional)</option>
          <option value="BALL">Ball/Spherical</option>
          <option value="EXTRUDED">Extruded/Stick</option>
          <option value="FLAKE">Flake</option>
        </select>
        <div class="comp-suggest-alert alert alert-danger d-none py-1 mb-1"></div>
        <button class="btn btn-sm btn-primary w-100 comp-suggest-submit">Submit</button>
      </div>`,
    payload: (box) => {
      const p = {
        brand: box.querySelector('[data-field=brand]').value.trim(),
        name:  box.querySelector('[data-field=name]').value.trim(),
      };
      const t = box.querySelector('[data-field=powder_type]').value;
      if (t) p.powder_type = t;
      return p;
    },
    label: (c) => `${c.brand} ${c.name}${c.powder_type ? ' – ' + c.powder_type : ''} [pending]`,
  },
};

// Attach suggest-link handlers (works for both recipe modal and batch modal)
document.addEventListener('click', async e => {
  const link = e.target.closest('.suggest-comp-link');
  if (!link) return;
  e.preventDefault();
  const compType = link.dataset.comp;
  const box = link.closest('.col-md-4, .col-md-6').querySelector('.suggest-comp-form');
  const cfg = COMP_SUGGEST_FORMS[compType];
  if (!box || !cfg) return;

  if (box.innerHTML) { box.classList.toggle('d-none'); return; }
  box.innerHTML = cfg.html;
  box.classList.remove('d-none');
  // If brass, load calibers into its select
  if (compType === 'brass') {
    const calSel = box.querySelector('[data-field=caliber]');
    if (calSel) loadCalibersIntoSelect(calSel);
  }

  box.querySelector('.comp-suggest-submit').addEventListener('click', async () => {
    const alertEl = box.querySelector('.comp-suggest-alert');
    alertEl.classList.add('d-none');
    const payload = cfg.payload(box);
    if (!payload.brand || !payload.name && !payload.caliber && !payload.model_name) {
      alertEl.textContent = 'Required fields are missing.';
      alertEl.classList.remove('d-none');
      return;
    }
    try {
      const created = await apiPost(cfg.endpoint, payload);
      // Add to the corresponding select and auto-select it
      const sel = document.getElementById(cfg.selectId);
      const opt = new Option(cfg.label(created), created.id, true, true);
      sel.appendChild(opt);
      // Add to components cache too
      if (components[compType]) components[compType].push(created);
      box.classList.add('d-none');
      showToast('Component submitted! It is now available in the selector.');
    } catch(err) {
      alertEl.textContent = formatErrors(err.data) || 'Submission failed.';
      alertEl.classList.remove('d-none');
    }
  });
});

// ── Init ──────────────────────────────────────────────────────────────────────
loadComponents();
loadRecipes();
