// ─── Savuki Drilling — Pumps Module (Install & Repair) ───────────────────
import { getTeams } from '../api.js';
import { showToast, openModal, closeModal, navigate } from '../app.js';
import { richSelect, jobcardItems, teamItems } from './rich-select.js';

const BASE = '/api/pumps';
const PUMP_TIMELINE_TYPES = ['DEPARTURE', 'ARRIVED', 'INSTALLING', 'START', 'PAUSE', 'RESUME', 'STOP', 'COMPLETE', 'OTHER'];
const TECH_UPLOADS = 'https://api.elegantwork.co.za/savuki_app/uploads/';
const ADMIN_UPLOADS = '/uploads/';

let _teams = [];
let _isAdmin = false;

// ── Fetch helpers ────────────────────────────────────────────────────────
function token() { return localStorage.getItem('sd_token') || ''; }

async function apiFetch(path, params = {}) {
  const url = `${BASE}/${path}?token=${token()}&${new URLSearchParams(params)}`;
  const res = await fetch(url);
  const json = await res.json();
  if (!json.success) throw new Error(json.message);
  return json.data;
}

async function apiPost(path, data) {
  const body = new URLSearchParams({ ...data, token: token() });
  const res = await fetch(`${BASE}/${path}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body,
  });
  const json = await res.json();
  if (!json.success) throw new Error(json.message);
  return json.data;
}

// ═════════════════════════════════════════════════════════════════════════
// PUMP INSTALLATIONS LIST
// ═════════════════════════════════════════════════════════════════════════
export async function initInstalls(role) {
  _isAdmin = ['admin', 'dev', 'test'].includes(role);
  const c = document.getElementById('view-content');
  c.innerHTML = `
  <div class="page-header">
    <div><h1>Pump Installations</h1></div>
    ${_isAdmin ? `<button class="btn btn-accent" id="btn-new-install">+ New Installation</button>` : ''}
  </div>
  <div class="toolbar" style="margin-bottom:1rem">
    <div class="toolbar-filters">
      <input class="form-control" id="f-client" placeholder="Client name" style="width:180px" />
      <input class="form-control" id="f-jc"     placeholder="Drilling JC #" style="width:130px" />
      <select class="form-control" id="f-status" style="width:150px">
        <option value="">All Statuses</option>
        <option value="0">In Progress</option>
        <option value="1">Complete</option>
      </select>
    </div>
  </div>
  <div class="card" id="install-wrap">
    <div class="card-body" style="padding:0"><div class="page-loader"><div class="spinner"></div></div></div>
  </div>`;

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

  const load = async () => {
    const wrap = document.getElementById('install-wrap');
    if (!wrap) return;
    wrap.innerHTML = `<div class="card-body" style="padding:0"><div class="page-loader"><div class="spinner"></div></div></div>`;
    try {
      const rows = await apiFetch('installs-list.php', {
        client: document.getElementById('f-client')?.value || '',
        jobcard: document.getElementById('f-jc')?.value || '',
        status: document.getElementById('f-status')?.value,
      });
      wrap.innerHTML = `<div class="card-body" style="padding:0">${renderInstallsTable(rows)}</div>`;
      wrap.querySelectorAll('.pi-view').forEach(b => b.addEventListener('click', () => navigate('pump-install-view', { id: +b.dataset.id })));
      bindShowMore(wrap);
    } catch (err) {
      wrap.innerHTML = `<div class="card-body"><div class="empty-state"><p>${err.message}</p></div></div>`;
    }
  };

  ['f-client', 'f-jc'].forEach(id => document.getElementById(id)?.addEventListener('input', debounce(load, 350)));
  document.getElementById('f-status')?.addEventListener('change', load);
  document.getElementById('btn-new-install')?.addEventListener('click', () => openInstallCreateModal(load));

  await load();
}

function renderInstallsTable(rows) {
  if (!rows.length) return `<div class="empty-state" style="padding:2rem"><p>No pump installations found.</p></div>`;
  const PREVIEW = 20;
  const html = rows.map((r, i) => {
    const hidden = i >= PREVIEW ? ' class="extra-row" style="display:none"' : '';
    const statusBadge = r.status == 1
      ? `<span class="badge badge-active">Complete</span>`
      : `<span class="badge badge-pending">In Progress</span>`;
    return `<tr${hidden}>
      <td data-label="ID"><strong>${r.jobcard_no}</strong></td>
      <td data-label="Client">${r.client_name || r.jc_client_name || '—'}</td>
      <td data-label="Area">${r.area || '—'}</td>
      <td data-label="Drilling JC">${r.drilling_invoice ? `<span class="badge badge-navy">#${r.drilling_invoice}</span>` : '—'}</td>
      <td data-label="Team">${r.team_name ? `<span class="badge badge-navy">${r.team_name}</span>` : '—'}</td>
      <td data-label="Status">${statusBadge}</td>
      <td data-label="Created" style="color:var(--text-muted);font-size:0.8rem">${(r.date_time_created || '').slice(0, 10)}</td>
      <td data-label=""><button class="btn btn-primary btn-sm pi-view" data-id="${r.record_id}">View</button></td>
    </tr>`;
  }).join('');
  const more = 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>ID</th><th>Client</th><th>Area</th><th>Drilling JC</th><th>Team</th><th>Status</th><th>Created</th><th></th></tr></thead>
    <tbody>${html}${more}</tbody>
  </table></div>`;
}

// ═════════════════════════════════════════════════════════════════════════
// PUMP INSTALLATION VIEW
// ═════════════════════════════════════════════════════════════════════════
export async function initInstallView(id, role) {
  _isAdmin = ['admin', 'dev', 'test'].includes(role);
  const c = document.getElementById('view-content');
  c.innerHTML = `<div class="page-loader"><div class="spinner"></div><span>Loading…</span></div>`;

  let data;
  try {
    [data, _teams] = await Promise.all([
      apiFetch('install-get.php', { id }),
      getTeams().catch(() => []),
    ]);
  } catch (err) { c.innerHTML = `<div class="empty-state"><p>${err.message}</p></div>`; return; }

  renderInstallView(data);
}

function renderInstallView(data) {
  const { install: pi, drilling_jc, timeline, notes, payments } = data;
  document.getElementById('page-title').textContent = pi.jobcard_no;

  const statusBadge = pi.status == 1
    ? `<span class="badge badge-active">Complete</span>`
    : `<span class="badge badge-pending">In Progress</span>`;

  document.getElementById('view-content').innerHTML = `
  <div class="page-header">
    <div>
      <h1>${pi.jobcard_no}</h1>
      <div class="sub">${pi.client_name || '—'} · ${statusBadge}</div>
    </div>
    <div style="display:flex;gap:0.5rem;flex-wrap:wrap">
      ${_isAdmin ? `<button class="btn btn-primary" id="btn-edit-install">Edit</button>` : ''}
      ${pi.status != 1 && _isAdmin ? `<button class="btn btn-ghost" id="btn-complete-install" style="color:var(--success);border-color:var(--success)">Mark Complete</button>` : ''}
      ${_isAdmin ? `<button class="btn btn-ghost btn-sm" id="btn-invoice-install">🧾 Invoice</button>` : ''}
      <button class="btn btn-ghost btn-sm" id="btn-view-pay-install">
        💳 Payments${payments.length ? ` (${payments.length})` : ''}
      </button>
      <button class="btn btn-ghost" id="btn-back">← Back</button>
    </div>
  </div>

  <!-- Linked drilling jobcard banner -->
  ${drilling_jc ? `
  <div style="background:var(--info-bg);border:1px solid var(--info);border-radius:var(--radius);
               padding:0.75rem 1rem;margin-bottom:1rem;display:flex;align-items:center;
               justify-content:space-between;gap:1rem;flex-wrap:wrap">
    <div style="font-size:0.875rem">
      <span style="font-weight:700;color:var(--info)">Linked Drilling Jobcard</span>
      <span style="margin-left:0.75rem">#${drilling_jc.jc_no} — ${drilling_jc.client_name || drilling_jc.address || '—'}</span>
      <span class="badge badge-${drilling_jc.jc_current_status === 'COMPLETE' ? 'complete' : 'drilling'}" style="margin-left:0.5rem">${drilling_jc.jc_current_status || '—'}</span>
    </div>
    <button class="btn btn-ghost btn-sm" id="btn-goto-jc" data-id="${drilling_jc.record_id}">View Jobcard →</button>
  </div>` : ''}

  <!-- Stat strip -->
  <div class="stat-grid" style="margin-bottom:1rem">
    ${iStat('Borehole', pi.borehole_meters, 'm')}
    ${iStat('Pump Depth', pi.pump_depth, 'm')}
    ${iStat('HDPE', pi.hdpe_meters, 'm')}
    ${iStat('Cable', pi.cable_meters, 'm')}
    ${iStat('Crack', pi.crack, 'm')}
    <div class="stat-card green" id="stat-pay-install" style="cursor:pointer">
      <div class="stat-label">Total Paid</div>
      <div class="stat-value" style="font-size:1.2rem" id="stat-pay-install-val">R ${(payments.reduce((s, p) => s + (+p.amount || 0), 0)).toLocaleString('en-ZA', { minimumFractionDigits: 2 })}</div>
      <div class="stat-sub" id="stat-pay-install-cnt">${payments.length} payment${payments.length !== 1 ? 's' : ''}</div>
    </div>
  </div>

  ${pumpTabNav(['Details', 'Timeline', 'Notes', 'Site Photos', 'Payments', 'Map'])}

  <div class="pump-tab-panel" data-panel="0">
    <div class="card"><div style="padding:0">${detailRows([
    ['Client', pi.client_name],
    ['Area', pi.area],
    ['Contact', pi.contact_number],
    ['Installed By', pi.installed_by],
    ['Attended By', pi.attended_by],
    ['Date Attended', pi.date_attended],
    ['Pack No', pi.pack_no],
    ['Pump No', pi.pump_no],
    ['GPS', pi.map_co_ordinates],
    ['Team', pi.team_name],
    ['Finished', pi.date_time_finished],
  ])}</div></div>
    ${renderPumpSlip(pi.pump_slip, 'pumps')}
  </div>

  <div class="pump-tab-panel" data-panel="1" style="display:none">
    <div class="card">
      <div id="tl-body" class="card-body" style="padding:0">${renderPumpTimeline(timeline)}</div>
    </div>
  </div>

  <div class="pump-tab-panel" data-panel="2" style="display:none">
    <div class="card"><div class="card-body">${renderNotes(notes.filter(n => n.reason !== 'INSTALL IMAGE'))}</div></div>
  </div>

  <div class="pump-tab-panel" data-panel="3" style="display:none">
    <div class="card"><div class="card-body">
      ${renderPumpSitePhotos(notes.filter(n => n.reason === 'INSTALL IMAGE')) || '<div class="empty-state"><p>No site photos.</p></div>'}
    </div></div>
  </div>

  <div class="pump-tab-panel" data-panel="4" style="display:none">
    <div class="card"><div class="card-header"><span class="card-title">💳 Payments</span></div>${renderPumpPayments(payments)}</div>
  </div>

  <div class="pump-tab-panel" data-panel="5" style="display:none">
    <div class="card"><div class="card-body">
      ${pi.map_co_ordinates
      ? `<div id="pump-map" data-coords="${esc(pi.map_co_ordinates)}" style="width:100%;height:400px;border-radius:8px;overflow:hidden"></div>`
      : '<div class="empty-state"><p>No GPS coordinates recorded.</p></div>'}
    </div></div>
  </div>`;

  // Wire buttons
  document.getElementById('btn-back')?.addEventListener('click', () => navigate('pump-install'));
  document.getElementById('btn-goto-jc')?.addEventListener('click', e => navigate('jobcard-view', { id: +e.currentTarget.dataset.id }));
  initPumpTabs();

  const openInstallPay = () => openPumpPaymentsModal(pi.jobcard_no, data, 'stat-pay-install');
  document.getElementById('btn-view-pay-install')?.addEventListener('click', openInstallPay);
  document.getElementById('stat-pay-install')?.addEventListener('click', openInstallPay);

  if (_isAdmin) {
    document.getElementById('btn-edit-install')?.addEventListener('click', () => openInstallEditModal(data, () => initInstallView(pi.record_id, _isAdmin ? 'admin' : 'driver')));
    document.getElementById('btn-invoice-install')?.addEventListener('click', () =>
      navigate('invoice-create', { pump_record_id: pi.record_id, pump_type: 'install' })
    );
    document.getElementById('btn-complete-install')?.addEventListener('click', async () => {
      if (!confirm('Mark this installation as complete?')) return;
      try {
        await apiPost('install-update.php', { id: pi.record_id, status: 1, ...pi });
        showToast('Marked complete.', 'success');
        initInstallView(pi.record_id, 'admin');
      } catch (err) { showToast(err.message, 'error'); }
    });
    bindTimelineActions(data.timeline, pi.jobcard_no, 'tl-body', 'install', pi.record_id);
  }
}

// ═════════════════════════════════════════════════════════════════════════
// PUMP REPAIRS LIST
// ═════════════════════════════════════════════════════════════════════════
export async function initRepairs(role) {
  _isAdmin = ['admin', 'dev', 'test'].includes(role);
  const c = document.getElementById('view-content');
  c.innerHTML = `
  <div class="page-header">
    <div><h1>Pump Repairs</h1></div>
    ${_isAdmin ? `<button class="btn btn-accent" id="btn-new-repair">+ New Repair</button>` : ''}
  </div>
  <div class="toolbar" style="margin-bottom:1rem">
    <div class="toolbar-filters">
      <input class="form-control" id="r-client" placeholder="Address / client" style="width:180px" />
      <select class="form-control" id="r-status" style="width:150px">
        <option value="">All Statuses</option>
        <option value="0">In Progress</option>
        <option value="1">Complete</option>
      </select>
    </div>
  </div>
  <div class="card" id="repair-wrap">
    <div class="card-body" style="padding:0"><div class="page-loader"><div class="spinner"></div></div></div>
  </div>`;

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

  const load = async () => {
    const wrap = document.getElementById('repair-wrap');
    if (!wrap) return;
    wrap.innerHTML = `<div class="card-body" style="padding:0"><div class="page-loader"><div class="spinner"></div></div></div>`;
    try {
      const rows = await apiFetch('repairs-list.php', {
        client: document.getElementById('r-client')?.value || '',
        status: document.getElementById('r-status')?.value,
      });
      wrap.innerHTML = `<div class="card-body" style="padding:0">${renderRepairsTable(rows)}</div>`;
      wrap.querySelectorAll('.pr-view').forEach(b => b.addEventListener('click', () => navigate('pump-repair-view', { id: +b.dataset.id })));
      bindShowMore(wrap);
    } catch (err) {
      wrap.innerHTML = `<div class="card-body"><div class="empty-state"><p>${err.message}</p></div></div>`;
    }
  };

  document.getElementById('r-client')?.addEventListener('input', debounce(load, 350));
  document.getElementById('r-status')?.addEventListener('change', load);
  document.getElementById('btn-new-repair')?.addEventListener('click', () => openRepairCreateModal(load));

  await load();
}

function renderRepairsTable(rows) {
  if (!rows.length) return `<div class="empty-state" style="padding:2rem"><p>No pump repairs found.</p></div>`;
  const PREVIEW = 20;
  const html = rows.map((r, i) => {
    const hidden = i >= PREVIEW ? ' class="extra-row" style="display:none"' : '';
    const statusBadge = r.status == 1
      ? `<span class="badge badge-active">Complete</span>`
      : `<span class="badge badge-pending">In Progress</span>`;
    const clientInfo = r.client_type === 'EXISTING'
      ? (r.install_client || r.install_area || '—')
      : (r.address || '—');
    return `<tr${hidden}>
      <td data-label="ID"><strong>${r.jobcard_no}</strong></td>
      <td data-label="Client">${clientInfo}</td>
      <td data-label="Type"><span class="badge ${r.client_type === 'NEW' ? 'badge-orange' : 'badge-navy'}">${r.client_type}</span></td>
      <td data-label="Team">${r.team_name ? `<span class="badge badge-navy">${r.team_name}</span>` : '—'}</td>
      <td data-label="Status">${statusBadge}</td>
      <td data-label="Created" style="color:var(--text-muted);font-size:0.8rem">${(r.date_time_created || '').slice(0, 10)}</td>
      <td data-label=""><button class="btn btn-primary btn-sm pr-view" data-id="${r.record_id}">View</button></td>
    </tr>`;
  }).join('');
  const more = 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>ID</th><th>Client</th><th>Type</th><th>Team</th><th>Status</th><th>Created</th><th></th></tr></thead>
    <tbody>${html}${more}</tbody>
  </table></div>`;
}

// ═════════════════════════════════════════════════════════════════════════
// PUMP REPAIR VIEW
// ═════════════════════════════════════════════════════════════════════════
export async function initRepairView(id, role) {
  _isAdmin = ['admin', 'dev', 'test'].includes(role);
  const c = document.getElementById('view-content');
  c.innerHTML = `<div class="page-loader"><div class="spinner"></div><span>Loading…</span></div>`;

  let data;
  try {
    [data, _teams] = await Promise.all([
      apiFetch('repair-get.php', { id }),
      getTeams().catch(() => []),
    ]);
  } catch (err) { c.innerHTML = `<div class="empty-state"><p>${err.message}</p></div>`; return; }

  renderRepairView(data);
}

function renderRepairView(data) {
  const { repair: pr, installation, drilling_jc, timeline, replaced, notes, payments } = data;
  document.getElementById('page-title').textContent = pr.jobcard_no;

  const statusBadge = pr.status == 1
    ? `<span class="badge badge-active">Complete</span>`
    : `<span class="badge badge-pending">In Progress</span>`;

  document.getElementById('view-content').innerHTML = `
  <div class="page-header">
    <div>
      <h1>${pr.jobcard_no}</h1>
      <div class="sub">${pr.address || installation?.client_name || '—'} · ${statusBadge}</div>
    </div>
    <div style="display:flex;gap:0.5rem;flex-wrap:wrap">
      ${_isAdmin ? `<button class="btn btn-primary" id="btn-edit-repair">Edit</button>` : ''}
      ${pr.status != 1 && _isAdmin ? `<button class="btn btn-ghost" id="btn-complete-repair" style="color:var(--success);border-color:var(--success)">Mark Complete</button>` : ''}
      ${_isAdmin ? `<button class="btn btn-ghost btn-sm" id="btn-invoice-repair">🧾 Invoice</button>` : ''}
      <button class="btn btn-ghost btn-sm" id="btn-view-pay-repair">
        💳 Payments${payments.length ? ` (${payments.length})` : ''}
      </button>
      <button class="btn btn-ghost" id="btn-back">← Back</button>
    </div>
  </div>

  <!-- Linked installation banner -->
  ${installation ? `
  <div style="background:var(--surface-2);border:1px solid var(--border);border-radius:var(--radius);
               padding:0.75rem 1rem;margin-bottom:0.75rem;display:flex;align-items:center;
               justify-content:space-between;gap:1rem;flex-wrap:wrap">
    <div style="font-size:0.875rem">
      <span style="font-weight:700;color:var(--primary)">Linked Installation</span>
      <span style="margin-left:0.75rem">${installation.jobcard_no} — ${installation.client_name || '—'}</span>
    </div>
    <button class="btn btn-ghost btn-sm" id="btn-goto-install" data-id="${installation.record_id}">View Install →</button>
  </div>` : ''}

  <!-- Linked drilling jobcard banner -->
  ${drilling_jc ? `
  <div style="background:var(--info-bg);border:1px solid var(--info);border-radius:var(--radius);
               padding:0.75rem 1rem;margin-bottom:1rem;display:flex;align-items:center;
               justify-content:space-between;gap:1rem;flex-wrap:wrap">
    <div style="font-size:0.875rem">
      <span style="font-weight:700;color:var(--info)">Linked Drilling Jobcard</span>
      <span style="margin-left:0.75rem">#${drilling_jc.jc_no} — ${drilling_jc.client_name || '—'}</span>
    </div>
    <button class="btn btn-ghost btn-sm" id="btn-goto-jc" data-id="${drilling_jc.record_id}">View Jobcard →</button>
  </div>` : ''}

  <div class="stat-grid" style="margin-bottom:1rem">
    <div class="stat-card green" id="stat-pay-repair" style="cursor:pointer">
      <div class="stat-label">Total Paid</div>
      <div class="stat-value" style="font-size:1.2rem" id="stat-pay-repair-val">R ${(payments.reduce((s, p) => s + (+p.amount || 0), 0)).toLocaleString('en-ZA', { minimumFractionDigits: 2 })}</div>
      <div class="stat-sub" id="stat-pay-repair-cnt">${payments.length} payment${payments.length !== 1 ? 's' : ''}</div>
    </div>
  </div>

  ${pumpTabNav(['Details', 'Problem/Solution', 'Timeline', 'Replaced Parts', 'Notes', 'Site Photos', 'Payments', 'Map'])}

  <div class="pump-tab-panel" data-panel="0">
    <div class="card"><div style="padding:0">${detailRows([
    ['Client Type', pr.client_type],
    ['Contact', pr.contact_number],
    ['Address', pr.address],
    ['Repaired By', pr.repaired_by],
    ['Team', pr.team_name],
    ['Date Started', pr.date_time_started],
    ['Date Finished', pr.date_time_finished],
    ['GPS', pr.map_co_ordinates],
  ])}</div></div>
    ${renderPumpSlip(pr.pump_slip_file, 'pumps')}
  </div>

  <div class="pump-tab-panel" data-panel="1" style="display:none">
    <div class="card"><div class="card-body">
      <div style="margin-bottom:1rem">
        <div class="form-label" style="margin-bottom:0.3rem;font-weight:600">Problem Description</div>
        <p style="font-size:.875rem">${esc(pr.problem_description) || '<span style="color:var(--text-muted)">—</span>'}</p>
      </div>
      <div>
        <div class="form-label" style="margin-bottom:0.3rem;font-weight:600">Solution</div>
        <p style="font-size:.875rem">${esc(pr.problem_solution) || '<span style="color:var(--text-muted)">—</span>'}</p>
      </div>
    </div></div>
  </div>

  <div class="pump-tab-panel" data-panel="2" style="display:none">
    <div class="card">
      <div id="tl-body" class="card-body" style="padding:0">${renderPumpTimeline(timeline)}</div>
    </div>
  </div>

  <div class="pump-tab-panel" data-panel="3" style="display:none">
    <div class="card">
      <div class="card-header">
        <span class="card-title">Replaced Items</span>
        <span class="badge badge-navy">${replaced.length}</span>
        ${_isAdmin ? `<button class="btn btn-ghost btn-sm" id="btn-add-replaced" style="margin-left:auto">+ Add Item</button>` : ''}
      </div>
      <div id="replaced-body" class="card-body" style="padding:0">${renderReplaced(replaced, _isAdmin)}</div>
    </div>
  </div>

  <div class="pump-tab-panel" data-panel="4" style="display:none">
    <div class="card"><div class="card-body">${renderNotes(notes.filter(n => n.reason !== 'INSTALL IMAGE'))}</div></div>
  </div>

  <div class="pump-tab-panel" data-panel="5" style="display:none">
    <div class="card"><div class="card-body">
      ${renderPumpSitePhotos(notes.filter(n => n.reason === 'INSTALL IMAGE')) || '<div class="empty-state"><p>No site photos.</p></div>'}
    </div></div>
  </div>

  <div class="pump-tab-panel" data-panel="6" style="display:none">
    <div class="card"><div class="card-header"><span class="card-title">💳 Payments</span></div>${renderPumpPayments(payments)}</div>
  </div>

  <div class="pump-tab-panel" data-panel="7" style="display:none">
    <div class="card"><div class="card-body">
      ${pr.map_co_ordinates
      ? `<div id="pump-map" data-coords="${esc(pr.map_co_ordinates)}" style="width:100%;height:400px;border-radius:8px;overflow:hidden"></div>`
      : '<div class="empty-state"><p>No GPS coordinates recorded.</p></div>'}
    </div></div>
  </div>`;

  // Wire buttons
  document.getElementById('btn-back')?.addEventListener('click', () => navigate('pump-repair'));
  document.getElementById('btn-goto-install')?.addEventListener('click', e => navigate('pump-install-view', { id: +e.currentTarget.dataset.id }));
  document.getElementById('btn-goto-jc')?.addEventListener('click', e => navigate('jobcard-view', { id: +e.currentTarget.dataset.id }));
  initPumpTabs();

  const openRepairPay = () => openPumpPaymentsModal(pr.jobcard_no, data, 'stat-pay-repair');
  document.getElementById('btn-view-pay-repair')?.addEventListener('click', openRepairPay);
  document.getElementById('stat-pay-repair')?.addEventListener('click', openRepairPay);

  if (_isAdmin) {
    document.getElementById('btn-edit-repair')?.addEventListener('click', () => openRepairEditModal(data, () => initRepairView(pr.record_id, 'admin')));
    document.getElementById('btn-invoice-repair')?.addEventListener('click', () =>
      navigate('invoice-create', { pump_record_id: pr.record_id, pump_type: 'repair' })
    );
    document.getElementById('btn-complete-repair')?.addEventListener('click', async () => {
      if (!confirm('Mark this repair as complete?')) return;
      try {
        await apiPost('repair-update.php', { id: pr.record_id, status: 1, ...pr });
        showToast('Marked complete.', 'success');
        initRepairView(pr.record_id, 'admin');
      } catch (err) { showToast(err.message, 'error'); }
    });
    document.getElementById('btn-add-replaced')?.addEventListener('click', () => openAddReplacedModal(pr.jobcard_no, data, () => initRepairView(pr.record_id, 'admin')));
    bindTimelineActions(data.timeline, pr.jobcard_no, 'tl-body', 'repair', pr.record_id);
    bindReplacedDelete(data.replaced, pr.record_id);
  }
}

// ═════════════════════════════════════════════════════════════════════════
// CREATE MODALS
// ═════════════════════════════════════════════════════════════════════════
async function openInstallCreateModal(reload) {
  openModal('New Pump Installation', `
    <div class="form-group">
      <label class="form-label">Team <span style="color:var(--danger)">*</span></label>
      <div id="ni-team-rs"></div>
    </div>
    <div class="form-group">
      <label class="form-label">Linked Drilling Jobcard</label>
      <div id="ni-jc-rs"></div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Client Name</label>
        <input class="form-control" id="ni-client" />
      </div>
      <div class="form-group">
        <label class="form-label">Area</label>
        <input class="form-control" id="ni-area" />
      </div>
    </div>
    <div class="form-group">
      <label class="form-label">Contact Number</label>
      <input class="form-control" id="ni-contact" type="tel" />
    </div>
    <div id="ni-err" class="login-error"></div>
  `, async () => {
    const errEl = document.getElementById('ni-err');
    errEl.classList.remove('visible');
    const teamId = niTeamRs?.getValue();
    const jcNo = niJcRs?.getValue();
    if (!teamId) { errEl.textContent = 'Team is required.'; errEl.classList.add('visible'); return; }
    try {
      const res = await apiPost('install-create.php', {
        drilling_team_id: teamId,
        drilling_invoice: jcNo || '',
        client_name: document.getElementById('ni-client').value,
        area: document.getElementById('ni-area').value,
        contact_number: document.getElementById('ni-contact').value,
      });
      closeModal();
      showToast(`${res.jobcard_no} created.`, 'success');
      reload();
    } catch (err) { errEl.textContent = err.message; errEl.classList.add('visible'); }
  }, { confirmLabel: 'Create Installation', confirmClass: 'btn-accent' });

  // Init rich selects after modal is in DOM
  let niTeamRs = null, niJcRs = null;

  niTeamRs = richSelect('ni-team-rs', {
    placeholder: 'Search teams…',
    items: teamItems(_teams),
  });
  // Default to the team named "Install Team"
  const _niInstallTeam = _teams.find(t => (t.name || '').toLowerCase() === 'install team');
  if (_niInstallTeam) niTeamRs.setValue(_niInstallTeam.record_id);

  // Load jobcards for the second dropdown
  try {
    const res = await fetch(`/api/jobcards/list.php?token=${token()}`);
    const json = await res.json();
    if (json.success) {
      niJcRs = richSelect('ni-jc-rs', {
        placeholder: 'Search jobcards… (optional)',
        items: jobcardItems(json.data),
        onSelect: (val, item) => {
          const jc = item?._raw;
          if (!jc) return;
          const set = (id, v) => { const el = document.getElementById(id); if (el) el.value = v || ''; };
          set('ni-client', jc.client_name || '');
          set('ni-area', jc.address || '');
          set('ni-contact', jc.contact_number || '');
        },
      });
    }
  } catch { }
}

async function openRepairCreateModal(reload) {
  openModal('New Pump Repair', `
    <div class="form-group">
      <label class="form-label">Client Type <span style="color:var(--danger)">*</span></label>
      <select class="form-control" id="nr-ctype">
        <option value="NEW">New Client (no prior installation)</option>
        <option value="EXISTING">Existing Client (has installation)</option>
      </select>
    </div>
    <div class="form-group" id="nr-install-wrap" style="display:none">
      <label class="form-label">Linked Installation <span style="color:var(--danger)">*</span></label>
      <div id="nr-install-rs"></div>
    </div>
    <div class="form-group">
      <label class="form-label">Team <span style="color:var(--danger)">*</span></label>
      <div id="nr-team-rs"></div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Contact Number</label>
        <input class="form-control" id="nr-contact" type="tel" />
      </div>
      <div class="form-group">
        <label class="form-label">Address</label>
        <input class="form-control" id="nr-address" />
      </div>
    </div>
    <div class="form-group">
      <label class="form-label">Problem Description</label>
      <textarea class="form-control" id="nr-prob" rows="3"></textarea>
    </div>
    <div id="nr-err" class="login-error"></div>
  `, async () => {
    const errEl = document.getElementById('nr-err');
    const ctype = document.getElementById('nr-ctype').value;
    errEl.classList.remove('visible');
    const teamId = nrTeamRs?.getValue();
    const instId = nrInstallRs?.getValue();
    if (!teamId) { errEl.textContent = 'Team is required.'; errEl.classList.add('visible'); return; }
    if (ctype === 'EXISTING' && !instId) { errEl.textContent = 'Please select the linked installation.'; errEl.classList.add('visible'); return; }
    try {
      const res = await apiPost('repair-create.php', {
        client_type: ctype,
        installation_id: instId || 0,
        drilling_team_id: teamId,
        contact_number: document.getElementById('nr-contact').value,
        address: document.getElementById('nr-address').value,
        problem_description: document.getElementById('nr-prob').value,
      });
      closeModal();
      showToast(`${res.jobcard_no} created.`, 'success');
      reload();
    } catch (err) { errEl.textContent = err.message; errEl.classList.add('visible'); }
  }, { confirmLabel: 'Create Repair', confirmClass: 'btn-accent' });

  let nrTeamRs = null, nrInstallRs = null;

  nrTeamRs = richSelect('nr-team-rs', {
    placeholder: 'Search teams…',
    items: teamItems(_teams),
  });
  // Default to the team named "Install Team"
  const _nrInstallTeam = _teams.find(t => (t.name || '').toLowerCase() === 'install team');
  if (_nrInstallTeam) nrTeamRs.setValue(_nrInstallTeam.record_id);

  // Load installs for existing client dropdown
  try {
    const rows = await apiFetch('installs-list.php', {});
    nrInstallRs = richSelect('nr-install-rs', {
      placeholder: 'Search installations…',
      items: rows.map(r => ({
        value: r.record_id,
        label: `${r.jobcard_no} — ${r.client_name || r.area || '—'}`,
        sub: [r.area, r.contact_number].filter(Boolean).join(' · '),
        badge: r.status == 1 ? 'Complete' : 'In Progress',
      })),
    });
  } catch { }

  document.getElementById('nr-ctype')?.addEventListener('change', e => {
    document.getElementById('nr-install-wrap').style.display = e.target.value === 'EXISTING' ? '' : 'none';
  });
}

// ═════════════════════════════════════════════════════════════════════════
// EDIT MODALS
// ═════════════════════════════════════════════════════════════════════════
function openInstallEditModal(data, reload) {
  const pi = data.install;
  let eiTeamRs = null;

  openModal(`Edit ${pi.jobcard_no}`, `
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Client Name</label>
        <input class="form-control" id="ei-client" value="${esc(pi.client_name)}" />
      </div>
      <div class="form-group">
        <label class="form-label">Area</label>
        <input class="form-control" id="ei-area" value="${esc(pi.area)}" />
      </div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Contact</label>
        <input class="form-control" id="ei-contact" value="${esc(pi.contact_number)}" />
      </div>
      <div class="form-group">
        <label class="form-label">Team</label>
        <div id="ei-team-rs"></div>
      </div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Installed By</label>
        <input class="form-control" id="ei-iby" value="${esc(pi.installed_by)}" />
      </div>
      <div class="form-group">
        <label class="form-label">Attended By</label>
        <input class="form-control" id="ei-aby" value="${esc(pi.attended_by)}" />
      </div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Pump Depth (m)</label>
        <input class="form-control" id="ei-depth" type="number" value="${pi.pump_depth || 0}" />
      </div>
      <div class="form-group">
        <label class="form-label">Borehole (m)</label>
        <input class="form-control" id="ei-borehole" type="number" value="${pi.borehole_meters || 0}" />
      </div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Cable (m)</label>
        <input class="form-control" id="ei-cable" type="number" value="${pi.cable_meters || 0}" />
      </div>
      <div class="form-group">
        <label class="form-label">HDPE (m)</label>
        <input class="form-control" id="ei-hdpe" type="number" value="${pi.hdpe_meters || 0}" />
      </div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Crack (m)</label>
        <input class="form-control" id="ei-crack" type="number" value="${pi.crack || 0}" />
      </div>
      <div class="form-group">
        <label class="form-label">Borehole (m)</label>
        <input class="form-control" id="ei-borehole" type="number" value="${pi.borehole_meters || 0}" />
      </div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Pack No</label>
        <input class="form-control" id="ei-pack" value="${esc(pi.pack_no)}" />
      </div>
      <div class="form-group">
        <label class="form-label">Pump No</label>
        <input class="form-control" id="ei-pumpno" value="${esc(pi.pump_no)}" />
      </div>
    </div>
    <div class="form-group">
      <label class="form-label">GPS Coordinates</label>
      <input class="form-control" id="ei-gps" value="${esc(pi.map_co_ordinates)}" />
    </div>
    <div class="form-group">
      <label class="form-label">Problem Description</label>
      <textarea class="form-control" id="ei-prob" rows="3">${esc(pi.problem_description)}</textarea>
    </div>
    <div class="form-group">
      <label class="form-label">Solution</label>
      <textarea class="form-control" id="ei-sol" rows="3">${esc(pi.problem_solution)}</textarea>
    </div>
    <div id="ei-err" class="login-error"></div>
  `, async () => {
    const errEl = document.getElementById('ei-err');
    errEl.classList.remove('visible');
    try {
      await apiPost('install-update.php', {
        id: pi.record_id,
        drilling_invoice: pi.drilling_invoice,
        drilling_team_id: eiTeamRs?.getValue() || pi.drilling_team_id,
        client_name: document.getElementById('ei-client').value,
        area: document.getElementById('ei-area').value,
        contact_number: document.getElementById('ei-contact').value,
        installed_by: document.getElementById('ei-iby').value,
        attended_by: document.getElementById('ei-aby').value,
        pump_depth: document.getElementById('ei-depth').value,
        borehole_meters: document.getElementById('ei-borehole').value,
        cable_meters: document.getElementById('ei-cable').value,
        hdpe_meters: document.getElementById('ei-hdpe').value,
        crack: document.getElementById('ei-crack').value,
        pack_no: document.getElementById('ei-pack').value,
        pump_no: document.getElementById('ei-pumpno').value,
        map_co_ordinates: document.getElementById('ei-gps').value,
        problem_description: document.getElementById('ei-prob').value,
        problem_solution: document.getElementById('ei-sol').value,
        status: pi.status,
      });
      closeModal();
      showToast('Installation updated.', 'success');
      reload();
    } catch (err) { errEl.textContent = err.message; errEl.classList.add('visible'); }
  }, { confirmLabel: 'Save', confirmClass: 'btn-primary' });

  // Init team rich select after modal is in DOM
  eiTeamRs = richSelect('ei-team-rs', {
    placeholder: 'Search teams…',
    items: teamItems(_teams),
  });
  if (pi.drilling_team_id) eiTeamRs.setValue(pi.drilling_team_id);
}

function openRepairEditModal(data, reload) {
  const pr = data.repair;
  let erTeamRs = null;

  openModal(`Edit ${pr.jobcard_no}`, `
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Contact</label>
        <input class="form-control" id="er-contact" value="${esc(pr.contact_number)}" />
      </div>
      <div class="form-group">
        <label class="form-label">Address</label>
        <input class="form-control" id="er-address" value="${esc(pr.address)}" />
      </div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Team</label>
        <div id="er-team-rs"></div>
      </div>
      <div class="form-group">
        <label class="form-label">Repaired By</label>
        <input class="form-control" id="er-rby" value="${esc(pr.repaired_by)}" />
      </div>
    </div>
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Date Started</label>
        <input class="form-control" id="er-started" type="datetime-local" value="${(pr.date_time_started || '').replace(' ', 'T')}" />
      </div>
      <div class="form-group">
        <label class="form-label">Date Finished</label>
        <input class="form-control" id="er-finished" type="datetime-local" value="${(pr.date_time_finished || '').replace(' ', 'T')}" />
      </div>
    </div>
    <div class="form-group">
      <label class="form-label">GPS Coordinates</label>
      <input class="form-control" id="er-gps" value="${esc(pr.map_co_ordinates)}" />
    </div>
    <div class="form-group">
      <label class="form-label">Problem Description</label>
      <textarea class="form-control" id="er-prob" rows="3">${esc(pr.problem_description)}</textarea>
    </div>
    <div class="form-group">
      <label class="form-label">Solution</label>
      <textarea class="form-control" id="er-sol" rows="3">${esc(pr.problem_solution)}</textarea>
    </div>
    <div id="er-err" class="login-error"></div>
  `, async () => {
    const errEl = document.getElementById('er-err');
    errEl.classList.remove('visible');
    try {
      await apiPost('repair-update.php', {
        id: pr.record_id,
        drilling_team_id: erTeamRs?.getValue() || pr.drilling_team_id,
        contact_number: document.getElementById('er-contact').value,
        address: document.getElementById('er-address').value,
        repaired_by: document.getElementById('er-rby').value,
        date_time_started: document.getElementById('er-started').value.replace('T', ' '),
        date_time_finished: document.getElementById('er-finished').value.replace('T', ' '),
        map_co_ordinates: document.getElementById('er-gps').value,
        problem_description: document.getElementById('er-prob').value,
        problem_solution: document.getElementById('er-sol').value,
        status: pr.status,
      });
      closeModal();
      showToast('Repair updated.', 'success');
      reload();
    } catch (err) { errEl.textContent = err.message; errEl.classList.add('visible'); }
  }, { confirmLabel: 'Save', confirmClass: 'btn-primary' });

  // Init team rich select after modal is in DOM
  erTeamRs = richSelect('er-team-rs', {
    placeholder: 'Search teams…',
    items: teamItems(_teams),
  });
  if (pr.drilling_team_id) erTeamRs.setValue(pr.drilling_team_id);
}

// ═════════════════════════════════════════════════════════════════════════
// PUMP TIMELINE MODAL
// ═════════════════════════════════════════════════════════════════════════
function openPumpTimelineModal(jobcard_no, entry, timelineArr, bodyId) {
  const isEdit = !!entry;
  const typeOpts = PUMP_TIMELINE_TYPES.map(t =>
    `<option value="${t}" ${entry?.type === t ? 'selected' : ''}>${t}</option>`
  ).join('');

  openModal(isEdit ? 'Edit Timeline Entry' : 'Add Timeline Entry', `
    <div class="form-group">
      <label class="form-label">Event Type <span style="color:var(--danger)">*</span></label>
      <select class="form-control" id="ptl-type">${typeOpts}</select>
    </div>
    <div class="form-group">
      <label class="form-label">Date & Time</label>
      <input class="form-control" id="ptl-dt" type="datetime-local"
             value="${new Date().toISOString().slice(0, 16)}" />
    </div>
    <div id="ptl-err" class="login-error"></div>
  `, async () => {
    const errEl = document.getElementById('ptl-err');
    errEl.classList.remove('visible');
    const type = document.getElementById('ptl-type').value;
    if (!type) { errEl.textContent = 'Type is required.'; errEl.classList.add('visible'); return; }
    try {
      const res = await apiPost('timeline-add.php', {
        jobcard_no,
        type,
        date_time: document.getElementById('ptl-dt').value,
      });
      timelineArr.push(res);
      closeModal();
      showToast('Timeline entry added.', 'success');
      const body = document.getElementById(bodyId);
      if (body) body.innerHTML = renderPumpTimeline(timelineArr);
      bindTimelineDeletes(timelineArr, jobcard_no, bodyId);
    } catch (err) { errEl.textContent = err.message; errEl.classList.add('visible'); }
  }, { confirmLabel: 'Add Entry', confirmClass: 'btn-primary' });
}

function bindTimelineActions(timeline, jobcard_no, bodyId, type, recordId) {
  bindTimelineDeletes(timeline, jobcard_no, bodyId);
}

function bindTimelineDeletes(timelineArr, jobcard_no, bodyId) {
  document.querySelectorAll('.ptl-del').forEach(btn => {
    btn.addEventListener('click', async () => {
      if (!confirm('Delete this entry?')) return;
      try {
        await apiPost('timeline-delete.php', { record_id: btn.dataset.id });
        const idx = timelineArr.findIndex(t => t.record_id == btn.dataset.id);
        if (idx > -1) timelineArr.splice(idx, 1);
        const body = document.getElementById(bodyId);
        if (body) body.innerHTML = renderPumpTimeline(timelineArr);
        bindTimelineDeletes(timelineArr, jobcard_no, bodyId);
        showToast('Deleted.', 'success');
      } catch (err) { showToast(err.message, 'error'); }
    });
  });
}

// ═════════════════════════════════════════════════════════════════════════
// REPLACED ITEMS
// ═════════════════════════════════════════════════════════════════════════
function openAddReplacedModal(jobcard_no, data, reload) {
  openModal('Add Replaced Item', `
    <div class="form-group">
      <label class="form-label">Item Name <span style="color:var(--danger)">*</span></label>
      <input class="form-control" id="ri-name" placeholder="e.g. Pump motor, Bearing, Shaft seal" />
    </div>
    <div id="ri-err" class="login-error"></div>
  `, async () => {
    const errEl = document.getElementById('ri-err');
    errEl.classList.remove('visible');
    const name = document.getElementById('ri-name').value.trim();
    if (!name) { errEl.textContent = 'Item name is required.'; errEl.classList.add('visible'); return; }
    try {
      await apiPost('replaced-add.php', { jobcard_no, replaced_item: name });
      closeModal();
      showToast('Item added.', 'success');
      reload();
    } catch (err) { errEl.textContent = err.message; errEl.classList.add('visible'); }
  }, { confirmLabel: 'Add Item', confirmClass: 'btn-primary' });
}

function bindReplacedDelete(replaced, repairId) {
  document.querySelectorAll('.ri-del').forEach(btn => {
    btn.addEventListener('click', async () => {
      if (!confirm('Remove this item?')) return;
      try {
        await apiPost('replaced-delete.php', { record_id: btn.dataset.id });
        showToast('Removed.', 'success');
        initRepairView(repairId, 'admin');
      } catch (err) { showToast(err.message, 'error'); }
    });
  });
}

// ═════════════════════════════════════════════════════════════════════════
// RENDER HELPERS
// ═════════════════════════════════════════════════════════════════════════
function renderPumpTimeline(timeline) {
  if (!timeline.length) return `<div class="empty-state" style="padding:2rem"><p>No timeline entries.</p></div>`;

  const typeColors = {
    DEPARTURE: 'badge-pending', ARRIVED: 'badge-active', INSTALLING: 'badge-drilling',
    START: 'badge-active', PAUSE: 'badge-pending', RESUME: 'badge-active',
    STOP: 'badge-complete', COMPLETE: 'badge-active', OTHER: 'badge-complete',
  };

  const rows = timeline.map(t => `<tr>
    <td data-label="Time" style="color:var(--text-muted);font-size:0.8rem">${(t.date_time || '').slice(0, 16)}</td>
    <td data-label="Event"><span class="badge ${typeColors[t.type] || 'badge-navy'}">${t.type}</span></td>
    <td data-label="By" style="color:var(--text-muted);font-size:0.8rem">${t.username || '—'}</td>
    ${_isAdmin ? `<td data-label=""><button class="btn btn-ghost btn-sm ptl-del" data-id="${t.record_id}" style="color:var(--danger)">Del</button></td>` : '<td></td>'}
  </tr>`).join('');

  return `<div class="table-wrap"><table>
    <thead><tr><th>Time</th><th>Event</th><th>By</th>${_isAdmin ? '<th></th>' : '<th></th>'}</tr></thead>
    <tbody>${rows}</tbody>
  </table></div>`;
}

function renderReplaced(items, isAdmin) {
  if (!items.length) return `<div class="empty-state" style="padding:1.5rem"><p>No replaced items recorded.</p></div>`;
  return `<div class="table-wrap"><table>
    <thead><tr><th>Item</th><th>Date Added</th>${isAdmin ? '<th></th>' : ''}</tr></thead>
    <tbody>
      ${items.map(r => `<tr>
        <td data-label="Item"><strong>${esc(r.replaced_item)}</strong></td>
        <td data-label="Date" style="color:var(--text-muted);font-size:0.8rem">${r.date_added || '—'}</td>
        ${isAdmin ? `<td data-label=""><button class="btn btn-ghost btn-sm ri-del" data-id="${r.record_id}" style="color:var(--danger)">Remove</button></td>` : ''}
      </tr>`).join('')}
    </tbody>
  </table></div>`;
}

function renderPumpSlip(filename, folder) {
  if (!filename) return '';
  const techSrc = `${TECH_UPLOADS}${folder}/${esc(filename)}`;
  const adminSrc = `${ADMIN_UPLOADS}${folder}/${esc(filename)}`;
  return `
  <div class="card">
    <div class="card-header"><span class="card-title">📄 Pump Slip</span></div>
    <div class="card-body">
      <img src="${techSrc}"
           onclick="window.open(this.src,'_blank')"
           onerror="this.src='${adminSrc}';this.onerror=function(){this.style.display='none'};"
           style="width:100%;max-height:280px;object-fit:contain;border-radius:8px;
                  border:1px solid var(--border-light);cursor:pointer;background:var(--surface-2)" />
    </div>
  </div>`;
}

function renderPumpSitePhotos(notes) {
  const withImages = (notes || []).filter(n => n.image);
  if (!withImages.length) return '';
  return `
    <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px">
      ${withImages.map(n => {
    const techSrc = `${TECH_UPLOADS}notes/${esc(n.image)}`;
    const adminSrc = `${ADMIN_UPLOADS}notes/${esc(n.image)}`;
    return `<div style="text-align:center">
          <img src="${techSrc}"
               onerror="this.src='${adminSrc}';this.onerror=function(){this.parentElement.style.display='none'};"
               style="width:100%;height:110px;object-fit:cover;border-radius:8px;
                      border:1px solid var(--border-light)" />
          ${n.note ? `<div style="font-size:.75rem;color:var(--text-muted);margin-top:2px">${esc(n.note)}</div>` : ''}
        </div>`;
  }).join('')}
    </div>`;
}

function renderPumpPayments(payments) {
  if (!payments?.length) return `<div class="empty-state"><p>No payments recorded yet.</p></div>`;
  const tot = payments.reduce((s, p) => s + (+p.amount || 0), 0);
  return `<div class="table-wrap">
    ${payments.map(p => {
    const techSrc = p.file ? `${TECH_UPLOADS}payments/${esc(p.file)}` : null;
    const adminSrc = p.file ? `${ADMIN_UPLOADS}payments/${esc(p.file)}` : null;
    return `<div style="padding:.75rem 1rem;border-bottom:1px solid var(--border-light)">
        <div style="display:flex;justify-content:space-between;align-items:center">
          <div>
            <span class="badge badge-navy">${p.payment_method || '—'}</span>
            <span style="margin-left:.5rem;font-size:.82rem;color:var(--text-muted)">${(p.date_time || '').slice(0, 10)}</span>
          </div>
          <strong>R ${(+p.amount || 0).toLocaleString('en-ZA', { minimumFractionDigits: 2 })}</strong>
        </div>
        ${adminSrc ? `
        <img src="${adminSrc}"
             onclick="window.open(this.src,'_blank')"
             onerror="this.src='${techSrc}';this.onerror=function(){this.style.display='none'};"
             style="width:100%;max-height:220px;object-fit:contain;border-radius:8px;
                    border:1px solid var(--border-light);cursor:pointer;margin-top:8px;
                    background:var(--surface-2);display:block" />` : ''}
      </div>`;
  }).join('')}
    <div style="padding:.75rem 1rem;font-weight:700;text-align:right;border-top:2px solid var(--border)">
      Total: <span style="color:var(--success)">R ${tot.toLocaleString('en-ZA', { minimumFractionDigits: 2 })}</span>
    </div>
  </div>`;
}

function renderNotes(notes) {
  if (!notes?.length) return `<div class="empty-state"><p>No notes.</p></div>`;
  return notes.map(n => `
    <div style="border-bottom:1px solid var(--border-light);padding:0.65rem 0">
      ${n.reason ? `<span class="badge badge-navy" style="font-size:.7rem;margin-bottom:.3rem">${esc(n.reason)}</span>` : ''}
      <div style="font-size:0.875rem">${n.note || ''}</div>
      ${n.image ? `
      <div style="margin-top:6px">
        <img src="${TECH_UPLOADS}notes/${esc(n.image)}"
             onclick="window.open(this.src,'_blank')"
             onerror="this.src='${ADMIN_UPLOADS}notes/${esc(n.image)}';this.onerror=function(){this.style.display='none'};"
             style="max-width:100%;max-height:200px;border-radius:8px;
                    border:1px solid var(--border-light);cursor:pointer;object-fit:cover" />
      </div>` : ''}
      <div style="font-size:0.72rem;color:var(--text-muted);margin-top:0.2rem">${n.reason || ''} · ${n.date_time || ''}</div>
    </div>`).join('');
}

// ── Pump payments popup ───────────────────────────────────────────────────
function openPumpPaymentsModal(jobcardNo, data, statCardId) {
  // data.payments is passed by reference via the module-level data object
  if (!data._payments) data._payments = data.payments || [];

  function modalBody() {
    const rows = data._payments;
    const tot = rows.reduce((s, p) => s + (+p.amount || 0), 0);
    return `
      ${_isAdmin ? `<div style="margin-bottom:.75rem">
        <button class="btn btn-primary btn-sm" id="btn-pump-pay-add">+ Add Payment</button>
      </div>` : ''}
      ${rows.length ? `<div class="table-wrap"><table>
        <thead><tr>
          <th>Method</th><th>Amount</th><th>By</th><th>Date</th><th>Proof</th>
          ${_isAdmin ? '<th></th>' : ''}
        </tr></thead>
        <tbody>
          ${rows.map(p => `<tr>
            <td><span class="badge badge-navy">${p.payment_method || '—'}</span></td>
            <td><strong>R ${(+p.amount || 0).toLocaleString('en-ZA', { minimumFractionDigits: 2 })}</strong></td>
            <td style="font-size:.78rem;color:var(--text-muted)">${p.username || '—'}</td>
            <td style="font-size:.78rem;color:var(--text-muted)">${(p.date_time || '').slice(0, 10)}</td>
            <td>${p.file
        ? `<img src="${ADMIN_UPLOADS}payments/${esc(p.file)}"
                       onclick="window.open(this.src,'_blank')"
                       onerror="this.src='${TECH_UPLOADS}payments/${esc(p.file)}';this.onerror=function(){this.style.display='none'};"
                       style="width:80px;height:56px;object-fit:cover;border-radius:6px;
                              border:1px solid var(--border-light);cursor:pointer" />`
        : '<span style="color:var(--text-muted);font-size:.75rem">—</span>'}</td>
            ${_isAdmin ? `<td><button class="btn btn-ghost btn-sm pump-pay-edit"
                data-payment="${encodeURIComponent(JSON.stringify(p))}"
                style="font-size:.72rem">Edit</button></td>` : ''}
          </tr>`).join('')}
        </tbody>
      </table>
      <div style="text-align:right;padding:.75rem 1rem;font-weight:700;border-top:2px solid var(--border)">
        Total Paid: <span style="color:var(--success)">R ${tot.toLocaleString('en-ZA', { minimumFractionDigits: 2 })}</span>
      </div></div>`
        : `<div class="empty-state" style="padding:2rem"><p>No payments recorded yet.</p></div>`}`;
  }

  function refreshStat() {
    const rows = data._payments;
    const tot = rows.reduce((s, p) => s + (+p.amount || 0), 0);
    const valEl = document.getElementById(`${statCardId}-val`);
    const cntEl = document.getElementById(`${statCardId}-cnt`);
    if (valEl) valEl.textContent = `R ${tot.toLocaleString('en-ZA', { minimumFractionDigits: 2 })}`;
    if (cntEl) cntEl.textContent = `${rows.length} payment${rows.length !== 1 ? 's' : ''}`;
    // Update button count
    const btnInstall = document.getElementById('btn-view-pay-install');
    const btnRepair = document.getElementById('btn-view-pay-repair');
    const target = btnInstall || btnRepair;
    if (target) target.textContent = `💳 Payments${rows.length ? ` (${rows.length})` : ''}`;
  }

  function refreshModal() {
    const body = document.getElementById('pump-pay-modal-body');
    if (body) {
      body.innerHTML = modalBody();
      bindPumpPayButtons();
    }
    refreshStat();
  }

  function bindPumpPayButtons() {
    document.getElementById('btn-pump-pay-add')?.addEventListener('click', () =>
      openPumpPaymentModal(jobcardNo, null, (p) => {
        data._payments.push(p);
        refreshModal();
      })
    );
    document.querySelectorAll('.pump-pay-edit').forEach(btn => {
      if (btn._b) return; btn._b = true;
      btn.addEventListener('click', () => {
        const p = JSON.parse(decodeURIComponent(btn.dataset.payment));
        openPumpPaymentModal(jobcardNo, p, (updated) => {
          const idx = data._payments.findIndex(x => x.record_id == updated.record_id);
          if (idx > -1) data._payments[idx] = updated;
          refreshModal();
        });
      });
    });
  }

  openModal('Payments', `<div id="pump-pay-modal-body">${modalBody()}</div>`,
    closeModal, { confirmLabel: 'Close', confirmClass: 'btn-ghost' }
  );
  setTimeout(() => {
    document.getElementById('modal-cancel-btn')?.remove();
    bindPumpPayButtons();
  }, 50);
}

function openPumpPaymentModal(jobcardNo, payment, onDone) {
  const isEdit = !!payment;
  const hasFile = isEdit && payment?.file;

  openModal(isEdit ? 'Edit Payment' : 'Add Payment', `
    <div class="form-row">
      <div class="form-group">
        <label class="form-label">Payment Method <span style="color:var(--danger)">*</span></label>
        <select class="form-control" id="ppay-method">
          <option value="">— Select —</option>
          <option value="CASH"   ${payment?.payment_method === 'CASH' ? 'selected' : ''}>Cash</option>
          <option value="EFT"    ${payment?.payment_method === 'EFT' ? 'selected' : ''}>EFT</option>
          <option value="CARD"   ${payment?.payment_method === 'CARD' ? 'selected' : ''}>Card</option>
          <option value="CHEQUE" ${payment?.payment_method === 'CHEQUE' ? 'selected' : ''}>Cheque</option>
        </select>
      </div>
      <div class="form-group">
        <label class="form-label">Amount (R) <span style="color:var(--danger)">*</span></label>
        <input class="form-control" id="ppay-amount" type="number" min="0.01" step="0.01"
               value="${payment?.amount || ''}" placeholder="0.00" />
      </div>
    </div>
    <div id="ppay-eft-wrap" style="display:${payment?.payment_method === 'EFT' ? '' : 'none'}" class="form-group">
      <label class="form-label">
        Proof of Payment (EFT) <span style="color:var(--danger)">*</span>
        ${hasFile ? `<span style="font-size:.75rem;color:var(--success);margin-left:.5rem">✓ File on record — upload new to replace</span>` : ''}
      </label>
      <input class="form-control" id="ppay-file" type="file" accept="image/*,.pdf" />
      ${hasFile ? `<div style="font-size:.75rem;color:var(--text-muted);margin-top:.25rem">Current: ${payment.file}</div>` : ''}
    </div>
    <div id="ppay-err" class="login-error"></div>
  `, async () => {
    const errEl = document.getElementById('ppay-err');
    errEl.classList.remove('visible');
    const method = document.getElementById('ppay-method')?.value;
    const amount = parseFloat(document.getElementById('ppay-amount')?.value || 0);
    const fileInput = document.getElementById('ppay-file');
    const hasNew = fileInput?.files?.length > 0;

    if (!method) { errEl.textContent = 'Payment method is required.'; errEl.classList.add('visible'); return; }
    if (amount <= 0) { errEl.textContent = 'Amount must be greater than 0.'; errEl.classList.add('visible'); return; }
    if (method === 'EFT' && !hasNew && !(isEdit && payment?.file)) {
      errEl.textContent = 'Proof of payment is required for EFT.'; errEl.classList.add('visible'); return;
    }
    try {
      const token = localStorage.getItem('sd_token') || '';
      const fd = new FormData();
      fd.append('token', token);
      fd.append('payment_method', method);
      fd.append('amount', amount);
      if (isEdit) fd.append('record_id', payment.record_id);
      else fd.append('jobcard_id', jobcardNo);
      if (hasNew) fd.append('file', fileInput.files[0]);
      const url = isEdit ? '/api/jobcards/payment-update.php' : '/api/jobcards/payment-add.php';
      const res = await fetch(url, { method: 'POST', body: fd });
      const json = await res.json();
      if (!json.success) throw new Error(json.message);
      closeModal();
      showToast(isEdit ? 'Payment updated.' : 'Payment added.', 'success');
      onDone(json.data);
    } catch (err) { errEl.textContent = err.message; errEl.classList.add('visible'); }
  }, { confirmLabel: isEdit ? 'Save Payment' : 'Add Payment', confirmClass: 'btn-primary' });

  setTimeout(() => {
    document.getElementById('ppay-method')?.addEventListener('change', e => {
      document.getElementById('ppay-eft-wrap').style.display = e.target.value === 'EFT' ? '' : 'none';
    });
  }, 50);
}

function renderPayments(payments) {
  return `<div class="table-wrap"><table>
    <thead><tr><th>Method</th><th>Amount</th><th>By</th><th>Date</th></tr></thead>
    <tbody>${payments.map(p => `<tr>
      <td data-label="Method">${p.payment_method || '—'}</td>
      <td data-label="Amount"><strong>R ${(+p.amount || 0).toLocaleString()}</strong></td>
      <td data-label="By" style="color:var(--text-muted);font-size:0.8rem">${p.username || '—'}</td>
      <td data-label="Date" style="color:var(--text-muted);font-size:0.8rem">${p.date_time || '—'}</td>
    </tr>`).join('')}</tbody>
  </table></div>`;
}

function pumpTabNav(labels) {
  return `<div style="display:flex;gap:0;border-bottom:2px solid var(--border);margin-bottom:1rem;overflow-x:auto;flex-wrap:nowrap">
    ${labels.map((t, i) => `
      <button class="pump-tab-btn${i === 0 ? ' ptab-active' : ''}" data-tab="${i}"
        style="padding:.55rem 1rem;border:none;background:none;white-space:nowrap;
               font-size:.82rem;font-weight:600;border-bottom:2px solid ${i === 0 ? 'var(--primary)' : 'transparent'};
               color:${i === 0 ? 'var(--primary)' : 'var(--text-muted)'};margin-bottom:-2px;cursor:pointer">
        ${t}
      </button>`).join('')}
  </div>`;
}

function initPumpTabs() {
  const btns = document.querySelectorAll('.pump-tab-btn');
  const panels = document.querySelectorAll('.pump-tab-panel');
  btns.forEach(btn => {
    btn.addEventListener('click', () => {
      const idx = +btn.dataset.tab;
      btns.forEach(b => {
        const on = +b.dataset.tab === idx;
        b.style.color = on ? 'var(--primary)' : 'var(--text-muted)';
        b.style.borderColor = on ? 'var(--primary)' : 'transparent';
      });
      panels.forEach(p => { p.style.display = +p.dataset.panel === idx ? '' : 'none'; });
      // Lazy-load map
      if (idx === 5 || idx === 7) initPumpMap();
    });
  });
}

function initPumpMap() {
  const el = document.getElementById('pump-map');
  if (!el || el.dataset.loaded) return;
  el.dataset.loaded = '1';
  const coords = el.dataset.coords || '';
  const [lat, lng] = coords.split(',').map(s => parseFloat(s.trim()));
  if (isNaN(lat) || isNaN(lng)) return;
  const iframe = document.createElement('iframe');
  iframe.style.cssText = 'width:100%;height:400px;border:none';
  iframe.src = `https://maps.google.com/maps?q=${lat},${lng}&z=15&output=embed`;
  el.appendChild(iframe);
}

function iStat(label, value, unit = '') {
  return `<div class="stat-card navy">
    <div class="stat-label">${label}</div>
    <div class="stat-value">${value ?? 0}<span style="font-size:1rem;font-weight:500">${unit}</span></div>
  </div>`;
}

function detailRows(pairs) {
  return `<table style="width:100%">${pairs.map(([label, val]) => `
    <tr>
      <td style="padding:.55rem 1rem;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;
                 color:var(--text-muted);white-space:nowrap;width:45%;border-bottom:1px solid var(--border-light)">${label}</td>
      <td style="padding:.55rem 1rem;font-size:.875rem;border-bottom:1px solid var(--border-light)">${val || '<span style="color:var(--text-light)">—</span>'}</td>
    </tr>`).join('')}</table>`;
}

function bindShowMore(wrap) {
  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';
    });
  });
}

function esc(v) { return (v || '').toString().replace(/"/g, '&quot;').replace(/</g, '&lt;'); }
function debounce(fn, ms) { let t; return (...a) => { clearTimeout(t); t = setTimeout(() => fn(...a), ms); }; }