// ============================================================
// BusManager — Invoice & Print utilities
// ============================================================

function fmtRp(n) { return "Rp " + Math.round(n).toLocaleString("id-ID"); }
function fmtDate(d) {
  const dt = typeof d === "string" ? new Date(d) : d;
  return dt.toLocaleDateString("id-ID", { day: "2-digit", month: "long", year: "numeric" });
}

// ---- Terbilang (Indonesian number to words) ----
function terbilang(n) {
  n = Math.floor(Math.abs(Number(n) || 0));
  if (n === 0) return "Nol";
  const ones = ["","Satu","Dua","Tiga","Empat","Lima","Enam","Tujuh","Delapan","Sembilan","Sepuluh","Sebelas"];
  const helper = (num) => {
    if (num < 12) return ones[num];
    if (num < 20) return helper(num - 10) + " Belas";
    if (num < 100) return helper(Math.floor(num/10)) + " Puluh" + (num%10 ? " " + helper(num%10) : "");
    if (num < 200) return "Seratus" + (num-100 ? " " + helper(num-100) : "");
    if (num < 1000) return helper(Math.floor(num/100)) + " Ratus" + (num%100 ? " " + helper(num%100) : "");
    if (num < 2000) return "Seribu" + (num-1000 ? " " + helper(num-1000) : "");
    if (num < 1000000) return helper(Math.floor(num/1000)) + " Ribu" + (num%1000 ? " " + helper(num%1000) : "");
    if (num < 1000000000) return helper(Math.floor(num/1000000)) + " Juta" + (num%1000000 ? " " + helper(num%1000000) : "");
    if (num < 1000000000000) return helper(Math.floor(num/1000000000)) + " Milyar" + (num%1000000000 ? " " + helper(num%1000000000) : "");
    return String(num);
  };
  return helper(n) + " Rupiah";
}
window.terbilang = terbilang;

// Generate complete self-contained invoice HTML for a rental
function buildInvoiceHTML(rental) {
  const s = window.SETTINGS;
  const cust = window.CUSTOMERS.find(c => c.id === rental.customerId);
  const bus = window.BUSES.find(b => b.id === rental.busId);
  const drivers = rental.driverIds.map(id => window.DRIVERS.find(d => d.id === id)?.nama).filter(Boolean);
  const sisa = (rental.harga || 0) - (rental.dp || 0);
  const isLunas = rental.status === "lunas" || rental.status === "selesai";
  const isBatal = rental.status === "batal";

  const statusLabel = window.STATUS_LABEL[rental.status] || rental.status;
  const statusColor = {
    lunas: "#1d7a52", selesai: "#777",
    dp: "#a37416", booking: "#3360b5", batal: "#a83a30"
  }[rental.status] || "#333";

  // Pricing breakdown rows
  const rows = [
    { label: `Sewa ${bus?.nama || "—"} (${bus?.plate || "—"})`, sub: `${rental.tujuan} · ${fmtDate(rental.start)}${rental.start !== rental.end ? " – " + fmtDate(rental.end) : ""}`, amount: rental.harga },
  ];

  return `<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8" />
<title>Invoice ${rental.kode}</title>
<style>
  * { box-sizing: border-box; }
  body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    color: #1c2438;
    margin: 0;
    padding: 32px 36px;
    background: white;
    font-size: 12.5px;
    line-height: 1.5;
  }
  .wrap { max-width: 720px; margin: 0 auto; }
  header {
    display: flex;
    gap: 24px;
    align-items: flex-start;
    border-bottom: 3px solid #1c2438;
    padding-bottom: 20px;
    margin-bottom: 24px;
  }
  .brand {
    display: flex; gap: 14px; align-items: center;
    flex: 1;
  }
  .brand .logo {
    width: 56px; height: 56px;
    border-radius: 12px;
    background: linear-gradient(140deg, #1b4a8f, #173d75);
    color: white;
    font-size: 28px; font-weight: 800;
    display: flex; align-items: center; justify-content: center;
    flex: none;
  }
  .brand .info h1 {
    margin: 0 0 2px;
    font-size: 16px;
    letter-spacing: -0.01em;
    color: #1c2438;
  }
  .brand .info .meta {
    color: #6a7388;
    font-size: 11px;
    line-height: 1.45;
    white-space: pre-line;
  }
  .invoice-head { text-align: right; }
  .invoice-head .label { color: #8c93a4; font-size: 10px; letter-spacing: .15em; text-transform: uppercase; font-weight: 700; }
  .invoice-head h2 {
    margin: 4px 0;
    font-size: 26px;
    color: #1c2438;
    letter-spacing: -0.02em;
  }
  .invoice-head .num {
    font-family: "JetBrains Mono", "Courier New", monospace;
    font-size: 13px;
    color: #4a5269;
    letter-spacing: .04em;
  }
  .invoice-head .date {
    color: #6a7388;
    font-size: 11px;
    margin-top: 6px;
  }

  .bill-to-row {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 18px;
    margin-bottom: 28px;
  }
  .box-label {
    font-size: 9.5px;
    color: #8c93a4;
    letter-spacing: .15em;
    text-transform: uppercase;
    font-weight: 700;
    margin-bottom: 6px;
  }
  .box-content {
    color: #1c2438;
  }
  .box-content .name { font-weight: 600; font-size: 13px; margin-bottom: 2px; }
  .box-content .meta { font-size: 11px; color: #6a7388; white-space: pre-line; line-height: 1.5; }

  table.items {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 16px;
  }
  table.items thead th {
    text-align: left;
    background: #f4f6fa;
    color: #6a7388;
    font-weight: 600;
    font-size: 10px;
    letter-spacing: .12em;
    text-transform: uppercase;
    padding: 10px 12px;
    border-bottom: 2px solid #1c2438;
  }
  table.items thead th.right { text-align: right; }
  table.items tbody td {
    padding: 14px 12px;
    border-bottom: 1px solid #e6e9ef;
    vertical-align: top;
  }
  table.items tbody td.right { text-align: right; font-family: "JetBrains Mono", "Courier New", monospace; }
  table.items tbody td .sub { color: #8c93a4; font-size: 11px; margin-top: 4px; }
  table.items tbody td.desc { font-weight: 600; }

  .totals {
    margin-left: auto;
    width: 320px;
    margin-top: 12px;
  }
  .totals .line {
    display: flex; justify-content: space-between;
    padding: 7px 0;
    font-size: 12.5px;
    color: #4a5269;
  }
  .totals .line.sub { font-size: 12px; color: #6a7388; }
  .totals .line.grand {
    border-top: 2px solid #1c2438;
    border-bottom: 2px solid #1c2438;
    padding: 14px 0;
    font-weight: 800;
    font-size: 16px;
    color: #1c2438;
    margin-top: 8px;
  }
  .totals .line .v { font-family: "JetBrains Mono", "Courier New", monospace; }
  .totals .line.sisa { color: #a83a30; font-weight: 700; padding-top: 14px; }
  .totals .line.lunas { color: #1d7a52; font-weight: 700; padding-top: 14px; }

  .stamp {
    position: absolute;
    top: 50%; right: 60px;
    transform: translateY(-50%) rotate(-12deg);
    border: 3px solid ${statusColor};
    color: ${statusColor};
    padding: 8px 26px;
    font-weight: 900;
    font-size: 32px;
    letter-spacing: .15em;
    border-radius: 8px;
    opacity: 0.18;
    pointer-events: none;
    text-transform: uppercase;
  }

  .trip-detail {
    background: #f9fafc;
    border: 1px solid #e6e9ef;
    border-radius: 8px;
    padding: 16px 18px;
    margin-bottom: 20px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px 24px;
  }
  .trip-detail .item .lbl { font-size: 10px; color: #8c93a4; letter-spacing: .12em; text-transform: uppercase; font-weight: 700; margin-bottom: 3px; }
  .trip-detail .item .val { font-size: 12.5px; color: #1c2438; font-weight: 500; }

  footer {
    margin-top: 36px;
    padding-top: 24px;
    border-top: 1px solid #e6e9ef;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px;
  }
  footer .note { font-size: 10.5px; color: #6a7388; line-height: 1.6; }
  footer .note strong { color: #1c2438; }
  footer .sign { text-align: right; }
  footer .sign .label { font-size: 10.5px; color: #6a7388; margin-bottom: 56px; }
  footer .sign .name { font-weight: 600; font-size: 12px; border-top: 1px solid #1c2438; padding-top: 6px; display: inline-block; min-width: 180px; }

  .actions {
    position: fixed;
    top: 16px; right: 16px;
    display: flex; gap: 8px;
    background: white;
    padding: 8px;
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(0,0,0,.1);
    z-index: 100;
  }
  .actions button {
    border: 1px solid #d6dae3;
    background: white;
    border-radius: 6px;
    padding: 8px 14px;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    color: #1c2438;
  }
  .actions button.primary {
    background: #1b4a8f;
    color: white;
    border-color: #1b4a8f;
  }
  .actions button:hover { filter: brightness(.95); }

  @media print {
    .actions { display: none !important; }
    body { padding: 0; }
    .wrap { max-width: none; }
    @page { margin: 18mm 14mm; size: A4; }
  }
</style>
</head>
<body>
  <div class="actions">
    <button onclick="window.close()">Tutup</button>
    <button class="primary" onclick="window.print()">🖨 Cetak / Save PDF</button>
  </div>

  <div class="wrap" style="position: relative;">
    <div class="stamp">${statusLabel}</div>

    <header>
      <div class="brand">
        <div class="logo">B</div>
        <div class="info">
          <h1>${s.nama}</h1>
          <div class="meta">${s.alamat}\nTelp: ${s.telp} · ${s.email}\nNPWP: ${s.npwp}</div>
        </div>
      </div>
      <div class="invoice-head">
        <div class="label">Invoice</div>
        <h2>${isLunas ? "KWITANSI" : "INVOICE"}</h2>
        <div class="num">${rental.kode}</div>
        <div class="date">Dicetak: ${fmtDate(new Date())}</div>
      </div>
    </header>

    <div class="bill-to-row">
      <div>
        <div class="box-label">Ditagihkan Kepada</div>
        <div class="box-content">
          <div class="name">${cust?.nama || "—"}</div>
          <div class="meta">${cust?.alamat || ""}\n${cust?.phone || ""}</div>
        </div>
      </div>
      <div>
        <div class="box-label">Tanggal Sewa</div>
        <div class="box-content">
          <div class="name">${fmtDate(rental.start)}</div>
          <div class="meta">${rental.start !== rental.end ? "s/d " + fmtDate(rental.end) : "(1 hari)"}</div>
        </div>
      </div>
      <div>
        <div class="box-label">Status Pembayaran</div>
        <div class="box-content">
          <div class="name" style="color: ${statusColor}">${statusLabel}</div>
          <div class="meta">${isLunas ? "Pembayaran lunas diterima" : isBatal ? "Transaksi dibatalkan" : sisa > 0 ? "Tersisa " + fmtRp(sisa) : "—"}</div>
        </div>
      </div>
    </div>

    <div class="trip-detail">
      <div class="item">
        <div class="lbl">Unit Bus</div>
        <div class="val">${bus?.nama || "—"} · ${bus?.plate || "—"} (${bus?.kapasitas || "—"} seat)</div>
      </div>
      <div class="item">
        <div class="lbl">Tujuan</div>
        <div class="val">${rental.tujuan || "—"}</div>
      </div>
      <div class="item">
        <div class="lbl">Lokasi Penjemputan</div>
        <div class="val">${rental.lokasi || "—"}</div>
      </div>
      <div class="item">
        <div class="lbl">Jam Penjemputan</div>
        <div class="val">${rental.jam || "—"} WIB</div>
      </div>
      <div class="item" style="grid-column: 1 / -1;">
        <div class="lbl">Sopir / Crew</div>
        <div class="val">${drivers.length ? drivers.join(", ") : "<em style='color:#a0a4b0'>belum ditugaskan</em>"}</div>
      </div>
      ${rental.catatan ? `
      <div class="item" style="grid-column: 1 / -1;">
        <div class="lbl">Catatan</div>
        <div class="val">${rental.catatan}</div>
      </div>` : ""}
    </div>

    <table class="items">
      <thead>
        <tr>
          <th style="width: 40px;">No</th>
          <th>Deskripsi</th>
          <th class="right" style="width: 160px;">Total</th>
        </tr>
      </thead>
      <tbody>
        ${rows.map((r, i) => `
          <tr>
            <td>${i+1}</td>
            <td class="desc">${r.label}<div class="sub">${r.sub}</div></td>
            <td class="right">${fmtRp(r.amount)}</td>
          </tr>
        `).join("")}
      </tbody>
    </table>

    <div class="totals">
      <div class="line"><span>Subtotal</span><span class="v">${fmtRp(rental.harga)}</span></div>
      <div class="line sub"><span>Pajak</span><span class="v">—</span></div>
      <div class="line grand"><span>TOTAL</span><span class="v">${fmtRp(rental.harga)}</span></div>
      <div class="line"><span>DP / Pembayaran diterima</span><span class="v">${fmtRp(rental.dp)}</span></div>
      <div class="line ${isLunas ? "lunas" : "sisa"}">
        <span>${isLunas ? "LUNAS" : "SISA PEMBAYARAN"}</span>
        <span class="v">${isLunas ? fmtRp(0) : fmtRp(Math.max(0, sisa))}</span>
      </div>
    </div>

    <footer>
      <div class="note">
        <strong>Cara pembayaran:</strong><br/>
        Transfer BCA <span style="font-family:'JetBrains Mono',monospace">012-3456-7890</span> a.n. ${s.nama}<br/><br/>
        Pelunasan paling lambat 1 hari sebelum keberangkatan. Kuitansi resmi dikirim setelah pembayaran lunas.
      </div>
      <div class="sign">
        <div class="label">Surabaya, ${fmtDate(new Date())}<br/>${s.nama}</div>
        <div class="name">( _________________________ )</div>
      </div>
    </footer>
  </div>
</body>
</html>`;
}

function printInvoice(rental) {
  const html = buildInvoiceHTML(rental);
  const w = window.open("", "_blank", "width=860,height=1080");
  if (!w) {
    alert("Pop-up diblokir. Mohon izinkan pop-up untuk situs ini.");
    return;
  }
  w.document.open();
  w.document.write(html);
  w.document.close();
  w.focus();
}

// ============================================================
// Kwitansi (Receipt) — classic Indonesian format
// ============================================================
function buildKwitansiHTML(rental, opts = {}) {
  const s = window.SETTINGS;
  const cust = window.CUSTOMERS.find(c => c.id === rental.customerId);
  const bus = window.BUSES.find(b => b.id === rental.busId);
  const isLunas = rental.status === "lunas" || rental.status === "selesai";

  // Determine amount based on mode
  const mode = opts.mode || (isLunas ? "lunas" : "dp"); // "lunas" | "dp" | "custom"
  let amount, untukLabel;
  if (mode === "lunas") {
    amount = rental.harga;
    untukLabel = "Pelunasan sewa bus";
  } else if (mode === "dp") {
    amount = rental.dp || 0;
    untukLabel = "Uang muka (DP) sewa bus";
  } else {
    amount = opts.amount || 0;
    untukLabel = opts.label || "Pembayaran sewa bus";
  }

  // Kwitansi number: KW-YYMM-RENTAL_ID
  const dt = new Date();
  const kwNo = `KW-${String(dt.getFullYear()%100).padStart(2,"0")}${String(dt.getMonth()+1).padStart(2,"0")}-${String(rental.id).padStart(3,"0")}${mode === "dp" ? "/DP" : "/L"}`;

  const dateRange = rental.start === rental.end
    ? fmtDate(rental.start)
    : `${fmtDate(rental.start)} – ${fmtDate(rental.end)}`;

  return `<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8" />
<title>Kwitansi ${kwNo}</title>
<style>
  * { box-sizing: border-box; }
  body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    color: #1c2438;
    margin: 0;
    padding: 28px;
    background: #f4f6fa;
    font-size: 13px;
    line-height: 1.5;
  }
  .kwitansi {
    background: white;
    max-width: 720px;
    margin: 0 auto;
    border: 2px solid #1c2438;
    border-radius: 4px;
    padding: 28px 36px 32px;
    position: relative;
    overflow: hidden;
  }
  .kwitansi::before {
    content: "";
    position: absolute;
    inset: 6px;
    border: 1px solid #1c2438;
    border-radius: 2px;
    pointer-events: none;
  }
  .head {
    text-align: center;
    margin-bottom: 18px;
    padding-bottom: 14px;
    border-bottom: 2px double #1c2438;
  }
  .head .brand {
    display: flex;
    gap: 14px;
    align-items: center;
    justify-content: center;
    margin-bottom: 10px;
  }
  .head .logo {
    width: 48px; height: 48px;
    border-radius: 10px;
    background: linear-gradient(140deg, #1b4a8f, #173d75);
    color: white;
    font-size: 24px; font-weight: 800;
    display: grid; place-items: center;
  }
  .head .brand-name { font-size: 16px; font-weight: 800; letter-spacing: -0.01em; }
  .head .brand-meta { font-size: 10.5px; color: #6a7388; line-height: 1.4; }
  .title {
    font-size: 32px;
    font-weight: 900;
    letter-spacing: .25em;
    text-align: center;
    color: #1c2438;
    margin: 8px 0 4px;
  }
  .subtitle {
    font-size: 11px;
    color: #6a7388;
    text-align: center;
    letter-spacing: .15em;
    text-transform: uppercase;
    font-weight: 600;
  }

  .no-tgl {
    display: flex;
    justify-content: space-between;
    margin: 16px 0 20px;
    font-size: 12px;
    color: #4a5269;
  }
  .no-tgl strong { color: #1c2438; }
  .no-tgl .mono { font-family: "JetBrains Mono", "Courier New", monospace; }

  .body-grid {
    display: grid;
    grid-template-columns: 160px 12px 1fr;
    row-gap: 14px;
    column-gap: 6px;
    align-items: start;
    font-size: 13px;
    margin-bottom: 22px;
  }
  .body-grid .label {
    color: #4a5269;
    font-weight: 500;
  }
  .body-grid .val {
    border-bottom: 1.5px dotted #8c93a4;
    padding-bottom: 4px;
    color: #1c2438;
    min-height: 22px;
    font-weight: 600;
  }
  .body-grid .val.box {
    border: 1.5px solid #1c2438;
    border-radius: 4px;
    padding: 8px 12px;
    background: #fffef5;
    font-style: italic;
    color: #5a4a1c;
  }
  .body-grid .small { font-size: 12px; color: #6a7388; font-weight: 400; font-style: italic; margin-top: 4px; }

  .foot {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 24px;
    align-items: end;
    margin-top: 18px;
  }
  .amount-box {
    border: 2.5px solid #1c2438;
    background: #fffef5;
    padding: 12px 16px;
    border-radius: 6px;
    box-shadow: 0 3px 0 #1c2438;
  }
  .amount-box .lbl { font-size: 10px; color: #8c93a4; letter-spacing: .12em; text-transform: uppercase; font-weight: 700; }
  .amount-box .val { font-family: "JetBrains Mono", "Courier New", monospace; font-size: 22px; font-weight: 800; margin-top: 4px; color: #1c2438; }

  .sign {
    text-align: center;
  }
  .sign .place { font-size: 12px; color: #4a5269; margin-bottom: 4px; }
  .sign .role { font-size: 12px; color: #4a5269; margin-bottom: 56px; font-weight: 600; }
  .sign .name-line {
    border-top: 1.5px solid #1c2438;
    padding-top: 6px;
    font-size: 12px;
    font-weight: 700;
    color: #1c2438;
    min-width: 240px;
    display: inline-block;
  }

  .lunas-stamp {
    position: absolute;
    top: 110px; right: 28px;
    transform: rotate(-14deg);
    border: 4px double #1d7a52;
    color: #1d7a52;
    padding: 6px 22px;
    font-weight: 900;
    font-size: 28px;
    letter-spacing: .12em;
    opacity: 0.22;
    pointer-events: none;
    border-radius: 6px;
    background: rgba(255,255,255,.5);
  }
  .dp-stamp {
    position: absolute;
    top: 110px; right: 28px;
    transform: rotate(-14deg);
    border: 4px double #a37416;
    color: #a37416;
    padding: 6px 28px;
    font-weight: 900;
    font-size: 26px;
    letter-spacing: .12em;
    opacity: 0.22;
    pointer-events: none;
    border-radius: 6px;
    background: rgba(255,255,255,.5);
  }

  .actions {
    position: fixed;
    top: 16px; right: 16px;
    display: flex; gap: 8px;
    background: white;
    padding: 8px;
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(0,0,0,.1);
    z-index: 100;
  }
  .actions button {
    border: 1px solid #d6dae3;
    background: white;
    border-radius: 6px;
    padding: 8px 14px;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    color: #1c2438;
  }
  .actions button.primary {
    background: #1b4a8f;
    color: white;
    border-color: #1b4a8f;
  }

  @media print {
    .actions { display: none !important; }
    body { padding: 0; background: white; }
    .kwitansi { box-shadow: none; max-width: none; }
    @page { size: A5 landscape; margin: 8mm; }
  }
</style>
</head>
<body>
  <div class="actions">
    <button onclick="window.close()">Tutup</button>
    <button class="primary" onclick="window.print()">🖨 Cetak / Save PDF</button>
  </div>

  <div class="kwitansi">
    ${mode === "lunas" ? '<div class="lunas-stamp">LUNAS</div>' : '<div class="dp-stamp">DP</div>'}

    <div class="head">
      <div class="brand">
        <div class="logo">B</div>
        <div style="text-align: left;">
          <div class="brand-name">${s.nama}</div>
          <div class="brand-meta">${s.alamat.replace(/\n/g, " · ")}<br/>${s.telp} · ${s.email}</div>
        </div>
      </div>
      <div class="title">KWITANSI</div>
      <div class="subtitle">Tanda Terima Pembayaran</div>
    </div>

    <div class="no-tgl">
      <div>No. Kwitansi: <strong class="mono">${kwNo}</strong></div>
      <div>Tanggal: <strong>${fmtDate(new Date())}</strong></div>
    </div>

    <div class="body-grid">
      <div class="label">Sudah terima dari</div>
      <div>:</div>
      <div class="val">${cust?.nama || "—"}</div>

      <div class="label">Uang sejumlah</div>
      <div>:</div>
      <div class="val box">${terbilang(amount)}</div>

      <div class="label">Untuk pembayaran</div>
      <div>:</div>
      <div class="val">
        ${untukLabel} <strong>${bus?.nama || ""}</strong> (${bus?.plate || "—"})
        <div class="small">Tujuan: <strong>${rental.tujuan || "—"}</strong> · Tanggal: ${dateRange} · Kode sewa: <span class="mono" style="font-weight:600">${rental.kode}</span></div>
      </div>
    </div>

    <div class="foot">
      <div class="amount-box">
        <div class="lbl">Jumlah Diterima</div>
        <div class="val">${fmtRp(amount)}</div>
      </div>
      <div class="sign">
        <div class="place">Surabaya, ${fmtDate(new Date())}</div>
        <div class="role">Yang Menerima<br/><span style="font-size:11px;color:#8c93a4;font-weight:500">${s.nama}</span></div>
        <div class="name-line">( _________________________ )</div>
      </div>
    </div>
  </div>
</body>
</html>`;
}

function printKwitansi(rental, opts = {}) {
  const html = buildKwitansiHTML(rental, opts);
  const w = window.open("", "_blank", "width=860,height=720");
  if (!w) {
    alert("Pop-up diblokir. Mohon izinkan pop-up untuk situs ini.");
    return;
  }
  w.document.open();
  w.document.write(html);
  w.document.close();
  w.focus();
}

window.buildKwitansiHTML = buildKwitansiHTML;
window.printKwitansi = printKwitansi;

// ============================================================
// Cetak Laporan Generic
// ============================================================
function printReport({ title, periode, headers, rows, totals, summary }) {
  const s = window.SETTINGS;
  const html = `<!doctype html>
<html lang="id"><head><meta charset="utf-8" /><title>${title}</title>
<style>
  body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; color: #1c2438; padding: 32px; font-size: 11.5px; line-height: 1.5; margin: 0; }
  .wrap { max-width: 900px; margin: 0 auto; }
  header { display: flex; gap: 16px; align-items: center; border-bottom: 3px solid #1c2438; padding-bottom: 16px; margin-bottom: 20px; }
  .logo { width: 48px; height: 48px; border-radius: 10px; background: linear-gradient(140deg, #1b4a8f, #173d75); color: white; font-size: 24px; font-weight: 800; display: grid; place-items: center; }
  header .info h1 { margin: 0; font-size: 14px; }
  header .info .meta { color: #6a7388; font-size: 10px; line-height: 1.4; white-space: pre-line; }
  .report-title { flex: 1; text-align: right; }
  .report-title h2 { font-size: 22px; margin: 0; letter-spacing: -.02em; }
  .report-title .periode { color: #6a7388; font-size: 11px; margin-top: 4px; }
  .summary { display: flex; gap: 12px; margin-bottom: 18px; }
  .sc { flex: 1; padding: 12px 14px; background: #f4f6fa; border-radius: 8px; }
  .sc .lbl { font-size: 9.5px; text-transform: uppercase; letter-spacing: .12em; color: #8c93a4; font-weight: 700; }
  .sc .val { font-size: 18px; font-weight: 700; font-family: "JetBrains Mono", monospace; margin-top: 4px; }
  table { width: 100%; border-collapse: collapse; margin-bottom: 12px; }
  thead th { background: #f4f6fa; padding: 10px; text-align: left; font-size: 9.5px; text-transform: uppercase; letter-spacing: .1em; color: #6a7388; border-bottom: 2px solid #1c2438; }
  thead th.right { text-align: right; }
  tbody td { padding: 10px; border-bottom: 1px solid #e6e9ef; vertical-align: top; }
  tbody td.right { text-align: right; font-family: "JetBrains Mono", monospace; }
  tfoot td { padding: 14px 10px; font-weight: 800; background: #f4f6fa; border-top: 2px solid #1c2438; }
  tfoot td.right { text-align: right; font-family: "JetBrains Mono", monospace; }
  footer { display: flex; justify-content: space-between; margin-top: 24px; color: #8c93a4; font-size: 10px; }
  .actions { position: fixed; top: 16px; right: 16px; display: flex; gap: 8px; background: white; padding: 8px; border-radius: 10px; box-shadow: 0 4px 16px rgba(0,0,0,.1); z-index: 100; }
  .actions button { border: 1px solid #d6dae3; background: white; border-radius: 6px; padding: 8px 14px; font-size: 12.5px; font-weight: 600; cursor: pointer; }
  .actions button.primary { background: #1b4a8f; color: white; border-color: #1b4a8f; }
  @media print { .actions { display: none !important; } body { padding: 0; } @page { size: A4; margin: 12mm; } }
</style>
</head><body>
<div class="actions">
  <button onclick="window.close()">Tutup</button>
  <button class="primary" onclick="window.print()">🖨 Cetak / Save PDF</button>
</div>
<div class="wrap">
  <header>
    <div class="logo">B</div>
    <div class="info"><h1>${s.nama}</h1><div class="meta">${s.alamat}\n${s.telp}</div></div>
    <div class="report-title"><h2>${title}</h2><div class="periode">Periode: ${periode}</div></div>
  </header>

  ${summary ? `<div class="summary">${summary.map(s => `<div class="sc"><div class="lbl">${s.lbl}</div><div class="val">${s.val}</div></div>`).join("")}</div>` : ""}

  <table>
    <thead><tr>${headers.map(h => `<th class="${h.align === "right" ? "right" : ""}" style="${h.width ? "width:" + h.width : ""}">${h.label}</th>`).join("")}</tr></thead>
    <tbody>
      ${rows.map(r => `<tr>${r.map((c, i) => `<td class="${headers[i].align === "right" ? "right" : ""}">${c}</td>`).join("")}</tr>`).join("")}
    </tbody>
    ${totals ? `<tfoot><tr>${totals.map((c, i) => `<td class="${headers[i]?.align === "right" ? "right" : ""}" ${c?.colspan ? `colspan="${c.colspan}"` : ""}>${c?.value !== undefined ? c.value : c}</td>`).join("")}</tr></tfoot>` : ""}
  </table>

  <footer>
    <div>Dicetak: ${fmtDate(new Date())} · ${new Date().toLocaleTimeString("id-ID", {hour:"2-digit", minute:"2-digit"})}</div>
    <div>BusManager · ${s.nama}</div>
  </footer>
</div>
</body></html>`;

  const w = window.open("", "_blank", "width=1000,height=1200");
  if (!w) { alert("Pop-up diblokir."); return; }
  w.document.open();
  w.document.write(html);
  w.document.close();
  w.focus();
}

window.printInvoice = printInvoice;
window.printReport = printReport;
window.buildInvoiceHTML = buildInvoiceHTML;
