// ─── Savuki Drilling — Leads Module ──────────────────────────────────────
import {
  getLeads, getLead, createLead, updateLead, assignLead,
  getTeams, getNextJcNo, getJobcards, getToken
} from '../api.js';
import { showToast, navigate, openModal, closeModal } from '../app.js';
import { richSelect, teamItems, jobcardItems } from './rich-select.js';

// ── Lead statuses (while still a lead) ───────────────────────────────────
const LEAD_STATUSES = [
  'WAITING FOR DEPOSIT',
  'FOLLOW UP',
  'QUOTE SENT',
  'WAITING FOR CONFIRMATION',
  'CLIENT CANCELED',
];

let _teams = [];
let mTeamRs = null;

// ─────────────────────────────────────────────────────────────────────────
// LEADS LIST
// ─────────────────────────────────────────────────────────────────────────

export async function initLeads() {
  const c = document.getElementById('view-content');
  c.innerHTML = pageShell('Leads', `
    <div class="toolbar">
      <div class="toolbar-filters">
        <input class="form-control" id="f-jcno"   placeholder="JC #"   style="width:90px" />
        <input class="form-control" id="f-area"   placeholder="Area / address" style="width:180px" />
        <select class="form-control" id="f-type"  style="width:130px">
          <option value="">All Types</option>
          <option value="LEAD">Leads</option>
          <option value="JOBCARD">Jobcards</option>
        </select>
        <select class="form-control" id="f-status" style="width:200px">
          <option value="">All Statuses</option>
          ${LEAD_STATUSES.map(s => `<option value="${s}">${s}</option>`).join('')}
          <option value="1">Assigned</option>
        </select>
      </div>
      <button class="btn btn-accent" id="btn-create-lead">
        ${plusIcon()} New Lead / Jobcard
      </button>
    </div>

    <div id="leads-table-wrap" class="card" style="margin-top:1rem">
      <div class="card-body" style="padding:0">
        <div class="page-loader"><div class="spinner"></div></div>
      </div>
    </div>
  `);

  // Load teams for later use in modals
  try { _teams = await getTeams(); } catch { }

  // Bind filters
  ['f-jcno', 'f-area', 'f-type', 'f-status'].forEach(id => {
    document.getElementById(id)?.addEventListener('input', debounce(loadLeads, 350));
    document.getElementById(id)?.addEventListener('change', loadLeads);
  });

  document.getElementById('btn-create-lead')?.addEventListener('click', openCreateModal);

  await loadLeads();
}

async function loadLeads() {
  const wrap = document.getElementById('leads-table-wrap');
  if (!wrap) return;

  const params = {
    jc_no: document.getElementById('f-jcno')?.value || '',
    area: document.getElementById('f-area')?.value || '',
    type: document.getElementById('f-type')?.value || '',
    status: document.getElementById('f-status')?.value || '',
  };

  wrap.innerHTML = `<div class="card-body" style="padding:0">
    <div class="page-loader"><div class="spinner"></div></div>
  </div>`;

  try {
    const rows = await getLeads(params);
    wrap.innerHTML = `<div class="card-body" style="padding:0">${renderLeadsTable(rows)}</div>`;

    wrap.querySelectorAll('[data-edit]').forEach(btn => {
      btn.addEventListener('click', () => openEditModal(btn.dataset.edit));
    });
    wrap.querySelectorAll('[data-assign]').forEach(btn => {
      btn.addEventListener('click', () => openAssignModal(btn.dataset.assign));
    });
    // re-bind show-more
    wrap.querySelectorAll('.show-more-btn').forEach(btn => {
      btn.addEventListener('click', () => {
        const tbody = btn.closest('tbody');
        const hidden = tbody.querySelectorAll('tr.extra-row');
        const exp = btn.dataset.expanded === 'true';
        hidden.forEach(r => r.style.display = exp ? 'none' : '');
        btn.dataset.expanded = exp ? 'false' : 'true';
        btn.textContent = exp ? `Show all ${btn.dataset.total}` : 'Show less';
      });
    });
  } catch (err) {
    wrap.innerHTML = `<div class="card-body"><div class="empty-state"><p>${err.message}</p></div></div>`;
  }
}

function renderLeadsTable(rows) {
  if (!rows.length) return `<div class="empty-state" style="padding:2rem"><p>No leads found.</p></div>`;

  const PREVIEW = 20;
  const html = rows.map((r, i) => {
    const isAssigned = r.status === '1';
    const hidden = i >= PREVIEW ? ' class="extra-row" style="display:none"' : '';
    return `<tr${hidden}>
      <td data-label="JC #"><strong>#${r.jc_no}</strong></td>
      <td data-label="Type">${typeBadge(r.type)}</td>
      <td data-label="Contact">${r.contact_number || '—'}</td>
      <td data-label="Area">${r.address || '—'}</td>
      <td data-label="Status">${statusBadge(r.status)}</td>
      <td data-label="Team">${r.team_name ? `<span class="badge badge-navy">${r.team_name}</span>` : '<span style="color:var(--text-muted)">Unassigned</span>'}</td>
      <td data-label="Created By" style="color:var(--text-muted);font-size:0.8rem">${r.created_by || '—'}</td>
      <td data-label="">
        <div style="display:flex;gap:0.4rem;justify-content:flex-end">
          <button class="btn btn-ghost btn-sm" data-edit="${r.record_id}">Edit</button>
          ${!isAssigned ? `<button class="btn btn-accent btn-sm" data-assign="${r.record_id}">Assign</button>` : ''}
        </div>
      </td>
    </tr>`;
  }).join('');

  const showMore = rows.length > PREVIEW
    ? `<tr class="show-more-row"><td colspan="99" data-label="">
        <button class="show-more-btn" data-expanded="false" data-total="${rows.length}">Show all ${rows.length}</button>
       </td></tr>` : '';

  return `<div class="table-wrap"><table>
    <thead><tr>
      <th>JC #</th><th>Type</th><th>Contact</th><th>Area</th>
      <th>Status</th><th>Team</th><th>Created By</th><th></th>
    </tr></thead>
    <tbody>${html}${showMore}</tbody>
  </table></div>`;
}

function typeBadge(type) {
  if (type === 'JOBCARD') return `<span class="badge badge-active">Jobcard</span>`;
  return `<span class="badge badge-navy">Lead</span>`;
}

function statusBadge(status) {
  if (status === '1') return `<span class="badge badge-active">Assigned</span>`;
  if (status === 'CLIENT CANCELED') return `<span class="badge badge-complete">Canceled</span>`;
  if (status === 'WAITING FOR DEPOSIT') return `<span class="badge badge-pending">Waiting Deposit</span>`;
  if (status === 'FOLLOW UP') return `<span class="badge badge-pending">Follow Up</span>`;
  if (status === 'QUOTE SENT') return `<span class="badge badge-orange">Quote Sent</span>`;
  if (status === 'WAITING FOR CONFIRMATION') return `<span class="badge badge-pending">Waiting Confirm</span>`;
  return `<span class="badge badge-complete">${status || 'New'}</span>`;
}

// ─────────────────────────────────────────────────────────────────────────
// CREATE MODAL — new lead or direct jobcard
// ─────────────────────────────────────────────────────────────────────────

async function openCreateModal() {
  let nextNo = '…';
  try { nextNo = (await getNextJcNo()).next_jc_no; } catch { }

  const teamOptions = _teams.map(t =>
    `<option value="${t.record_id}">${t.name}</option>`).join('');

  openModal('New Lead / Jobcard', `
    <div class="form-group">
      <label class="form-label">JC Number</label>
      <input class="form-control" value="${nextNo}" readonly style="background:var(--surface-2);color:var(--text-muted)" />
    </div>

    <div class="form-group">
      <label class="form-label">Type <span style="color:var(--danger)">*</span></label>
      <select class="form-control" id="m-type" required>
        <option value="LEAD">Lead</option>
        <option value="JOBCARD" selected>Direct Jobcard (assign team now)</option>
      </select>
    </div>

    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Contact Number <span style="color:var(--danger)">*</span></label>
        <input class="form-control" id="m-contact" type="tel" placeholder="e.g. 082 000 0000" required />
      </div>
      <div class="form-group">
        <label class="form-label">Other Number</label>
        <input class="form-control" id="m-other" type="tel" />
      </div>
    </div>

    <div class="form-group">
      <label class="form-label">Alternate Number</label>
      <input class="form-control" id="m-alt" type="tel" />
    </div>

    <div class="form-group">
      <label class="form-label">Area / Address <span style="color:var(--danger)">*</span></label>
      <input class="form-control" id="m-area" placeholder="Town or area" required />
    </div>

    <div id="m-status-wrap" class="form-group">
      <label class="form-label">Status</label>
      <select class="form-control" id="m-status">
        ${LEAD_STATUSES.map(s => `<option value="${s}">${s}</option>`).join('')}
      </select>
    </div>

    <div id="m-team-wrap" class="form-group" style="display:none">
      <label class="form-label">Assign Team <span style="color:var(--danger)">*</span></label>
      <div id="m-team-rs"></div>
    </div>

    <div class="form-group">
      <label class="form-label">Additional Notes</label>
      <textarea class="form-control" id="m-notes" rows="3" placeholder="Any notes…"></textarea>
    </div>

    <div id="m-error" class="login-error"></div>
  `, async () => {
    await submitCreate();
  });

  // Default is JOBCARD — show team selector and hide status immediately
  mTeamRs = richSelect('m-team-rs', { placeholder: 'Search teams…', items: teamItems(_teams) });
  document.getElementById('m-team-wrap').style.display = '';
  document.getElementById('m-status-wrap').style.display = 'none';

  document.getElementById('m-type')?.addEventListener('change', e => {
    const isJobcard = e.target.value === 'JOBCARD';
    document.getElementById('m-team-wrap').style.display = isJobcard ? '' : 'none';
    document.getElementById('m-status-wrap').style.display = isJobcard ? 'none' : '';
    if (isJobcard && !mTeamRs) {
      mTeamRs = richSelect('m-team-rs', { placeholder: 'Search teams…', items: teamItems(_teams) });
    }
  });
}

async function submitCreate() {
  const type = document.getElementById('m-type').value;
  const contact = document.getElementById('m-contact').value.trim();
  const area = document.getElementById('m-area').value.trim();
  const errEl = document.getElementById('m-error');

  errEl.classList.remove('visible');

  if (!contact) { errEl.textContent = 'Contact number is required.'; errEl.classList.add('visible'); return; }
  if (!area) { errEl.textContent = 'Area / address is required.'; errEl.classList.add('visible'); return; }
  if (type === 'JOBCARD' && !mTeamRs?.getValue()) {
    errEl.textContent = 'Please select a team.'; errEl.classList.add('visible'); return;
  }

  try {
    const res = await createLead({
      type,
      contact_number: contact,
      other_number: document.getElementById('m-other').value,
      alternate_number: document.getElementById('m-alt').value,
      area,
      status: type === 'LEAD' ? document.getElementById('m-status').value : '',
      team_id: type === 'JOBCARD' ? (mTeamRs?.getValue() || '') : '',
      additional_notes: document.getElementById('m-notes').value,
    });

    closeModal();
    showToast(`JC #${res.jc_no} created successfully.`, 'success');
    await loadLeads();
    await reloadJobcardsTable(); // also refresh jobcards tab if visible
  } catch (err) {
    errEl.textContent = err.message;
    errEl.classList.add('visible');
  }
}

// ─────────────────────────────────────────────────────────────────────────
// EDIT MODAL — update lead details/status
// ─────────────────────────────────────────────────────────────────────────

async function openEditModal(recordId) {
  let lead;
  try { lead = await getLead(recordId); } catch (err) { showToast(err.message, 'error'); return; }

  openModal(`Edit Lead / Jobcard — JC #${lead.jc_no}`, `
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Contact Number</label>
        <input class="form-control" id="e-contact" value="${lead.contact_number || ''}" />
      </div>
      <div class="form-group">
        <label class="form-label">Other Number</label>
        <input class="form-control" id="e-other" value="${lead.other_number || ''}" />
      </div>
    </div>
    <div class="form-group">
      <label class="form-label">Alternate Number</label>
      <input class="form-control" id="e-alt" value="${lead.alternate_number || ''}" />
    </div>
    <div class="form-group">
      <label class="form-label">Area / Address</label>
      <input class="form-control" id="e-area" value="${lead.address || ''}" />
    </div>
    ${lead.status !== '1' ? `
    <div class="form-group">
      <label class="form-label">Status</label>
      <select class="form-control" id="e-status">
        ${LEAD_STATUSES.map(s =>
    `<option value="${s}" ${lead.status === s ? 'selected' : ''}>${s}</option>`
  ).join('')}
      </select>
    </div>` : `
    <div class="form-group">
      <label class="form-label">Status</label>
      <input class="form-control" value="Assigned to ${lead.team_name || 'team'}" readonly
             style="background:var(--surface-2);color:var(--text-muted)" />
    </div>`}
    <div class="form-group">
      <label class="form-label">Additional Notes</label>
      <textarea class="form-control" id="e-notes" rows="3">${lead.additional_notes || ''}</textarea>
    </div>
    <div id="e-error" class="login-error"></div>
  `, async () => {
    const errEl = document.getElementById('e-error');
    errEl.classList.remove('visible');
    try {
      await updateLead({
        record_id: recordId,
        contact_number: document.getElementById('e-contact').value,
        other_number: document.getElementById('e-other').value,
        alternate_number: document.getElementById('e-alt').value,
        area: document.getElementById('e-area').value,
        status: document.getElementById('e-status')?.value || lead.status,
        additional_notes: document.getElementById('e-notes').value,
      });
      closeModal();
      showToast('Lead updated.', 'success');
      await loadLeads();
    } catch (err) {
      errEl.textContent = err.message;
      errEl.classList.add('visible');
    }
  });
}

// ─────────────────────────────────────────────────────────────────────────
// ASSIGN MODAL — convert lead → jobcard by picking a team
// ─────────────────────────────────────────────────────────────────────────

export async function initAssign() {
  const c = document.getElementById('view-content');
  c.innerHTML = pageShell('Assign Jobcard', `
    <p style="color:var(--text-muted);margin-bottom:1rem;font-size:0.9rem">
      Leads listed below are unassigned. Click <strong>Assign Team</strong> to convert a lead
      into a live drilling jobcard.
    </p>
    <div id="assign-table-wrap" class="card">
      <div class="card-body" style="padding:0">
        <div class="page-loader"><div class="spinner"></div></div>
      </div>
    </div>
  `);

  try { _teams = await getTeams(); } catch { }
  await loadUnassigned();
}

async function loadUnassigned() {
  const wrap = document.getElementById('assign-table-wrap');
  if (!wrap) return;
  try {
    const rows = await getLeads({ type: 'LEAD' });
    const unassigned = rows.filter(r => r.status !== '1' && r.status !== 'CLIENT CANCELED');
    wrap.innerHTML = `<div class="card-body" style="padding:0">${renderAssignTable(unassigned)}</div>`;
    wrap.querySelectorAll('[data-assign]').forEach(btn => {
      btn.addEventListener('click', () => openAssignModal(btn.dataset.assign));
    });
  } catch (err) {
    wrap.innerHTML = `<div class="card-body"><div class="empty-state"><p>${err.message}</p></div></div>`;
  }
}

function renderAssignTable(rows) {
  if (!rows.length) return `<div class="empty-state" style="padding:2rem">
    <p>No unassigned leads.</p></div>`;

  return `<div class="table-wrap"><table>
    <thead><tr>
      <th>JC #</th><th>Contact</th><th>Area</th>
      <th>Status</th><th>Created By</th><th></th>
    </tr></thead>
    <tbody>
      ${rows.map(r => `<tr>
        <td data-label="JC #"><strong>#${r.jc_no}</strong></td>
        <td data-label="Contact">${r.contact_number || '—'}</td>
        <td data-label="Area">${r.address || '—'}</td>
        <td data-label="Status">${statusBadge(r.status)}</td>
        <td data-label="Created By" style="color:var(--text-muted);font-size:0.8rem">${r.created_by || '—'}</td>
        <td data-label="">
          <button class="btn btn-accent btn-sm" data-assign="${r.record_id}">Assign Team</button>
        </td>
      </tr>`).join('')}
    </tbody>
  </table></div>`;
}

async function openAssignModal(recordId) {
  let lead;
  try { lead = await getLead(recordId); } catch (err) { showToast(err.message, 'error'); return; }

  const teamOptions = _teams.map(t =>
    `<option value="${t.record_id}">${t.name}</option>`).join('');

  openModal(`Assign Team — JC #${lead.jc_no}`, `
    <div style="background:var(--surface-2);border:1px solid var(--border);border-radius:var(--radius);
                padding:0.85rem 1rem;margin-bottom:1.25rem;font-size:0.875rem">
      <div><strong>Contact:</strong> ${lead.contact_number || '—'}</div>
      <div style="margin-top:0.25rem"><strong>Area:</strong> ${lead.address || '—'}</div>
      ${lead.additional_notes ? `<div style="margin-top:0.25rem"><strong>Notes:</strong> ${lead.additional_notes}</div>` : ''}
    </div>

    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Contact Number</label>
        <input class="form-control" id="a-contact" value="${lead.contact_number || ''}" />
      </div>
      <div class="form-group">
        <label class="form-label">Other Number</label>
        <input class="form-control" id="a-other" value="${lead.other_number || ''}" />
      </div>
    </div>

    <div class="form-group">
      <label class="form-label">Alternate Number</label>
      <input class="form-control" id="a-alt" value="${lead.alternate_number || ''}" />
    </div>

    <div class="form-group">
      <label class="form-label">Area / Address <span style="color:var(--danger)">*</span></label>
      <input class="form-control" id="a-area" value="${lead.address || ''}" required />
    </div>

    <div class="form-group">
      <label class="form-label">Assign Team <span style="color:var(--danger)">*</span></label>
      <div id="a-team-rs" style="--rs-label-color:#000"></div>
    </div>

    <div class="form-group">
      <label class="form-label">Additional Notes</label>
      <textarea class="form-control" id="a-notes" rows="3">${lead.additional_notes || ''}</textarea>
    </div>

    <div style="background:var(--warning-bg);border:1px solid var(--warning);border-radius:var(--radius);
                padding:0.7rem 1rem;font-size:0.82rem;color:var(--warning);margin-bottom:0.5rem">
      ⚠ Assigning a team will convert this lead into a live <strong>Drilling Jobcard</strong>
      with status <strong>PENDING</strong>.
    </div>

    <div id="a-error" class="login-error"></div>
  `, async () => {
    const errEl = document.getElementById('a-error');
    errEl.classList.remove('visible');
    const teamId = aTeamRs?.getValue();
    const area = document.getElementById('a-area').value.trim();
    if (!teamId) { errEl.textContent = 'Please select a team.'; errEl.classList.add('visible'); return; }
    if (!area) { errEl.textContent = 'Area is required.'; errEl.classList.add('visible'); return; }

    try {
      const res = await assignLead({
        record_id: recordId,
        team_id: teamId,
        contact_number: document.getElementById('a-contact').value,
        other_number: document.getElementById('a-other').value,
        alternate_number: document.getElementById('a-alt').value,
        area,
        additional_notes: document.getElementById('a-notes').value,
      });

      closeModal();
      showToast(res.message || `JC #${lead.jc_no} assigned!`, 'success');

      // Reload whichever list is visible
      const assignWrap = document.getElementById('assign-table-wrap');
      if (assignWrap) await loadUnassigned();
      else await loadLeads();

    } catch (err) {
      errEl.textContent = err.message;
      errEl.classList.add('visible');
    }
  }, { confirmLabel: 'Assign & Create Jobcard', confirmClass: 'btn-accent' });

  // Init team rich select after modal is in DOM
  const aTeamRs = richSelect('a-team-rs', { placeholder: 'Search teams…', items: teamItems(_teams) });
}

// ─────────────────────────────────────────────────────────────────────────
// JOBCARDS LIST PAGE
// ─────────────────────────────────────────────────────────────────────────

export async function initJobcards() {
  const c = document.getElementById('view-content');
  c.innerHTML = pageShell('Jobcards', `
    <!-- Stat cards -->
    <div class="stat-grid" id="jc-stats" style="margin-bottom:1rem">
      <div class="stat-card navy">
        <div class="stat-label">New <span id="jc-stat-this-label">This Month</span></div>
        <div class="stat-value" id="jc-stat-this">—</div>
      </div>
      <div class="stat-card blue">
        <div class="stat-label">New <span id="jc-stat-last-label">Last Month</span></div>
        <div class="stat-value" id="jc-stat-last">—</div>
      </div>
      <div class="stat-card orange">
        <div class="stat-label">Active Now</div>
        <div class="stat-value" id="jc-stat-active">—</div>
      </div>
      <div class="stat-card green">
        <div class="stat-label">Completed <span id="jc-stat-comp-label">This Month</span></div>
        <div class="stat-value" id="jc-stat-comp">—</div>
      </div>
    </div>
    <div class="toolbar">
      <div class="toolbar-filters">
        <input class="form-control" id="jc-no" placeholder="JC #" style="width:90px" />
        <select class="form-control" id="jc-status" style="width:160px">
          <option value="">All Statuses</option>
          <option value="PENDING">Pending</option>
          <option value="ACTIVE">Active</option>
          <option value="DRILLING">Drilling</option>
          <option value="COMPLETE">Complete</option>
        </select>
      </div>
      <button class="btn btn-accent" id="btn-new-jc">+ New Jobcard</button>
    </div>
    <div id="jc-table-wrap" class="card" style="margin-top:1rem">
      <div class="card-body" style="padding:0">
        <div class="page-loader"><div class="spinner"></div></div>
      </div>
    </div>
  `);

  // Load stats async (non-blocking)
  const tok = getToken();
  fetch(`/api/jobcards/stats.php?token=${tok}`)
    .then(r => r.json())
    .then(json => {
      if (!json.success) return;
      const s = json.data;
      const el = (id, v) => { const e = document.getElementById(id); if (e) e.textContent = v; };
      el('jc-stat-this-label', s.this_month_label);
      el('jc-stat-last-label', s.last_month_label);
      el('jc-stat-comp-label', s.this_month_label);
      el('jc-stat-this', s.jc_this_month);
      el('jc-stat-last', s.jc_last_month);
      el('jc-stat-active', s.jc_active);
      el('jc-stat-comp', s.jc_completed_this);
    }).catch(() => { });

  document.getElementById('jc-no')?.addEventListener('input', debounce(reloadJobcardsTable, 350));
  document.getElementById('jc-status')?.addEventListener('change', reloadJobcardsTable);
  document.getElementById('btn-new-jc')?.addEventListener('click', async () => {
    if (!_teams.length) { try { _teams = await getTeams(); } catch { } }
    openCreateModal();
  });

  await reloadJobcardsTable();
}

// Module-level reload for the jobcards table — callable from anywhere
async function reloadJobcardsTable() {
  const wrap = document.getElementById('jc-table-wrap');
  if (!wrap) return;
  const params = {
    jc_no: document.getElementById('jc-no')?.value || '',
    status: document.getElementById('jc-status')?.value || '',
  };
  wrap.innerHTML = `<div class="card-body" style="padding:0"><div class="page-loader"><div class="spinner"></div></div></div>`;
  try {
    const rows = await getJobcards(params);
    wrap.innerHTML = `<div class="card-body" style="padding:0">${renderJobcardsTable(rows)}</div>`;
    wrap.querySelectorAll('.jc-view-btn').forEach(btn => {
      btn.addEventListener('click', () => navigate('jobcard-view', { id: +btn.dataset.id }));
    });
    wrap.querySelectorAll('.show-more-btn').forEach(btn => {
      btn.addEventListener('click', () => {
        const tbody = btn.closest('tbody');
        const hidden = tbody.querySelectorAll('tr.extra-row');
        const exp = btn.dataset.expanded === 'true';
        hidden.forEach(r => r.style.display = exp ? 'none' : '');
        btn.dataset.expanded = exp ? 'false' : 'true';
        btn.textContent = exp ? `Show all ${btn.dataset.total}` : 'Show less';
      });
    });
  } catch (err) {
    wrap.innerHTML = `<div class="card-body"><div class="empty-state"><p>${err.message}</p></div></div>`;
  }
}

function renderJobcardsTable(rows) {
  if (!rows.length) return `<div class="empty-state" style="padding:2rem"><p>No jobcards found.</p></div>`;

  const PREVIEW = 20;
  const html = rows.map((r, i) => {
    const hidden = i >= PREVIEW ? ' class="extra-row" style="display:none"' : '';
    return `<tr${hidden}>
      <td data-label="JC #"><strong>#${r.jc_no}</strong></td>
      <td data-label="Client">${r.client_name || r.address || '—'}</td>
      <td data-label="Contact">${r.contact_number || '—'}</td>
      <td data-label="Team"><span class="badge badge-navy">${r.team_name || '—'}</span></td>
      <td data-label="Status">${jcStatusBadge(r.live_status || r.jc_current_status)}</td>
      <td data-label="Date" style="color:var(--text-muted);font-size:0.8rem">${r.date_created || '—'}</td>
      <td data-label="Action" style="text-align:right">
        <button class="btn btn-primary btn-sm jc-view-btn" data-id="${r.record_id}">View</button>
      </td>
    </tr>`;
  }).join('');

  const showMore = rows.length > PREVIEW
    ? `<tr class="show-more-row"><td colspan="99" data-label="">
        <button class="show-more-btn" data-expanded="false" data-total="${rows.length}">Show all ${rows.length}</button>
       </td></tr>` : '';

  return `<div class="table-wrap"><table>
    <thead><tr>
      <th>JC #</th><th>Client / Area</th><th>Contact</th>
      <th>Team</th><th>Status</th><th>Date</th><th></th>
    </tr></thead>
    <tbody>${html}${showMore}</tbody>
  </table></div>`;
}

function jcStatusBadge(s) {
  const map = {
    // jc_current_status values
    PENDING: 'badge-pending',
    ACTIVE: 'badge-active',
    COMPLETE: 'badge-complete',
    // Timeline types
    DEPARTED: 'badge-orange',
    DEPARTURE: 'badge-orange',
    ARRIVED: 'badge-blue',
    DRILLING_START: 'badge-drilling',
    DRILLING_RESUME: 'badge-drilling',
    DRILLING_PAUSE: 'badge-orange',
    DRILLING_STOP: 'badge-active',
    RIEMING_START: 'badge-drilling',
    RIEMING_RESUMED: 'badge-drilling',
    RIEM_START: 'badge-drilling',
    RIEMING_PAUSED: 'badge-orange',
    RIEMING_STOP: 'badge-active',
    RIEM_STOP: 'badge-active',
    REIMING_STOP: 'badge-active',
    CASING_START: 'badge-drilling',
    CASING_RESUME: 'badge-drilling',
    CASING_PAUSE: 'badge-orange',
    CASING_STOP: 'badge-active',
    BLASTING_START: 'badge-drilling',
    BLASTING_RESUME: 'badge-drilling',
    BLASTING_PAUSE: 'badge-orange',
    BLASTING_STOP: 'badge-active',
    FINALISING: 'badge-orange',
  };
  const label = {
    PENDING: 'Pending',
    ACTIVE: 'Active',
    COMPLETE: 'Complete',
    DEPARTED: 'Departed',
    DEPARTURE: 'Departed',
    ARRIVED: 'On Site',
    DRILLING_START: 'Drilling',
    DRILLING_RESUME: 'Drilling',
    DRILLING_PAUSE: 'Drill Paused',
    DRILLING_STOP: 'Drill Stopped',
    RIEMING_START: 'Rieming',
    RIEMING_RESUMED: 'Rieming',
    RIEM_START: 'Rieming',
    RIEMING_PAUSED: 'Riem Paused',
    RIEMING_STOP: 'Riem Stopped',
    RIEM_STOP: 'Riem Stopped',
    REIMING_STOP: 'Riem Stopped',
    CASING_START: 'Casing',
    CASING_RESUME: 'Casing',
    CASING_PAUSE: 'Casing Paused',
    CASING_STOP: 'Casing Stopped',
    BLASTING_START: 'Blasting',
    BLASTING_RESUME: 'Blasting',
    BLASTING_PAUSE: 'Blast Paused',
    BLASTING_STOP: 'Blast Stopped',
    FINALISING: 'Finalising',
  };
  const upper = (s || '').toUpperCase();
  return `<span class="badge ${map[upper] || 'badge-navy'}">${label[upper] || s || '—'}</span>`;
}

// ─────────────────────────────────────────────────────────────────────────
// Shared helpers
// ─────────────────────────────────────────────────────────────────────────

function pageShell(title, body) {
  return `<div class="page-header">
    <div><h1>${title}</h1></div>
  </div>${body}`;
}

function plusIcon() {
  return `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
    style="width:16px;height:16px"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>`;
}

function debounce(fn, ms) {
  let t;
  return (...args) => { clearTimeout(t); t = setTimeout(() => fn(...args), ms); };
}