<?php
$rootDir   = str_replace('\\', '/', dirname(__DIR__));
$uploadUrl = 'uploads/bukti_bayar/';
$uploadAbs = $rootDir . '/uploads/bukti_bayar/';

function ensureKolomBukti(PDO $pdo): void {
    try {
        if (!$pdo->query("SHOW COLUMNS FROM pembayaran LIKE 'bukti_bayar'")->fetch())
            $pdo->exec("ALTER TABLE pembayaran ADD COLUMN bukti_bayar VARCHAR(255) NULL AFTER keterangan");
    } catch(Exception $e) {}
    try {
        if (!$pdo->query("SHOW COLUMNS FROM pembayaran LIKE 'tanggal_bayar'")->fetch())
            $pdo->exec("ALTER TABLE pembayaran ADD COLUMN tanggal_bayar DATETIME NULL AFTER bukti_bayar");
    } catch(Exception $e) {}
}

function simpanBuktiBayar(string $absDir): ?string {
    if (!isset($_FILES['bukti_bayar']) || $_FILES['bukti_bayar']['error'] !== UPLOAD_ERR_OK) return null;
    if (empty($_FILES['bukti_bayar']['name'])) return null;
    $ext     = strtolower(pathinfo($_FILES['bukti_bayar']['name'], PATHINFO_EXTENSION));
    $allowed = ['jpg','jpeg','png','webp','pdf'];
    if (!in_array($ext, $allowed) || $_FILES['bukti_bayar']['size'] > 5*1024*1024) return null;
    if (!is_dir($absDir)) mkdir($absDir, 0755, true);
    $namaFile = 'bukti_'.time().'_'.rand(1000,9999).'.'.$ext;
    return move_uploaded_file($_FILES['bukti_bayar']['tmp_name'], $absDir.$namaFile) ? $namaFile : null;
}

function hapusFileBukti(string $absDir, ?string $nama): void {
    if ($nama && file_exists($absDir.$nama)) @unlink($absDir.$nama);
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    ensureKolomBukti($pdo);
    $act = $_POST['action'] ?? 'bayar';

    if ($act === 'hapus_bukti') {
        $pid = (int)($_POST['pembayaran_id'] ?? 0);
        $row = $pdo->prepare("SELECT bukti_bayar FROM pembayaran WHERE id=?");
        $row->execute([$pid]); $r = $row->fetch();
        if ($r) {
            hapusFileBukti($uploadAbs, $r['bukti_bayar']);
            $pdo->prepare("UPDATE pembayaran SET bukti_bayar=NULL WHERE id=?")->execute([$pid]);
            $_SESSION['toast'] = 'Bukti pembayaran berhasil dihapus';
        }
        redirect('index.php?page=pembayaran&siswa_id='.($_POST['_siswa_id']??0)
            .'&bulan='.($_POST['_bulan']??date('n')).'&tahun='.($_POST['_tahun']??date('Y')));
    }

    if ($act === 'edit_bukti') {
        $pid = (int)($_POST['pembayaran_id'] ?? 0);
        $row = $pdo->prepare("SELECT bukti_bayar FROM pembayaran WHERE id=?");
        $row->execute([$pid]); $r = $row->fetch();
        $buktiLama = $r['bukti_bayar'] ?? null;
        $buktiCopy = simpanBuktiBayar($uploadAbs);
        if ($buktiCopy) {
            hapusFileBukti($uploadAbs, $buktiLama);
            $pdo->prepare("UPDATE pembayaran SET bukti_bayar=? WHERE id=?")->execute([$buktiCopy, $pid]);
            $_SESSION['toast'] = 'Bukti pembayaran berhasil diperbarui';
        } else {
            $_SESSION['toast'] = 'Gagal mengganti bukti — pastikan file valid (JPG/PNG/WEBP/PDF, maks 5MB)';
        }
        redirect('index.php?page=pembayaran&siswa_id='.($_POST['_siswa_id']??0)
            .'&bulan='.($_POST['_bulan']??date('n')).'&tahun='.($_POST['_tahun']??date('Y')));
    }

    $tagihanId = (int)($_POST['tagihan_id'] ?? 0);
    $jumlah    = (int)($_POST['jumlah_bayar'] ?? 0);
    $metode    = $_POST['metode_bayar'] ?? 'tunai';
    $noRek     = $_POST['no_rekening']  ?? '';
    $ket       = $_POST['keterangan']   ?? '';
    $tglBayar  = !empty($_POST['tanggal_bayar']) ? $_POST['tanggal_bayar'] : date('Y-m-d H:i:s');

    $tagihan = $pdo->prepare("SELECT * FROM tagihan_spp WHERE id=?");
    $tagihan->execute([$tagihanId]); $t = $tagihan->fetch();

    if ($t && $jumlah > 0) {
        $bukti = simpanBuktiBayar($uploadAbs);
        $pdo->prepare(
            "INSERT INTO pembayaran (tagihan_id, siswa_id, admin_id, jumlah_bayar, metode_bayar,
              no_rekening, keterangan, bukti_bayar, tanggal_bayar)
             VALUES (?,?,?,?,?,?,?,?,?)"
        )->execute([
            $tagihanId, $t['siswa_id'], $_SESSION['admin_id'],
            $jumlah, $metode, $noRek, $ket, $bukti, $tglBayar
        ]);
        $stmt2 = $pdo->prepare("SELECT COALESCE(SUM(jumlah_bayar),0) FROM pembayaran WHERE tagihan_id=?");
        $stmt2->execute([$tagihanId]);
        $totalBayar = (int)$stmt2->fetchColumn();
        $newStatus  = $totalBayar >= $t['nominal'] ? 'lunas' : 'cicilan';
        $pdo->prepare("UPDATE tagihan_spp SET status=? WHERE id=?")->execute([$newStatus, $tagihanId]);
        $_SESSION['toast'] = 'Pembayaran berhasil diproses!'.($bukti ? ' Bukti tersimpan.' : '');
    }
    redirect('index.php?page=pembayaran&siswa_id='.($_POST['_siswa_id']??$t['siswa_id']??0)
        .'&bulan='.($_POST['_bulan']??date('n')).'&tahun='.($_POST['_tahun']??date('Y')));
}

require_once 'layout/header.php';
ensureKolomBukti($pdo);

$stAllTagihan = $pdo->query(
    "SELECT t.id, t.bulan, t.tahun, t.nominal, t.status,
            s.nama, s.nis, s.kelas, s.jurusan, s.id as siswa_id, s.foto as foto_siswa,
            COALESCE(SUM(p.jumlah_bayar),0) as total_dibayar,
            MAX(COALESCE(p.tanggal_bayar, p.created_at)) as tgl_terakhir,
            (SELECT metode_bayar FROM pembayaran WHERE tagihan_id=t.id ORDER BY id DESC LIMIT 1) as metode_terakhir
     FROM tagihan_spp t
     JOIN siswa s ON t.siswa_id = s.id
     LEFT JOIN pembayaran p ON p.tagihan_id = t.id
     GROUP BY t.id
     ORDER BY tgl_terakhir DESC, s.nama ASC"
);
$allTagihan     = $stAllTagihan->fetchAll();
$fotoSiswaUrl   = 'uploads/foto_siswa/';
$fotoSiswaAbs   = $rootDir . '/uploads/foto_siswa/';
$allTagihanJson = json_encode(array_map(function($r) use ($fotoSiswaUrl, $fotoSiswaAbs) {
    $f = $r['foto_siswa'] ?? '';
    return [
        'id'      => (int)$r['id'],
        'siswaId' => (int)$r['siswa_id'],
        'nama'    => $r['nama'],
        'nis'     => $r['nis'],
        'kelas'   => $r['kelas'],
        'jurusan' => $r['jurusan'],
        'bulan'   => (int)$r['bulan'],
        'tahun'   => (int)$r['tahun'],
        'nominal' => (int)$r['nominal'],
        'dibayar' => (int)$r['total_dibayar'],
        'status'  => $r['status'],
        'metode'  => $r['metode_terakhir'] ?? '',
        'tgl'     => $r['tgl_terakhir'] ?? '',
        'foto'    => ($f && file_exists($fotoSiswaAbs.$f)) ? $fotoSiswaUrl.$f : '',
    ];
}, $allTagihan));

$siswas  = $pdo->query("SELECT * FROM siswa WHERE status='aktif' ORDER BY nama")->fetchAll();
$toast   = $_SESSION['toast'] ?? ''; unset($_SESSION['toast']);
$siswaId = (int)($_GET['siswa_id'] ?? 0);
$bulan   = (int)($_GET['bulan']    ?? date('n'));
$tahun   = (int)($_GET['tahun']    ?? date('Y'));
$defaultTab = $siswaId ? 'cari' : 'all';

$tagihanList = [];
if ($siswaId) {
    $st = $pdo->prepare(
        "SELECT t.*, s.nama, s.nis, s.kelas, s.jurusan, s.foto as foto_siswa
         FROM tagihan_spp t JOIN siswa s ON t.siswa_id=s.id
         WHERE t.siswa_id=? AND t.bulan=? AND t.tahun=?"
    );
    $st->execute([$siswaId, $bulan, $tahun]);
    $tagihanList = $st->fetchAll();
}

$kelasList     = $pdo->query("SELECT DISTINCT kelas   FROM siswa WHERE status='aktif' ORDER BY kelas")->fetchAll(PDO::FETCH_COLUMN);
$jurusanList   = $pdo->query("SELECT DISTINCT jurusan FROM siswa WHERE status='aktif' ORDER BY jurusan")->fetchAll(PDO::FETCH_COLUMN);
$filterKelas   = $_GET['filter_kelas']   ?? '';
$filterJurusan = $_GET['filter_jurusan'] ?? '';
$filterCari    = $_GET['cari_siswa']     ?? '';
$siswasJson    = json_encode(array_map(function($s) use ($fotoSiswaUrl, $fotoSiswaAbs) {
    $f = $s['foto'] ?? '';
    return [
        'id'     => (int)$s['id'],
        'nama'   => $s['nama'],
        'nis'    => $s['nis'],
        'kelas'  => $s['kelas'],
        'jurusan'=> $s['jurusan'],
        'foto'   => ($f && file_exists($fotoSiswaAbs.$f)) ? $fotoSiswaUrl.$f : '',
    ];
}, $siswas));
?>
<?php if($toast): ?><script>window.onload=()=>showToast('<?= addslashes($toast) ?>')</script><?php endif ?>

<style>
/* ═══════════════════════════════════════════
   STAT CARDS — terlihat jelas di semua ukuran
═══════════════════════════════════════════ */
.pay-stats {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  margin-bottom: 20px;
}
@media (max-width: 1100px) { .pay-stats { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px)  { .pay-stats { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 360px)  { .pay-stats { grid-template-columns: 1fr; } }

.pay-stat {
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: 16px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: relative;
  overflow: hidden;
  transition: transform .18s, box-shadow .18s;
  min-width: 0;
}
.pay-stat:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(0,0,0,.08); }
.pay-stat-icon {
  width: 40px; height: 40px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; flex-shrink: 0; margin-bottom: 2px;
}
.pay-stat-val {
  font-size: 22px; font-weight: 800; line-height: 1;
  font-family: 'DM Mono', monospace;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pay-stat-label { font-size: 11.5px; color: var(--text3); font-weight: 500; }
.pay-stat-sub   { font-size: 11px;   color: var(--text3); }
.pay-stat-bg {
  position: absolute; right: -10px; bottom: -14px;
  font-size: 64px; line-height: 1; opacity: .07;
  pointer-events: none; user-select: none;
}
/* last stat (Terkumpul) spans full width on smaller grids */
@media (max-width: 1100px) and (min-width: 641px) {
  .pay-stat:last-child { grid-column: span 1; }
}

/* ═══════════════════════════════════════════
   MAIN TABS
═══════════════════════════════════════════ */
.main-tab-bar {
  display: flex; gap: 0;
  border: 1.5px solid var(--border);
  border-radius: 12px; overflow: hidden;
  width: fit-content; margin-bottom: 20px;
  flex-wrap: wrap;
}
.main-tab {
  padding: 9px 20px; font-size: 13px; font-weight: 600;
  font-family: inherit; cursor: pointer;
  border: none; border-right: 1.5px solid var(--border);
  background: var(--surface); color: var(--text2);
  transition: background .18s, color .18s;
  display: flex; align-items: center; gap: 6px;
  white-space: nowrap;
}
.main-tab:last-child { border-right: none; }
.main-tab.active { background: var(--candy-purple, #7C3AED); color: #fff; }
.main-tab:hover:not(.active) { background: var(--surface2); color: var(--text); }

/* ═══════════════════════════════════════════
   FILTER BAR — responsive, tidak terpotong
═══════════════════════════════════════════ */
.dash-filter-wrap {
  display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px;
}
.dash-filter-row1 {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}
.dash-filter-row2 {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}
.status-tab-bar {
  display: flex; gap: 0; border: 1.5px solid var(--border);
  border-radius: 9px; overflow: hidden; flex-shrink: 0;
}
.status-tab {
  padding: 7px 14px; font-size: 12.5px; font-weight: 600;
  cursor: pointer; border: none;
  border-right: 1.5px solid var(--border);
  background: transparent; color: var(--text2);
  font-family: inherit; transition: background .15s, color .15s;
  white-space: nowrap;
}
.status-tab:last-child { border-right: none; }
.status-tab.active { background: var(--candy-purple, #7C3AED); color: #fff; }
.status-tab:hover:not(.active) { background: var(--surface2); }

.dash-search-input {
  flex: 1; min-width: 160px; max-width: 320px;
  height: 38px; padding: 0 12px; font-size: 13px;
  border: 1.5px solid var(--border); border-radius: 9px;
  background: var(--surface); color: var(--text);
  font-family: inherit; transition: border-color .18s;
}
.dash-search-input:focus { outline: none; border-color: var(--candy-purple, #7C3AED); }

.dash-select {
  height: 38px; padding: 0 10px; font-size: 12.5px;
  border: 1.5px solid var(--border); border-radius: 9px;
  background: var(--surface); color: var(--text);
  font-family: inherit; cursor: pointer; flex-shrink: 0;
  min-width: 0;
}
.dash-select:focus { outline: none; border-color: var(--candy-purple, #7C3AED); }

/* view toggle */
.view-toggle {
  display: flex; gap: 3px; background: var(--surface2);
  border-radius: 10px; padding: 3px; flex-shrink: 0; margin-left: auto;
}
.view-toggle button {
  display: flex; align-items: center; gap: 5px;
  padding: 5px 11px; border: none; border-radius: 8px;
  background: transparent; color: var(--text3);
  font-size: 12px; font-weight: 500; cursor: pointer;
  transition: all .18s; white-space: nowrap; font-family: inherit;
}
.view-toggle button.active {
  background: var(--surface); color: var(--candy-purple, #7C3AED);
  box-shadow: 0 1px 4px rgba(0,0,0,.08);
}

/* ═══════════════════════════════════════════
   TABLE WRAP
═══════════════════════════════════════════ */
.dash-tbl-wrap {
  border: 1.5px solid var(--border); border-radius: 14px;
  overflow: hidden; display: flex; flex-direction: column;
}
.dash-tbl-scroll {
  overflow-x: auto; overflow-y: auto; max-height: 500px;
  scrollbar-width: thin; scrollbar-color: var(--border) transparent;
}
.dash-tbl-scroll::-webkit-scrollbar { width: 5px; height: 5px; }
.dash-tbl-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 99px; }
.dash-tbl { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 600px; }
.dash-tbl thead { position: sticky; top: 0; z-index: 2; }
.dash-tbl th {
  background: var(--surface2); padding: 10px 13px;
  text-align: left; font-weight: 700; font-size: 11px;
  color: var(--text3); white-space: nowrap;
  text-transform: uppercase; letter-spacing: .5px;
  box-shadow: 0 1.5px 0 var(--border);
}
.dash-tbl td {
  padding: 11px 13px; border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.dash-tbl tr:last-child td { border-bottom: none; }
.dash-tbl tbody tr:hover td { background: var(--surface2); }

/* ═══════════════════════════════════════════
   GRID CARDS
═══════════════════════════════════════════ */
.dash-grid-scroll {
  overflow-y: auto; max-height: 540px; padding: 14px;
  scrollbar-width: thin;
}
.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.dash-card {
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: 16px; overflow: hidden; display: flex;
  flex-direction: column; transition: box-shadow .18s, transform .18s;
  animation: dcIn .22s ease both;
}
.dash-card:hover { box-shadow: 0 6px 22px rgba(0,0,0,.09); transform: translateY(-2px); }
@keyframes dcIn { from{opacity:0;transform:translateY(10px)} to{opacity:1;transform:translateY(0)} }
.dash-card-bar  { height: 4px; flex-shrink: 0; }
.dash-card-body { padding: 13px 14px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.dash-card-head { display: flex; align-items: center; gap: 10px; }
.dash-card-ava  {
  width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0;
  background: linear-gradient(135deg, #7C3AED, #A855F7);
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 700; color: #fff;
}
.dash-card-info { flex: 1; min-width: 0; }
.dash-card-nama { font-weight: 700; font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-card-meta { font-size: 10.5px; color: var(--text3); margin-top: 1px; }
.dash-card-periode { font-size: 11px; color: var(--text2); font-weight: 600; background: var(--surface2); border-radius: 7px; padding: 2px 7px; white-space: nowrap; flex-shrink: 0; }
.dash-card-progress-wrap { background: var(--border); border-radius: 99px; height: 5px; overflow: hidden; }
.dash-card-progress-bar  { height: 100%; border-radius: 99px; transition: width .4s ease; }
.dash-card-row { display: flex; justify-content: space-between; align-items: center; font-size: 12px; }
.dash-card-row-label { color: var(--text3); }
.dash-card-row-val   { font-weight: 600; color: var(--text); font-family: 'DM Mono', monospace; font-size: 11.5px; }
.dash-card-footer {
  display: flex; gap: 6px; padding: 10px 13px 12px;
  border-top: 1px solid var(--border); background: var(--surface2);
}
.dash-card-footer a,
.dash-card-footer button { flex: 1; font-size: 11.5px; text-align: center; justify-content: center; }

/* ═══════════════════════════════════════════
   PAGER
═══════════════════════════════════════════ */
.dash-pager {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 16px; font-size: 12.5px; color: var(--text2);
  border-top: 1px solid var(--border); flex-wrap: wrap; gap: 8px;
  background: var(--surface2);
}
.dash-pager-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.dash-pp-wrap { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text3); }
.dash-pp-wrap select {
  height: 30px; padding: 0 7px; font-size: 12px;
  border: 1.5px solid var(--border); border-radius: 7px;
  background: var(--surface); color: var(--text2);
  cursor: pointer; font-family: inherit;
}
.dash-pager-btns { display: flex; gap: 3px; flex-wrap: wrap; }
.dash-pager-btn {
  height: 30px; min-width: 30px; padding: 0 8px;
  border: 1.5px solid var(--border); border-radius: 7px;
  background: var(--surface); color: var(--text); font-size: 12px;
  font-family: inherit; cursor: pointer; transition: background .15s;
  display: inline-flex; align-items: center; justify-content: center;
}
.dash-pager-btn:disabled { opacity: .35; cursor: default; }
.dash-pager-btn:hover:not(:disabled):not(.active) { background: var(--bg3); }
.dash-pager-btn.active {
  background: var(--candy-purple, #7C3AED); color: #fff;
  border-color: transparent; box-shadow: 0 2px 8px rgba(124,58,237,.25);
}
.dash-pager-dots { height: 30px; min-width: 24px; display: inline-flex; align-items: flex-end; justify-content: center; padding-bottom: 3px; font-size: 14px; color: var(--text3); }

/* ═══════════════════════════════════════════
   BADGE & MISC
═══════════════════════════════════════════ */
.siswa-ava {
  width: 32px; height: 32px; border-radius: 9px;
  background: linear-gradient(135deg, #7C3AED, #A855F7);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: #fff; flex-shrink: 0;
}
.badge-metode-tunai    { background:#FEF3C7; color:#92400E; }
.badge-metode-transfer { background:#DBEAFE; color:#1E40AF; }
.badge-metode-qris     { background:#EDE9FE; color:#6D28D9; }

/* ═══════════════════════════════════════════
   PANEL CARI — autocomplete & form
═══════════════════════════════════════════ */
.search-steps {
  display: flex; gap: 0; margin-bottom: 20px;
  border-radius: 10px; overflow: hidden;
  border: 1.5px solid var(--border);
  flex-wrap: wrap;
}
.search-step {
  flex: 1; min-width: 100px; padding: 9px 12px;
  display: flex; align-items: center; gap: 8px;
  background: var(--surface2); border-right: 1.5px solid var(--border);
  font-size: 12px; color: var(--text3); transition: background .2s, color .2s;
}
.search-step:last-child { border-right: none; }
.search-step.done   { background: #EDE9FE; color: #6D28D9; }
.search-step.active { background: var(--surface); color: var(--text); font-weight: 600; }
.search-step-num {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--border); color: var(--text3);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700; flex-shrink: 0;
}
.search-step.done   .search-step-num { background: #7C3AED; color: #fff; }
.search-step.active .search-step-num { background: var(--text); color: #fff; }

.filter-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
@media (max-width: 540px) { .filter-row { grid-template-columns: 1fr; } }

.ac-wrap { position: relative; }
.ac-input-group {
  display: flex; align-items: center;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm, 10px);
  background: var(--surface);
  transition: border-color .2s, box-shadow .2s; overflow: hidden;
}
.ac-input-group:focus-within { border-color: var(--candy-purple); box-shadow: 0 0 0 3px rgba(124,58,237,.12); }
.ac-input-group .ac-icon { padding: 0 10px; font-size: 16px; color: var(--text3); flex-shrink: 0; }
.ac-input-group input { flex: 1; border: none; outline: none; background: transparent; padding: 10px 10px 10px 0; font-size: 13.5px; color: var(--text); font-family: inherit; min-width: 0; }
.ac-clear { padding: 0 10px; font-size: 16px; cursor: pointer; color: var(--text3); background: none; border: none; display: none; line-height: 1; }
.ac-clear.visible { display: flex; align-items: center; }
.ac-dropdown {
  position: absolute; top: calc(100% + 5px); left: 0; right: 0;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: 12px; box-shadow: 0 8px 28px rgba(0,0,0,.12);
  z-index: 999; overflow: hidden; display: none; max-height: 280px; flex-direction: column;
}
.ac-dropdown.open { display: flex; }
.ac-dropdown-header { padding: 8px 12px 6px; font-size: 11px; font-weight: 600; color: var(--text3); border-bottom: 1px solid var(--border); background: var(--surface2); display: flex; align-items: center; justify-content: space-between; }
.ac-count-badge { background: var(--candy-purple, #7C3AED); color: #fff; border-radius: 99px; padding: 0 6px; font-size: 10px; font-weight: 700; }
.ac-list { overflow-y: auto; flex: 1; }
.ac-item { padding: 9px 14px; display: flex; align-items: center; gap: 10px; cursor: pointer; transition: background .12s; border-bottom: 1px solid var(--border); }
.ac-item:last-child { border-bottom: none; }
.ac-item:hover, .ac-item.highlighted { background: var(--surface2); }
.ac-item.highlighted { background: #EDE9FE; }
.ac-item-ava { width: 32px; height: 32px; border-radius: 9px; background: linear-gradient(135deg,#7C3AED,#A855F7); display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; color: #fff; flex-shrink: 0; }
.ac-item-info { flex: 1; min-width: 0; }
.ac-item-nama { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ac-item-nama mark { background: #FEF3C7; color: #92400E; border-radius: 3px; padding: 0 2px; }
.ac-item-meta { font-size: 11px; color: var(--text3); margin-top: 1px; }
.ac-item-kelas { background: var(--surface2); border: 1px solid var(--border); border-radius: 6px; padding: 2px 7px; font-size: 10.5px; font-weight: 600; color: var(--text2); white-space: nowrap; flex-shrink: 0; }
.ac-empty { padding: 24px; text-align: center; font-size: 13px; color: var(--text3); }

.selected-chip { display: none; align-items: center; gap: 10px; background: #EDE9FE; border: 1.5px solid #C4B5FD; border-radius: 12px; padding: 10px 14px; margin-bottom: 14px; }
.selected-chip.show { display: flex; }
.selected-chip-ava { width: 36px; height: 36px; border-radius: 10px; background: linear-gradient(135deg,#7C3AED,#A855F7); display: flex; align-items: center; justify-content: center; font-size: 16px; font-weight: 700; color: #fff; flex-shrink: 0; }
.selected-chip-info { flex: 1; min-width: 0; }
.selected-chip-nama { font-size: 13.5px; font-weight: 700; color: #4C1D95; }
.selected-chip-meta { font-size: 11.5px; color: #6D28D9; margin-top: 1px; }
.selected-chip-remove { background: none; border: none; cursor: pointer; font-size: 18px; color: #7C3AED; opacity: .6; padding: 0 2px; }
.selected-chip-remove:hover { opacity: 1; }

/* Bukti zone */
.bukti-zone { border: 2px dashed var(--border); border-radius: var(--radius-sm); cursor: pointer; transition: border-color .2s, background .2s; overflow: hidden; background: var(--surface); }
.bukti-zone:hover { border-color: var(--candy-purple); background: var(--surface2); }
.bukti-preview-inner { padding: 18px; text-align: center; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 80px; }
.bukti-preview-inner img { max-height: 110px; border-radius: 10px; object-fit: contain; margin-bottom: 6px; }

/* Riwayat views */
.riwayat-list { display: flex; flex-direction: column; gap: 8px; }
.riwayat-grid { display: none; grid-template-columns: repeat(auto-fill, minmax(240px,1fr)); gap: 10px; }
.riwayat-card { background: var(--surface); border: 1.5px solid var(--border); border-radius: 14px; overflow: hidden; display: flex; flex-direction: column; transition: box-shadow .18s, transform .18s; animation: rcIn .2s ease both; }
.riwayat-card:hover { box-shadow: 0 5px 18px rgba(0,0,0,.08); transform: translateY(-2px); }
@keyframes rcIn { from{opacity:0;transform:translateY(8px)} to{opacity:1;transform:translateY(0)} }
.riwayat-card-bar  { height: 4px; }
.riwayat-card-body { padding: 13px 14px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.riwayat-card-top  { display: flex; align-items: center; gap: 10px; }
.riwayat-card-ico  { width: 36px; height: 36px; border-radius: 10px; background: var(--surface2); display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
.riwayat-card-amount { font-family: 'DM Mono',monospace; font-weight: 700; font-size: 15px; color: var(--text); }
.riwayat-card-hr   { border: none; border-top: 1px solid var(--border); margin: 0; }
.riwayat-card-rows { display: flex; flex-direction: column; gap: 6px; }
.riwayat-card-row  { display: flex; align-items: center; justify-content: space-between; font-size: 12px; }
.riwayat-card-label { color: var(--text3); display: flex; align-items: center; gap: 4px; }
.riwayat-card-footer { display: flex; gap: 5px; flex-wrap: wrap; padding: 9px 13px 11px; border-top: 1px solid var(--border); background: var(--surface2); }
.riwayat-card-thumb { width: 100%; height: 60px; object-fit: cover; border-radius: 8px; border: 1.5px solid var(--border); cursor: pointer; }
.metode-tunai    { background: #FEF3C7; color: #92400E; }
.metode-transfer { background: #DBEAFE; color: #1E40AF; }
.metode-qris     { background: #EDE9FE; color: #6D28D9; }

/* ═══════════════════════════════════════════
   RESPONSIVE OVERRIDES
═══════════════════════════════════════════ */
@media (max-width: 768px) {
  .main-tab { padding: 8px 13px; font-size: 12px; }
  .dash-filter-row2 { flex-wrap: wrap; }
  .dash-select { flex: 1; min-width: 90px; }
  .view-toggle button .toggle-label { display: none; }
  .dash-pager { justify-content: center; }
  .dash-pager-info { width: 100%; text-align: center; }
  .dash-pager-right { justify-content: center; }
}
@media (max-width: 480px) {
  .pay-stat-val { font-size: 18px; }
  .search-steps { display: none; }
  .status-tab { padding: 6px 9px; font-size: 11px; }
  .dash-tbl th:nth-child(4),
  .dash-tbl td:nth-child(4),
  .dash-tbl th:nth-child(5),
  .dash-tbl td:nth-child(5) { display: none; }
  .riwayat-grid { grid-template-columns: 1fr !important; }
}
</style>

<!-- Page Header -->
<div class="page-header">
  <div>
    <div class="page-header-title">💳 Pembayaran SPP</div>
    <div class="page-header-sub">Lihat semua tagihan atau proses pembayaran per siswa</div>
  </div>
</div>

<!-- Tab Utama -->
<div class="main-tab-bar">
  <button class="main-tab" id="mainTabAll"  onclick="switchMainTab('all')">📋 Semua Pembayaran</button>
  <button class="main-tab" id="mainTabCari" onclick="switchMainTab('cari')">🔍 Bayar per Siswa</button>
</div>

<!-- ══ PANEL SEMUA ══ -->
<div id="panelAll">

  <!-- STAT CARDS -->
  <div class="pay-stats" id="dashStats"></div>

  <!-- FILTER BAR -->
  <div class="dash-filter-wrap">
    <div class="dash-filter-row1">
      <div class="status-tab-bar">
        <button class="status-tab active" id="stab-semua"   onclick="setStatusTab('semua')">Semua</button>
        <button class="status-tab"        id="stab-lunas"   onclick="setStatusTab('lunas')">✅ Lunas</button>
        <button class="status-tab"        id="stab-cicilan" onclick="setStatusTab('cicilan')">🔄 Cicilan</button>
        <button class="status-tab"        id="stab-belum"   onclick="setStatusTab('belum')">⏳ Belum</button>
      </div>
      <input type="text" class="dash-search-input" id="dashSrch"
             placeholder="🔎 Cari nama, NIS, kelas..."
             oninput="dashFilter()">
      <div class="view-toggle">
        <button id="dashBtnList" class="active" onclick="dashSwitchView('list')">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg>
          <span class="toggle-label">Tabel</span>
        </button>
        <button id="dashBtnGrid" onclick="dashSwitchView('grid')">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="8" height="8" rx="1.5"/><rect x="13" y="3" width="8" height="8" rx="1.5"/><rect x="3" y="13" width="8" height="8" rx="1.5"/><rect x="13" y="13" width="8" height="8" rx="1.5"/></svg>
          <span class="toggle-label">Kartu</span>
        </button>
      </div>
    </div>
    <div class="dash-filter-row2">
      <select class="dash-select" id="dashBulan" onchange="dashFilter()">
        <option value="">Semua bulan</option>
        <?php for($b=1;$b<=12;$b++): ?>
          <option value="<?= $b ?>"><?= bulanIndo($b) ?></option>
        <?php endfor ?>
      </select>
      <select class="dash-select" id="dashTahun" onchange="dashFilter()">
        <option value="">Semua tahun</option>
        <?php for($y=date('Y');$y>=2020;$y--): ?>
          <option value="<?= $y ?>"><?= $y ?></option>
        <?php endfor ?>
      </select>
      <select class="dash-select" id="dashMetode" onchange="dashFilter()">
        <option value="">Semua metode</option>
        <option value="tunai">💵 Tunai</option>
        <option value="transfer">🏦 Transfer</option>
        <option value="qris">📱 QRIS</option>
        <option value="dana">💙 DANA</option>
        <option value="gopay">💚 GoPay</option>
        <option value="ovo">💜 OVO</option>
        <option value="shopeepay">🧡 ShopeePay</option>
        <option value="linkaja">❤️ LinkAja</option>
      </select>
      <select class="dash-select" id="dashSort" onchange="dashFilter()">
        <option value="tgl_desc">Terbaru</option>
        <option value="tgl_asc">Terlama</option>
        <option value="nominal_desc">Nominal ↓</option>
        <option value="nominal_asc">Nominal ↑</option>
        <option value="nama_asc">Nama A–Z</option>
      </select>
    </div>
  </div>

  <!-- TABLE + GRID WRAPPER -->
  <div class="dash-tbl-wrap">
    <div id="dashViewList">
      <div class="dash-tbl-scroll">
        <table class="dash-tbl">
          <thead>
            <tr>
              <th style="width:30%">Siswa</th>
              <th style="width:13%">Periode</th>
              <th style="width:14%">Nominal</th>
              <th style="width:13%">Dibayar</th>
              <th style="width:11%">Metode</th>
              <th style="width:11%">Status</th>
              <th style="width:8%"></th>
            </tr>
          </thead>
          <tbody id="dashTbody"></tbody>
        </table>
      </div>
    </div>
    <div id="dashViewGrid" style="display:none">
      <div class="dash-grid-scroll">
        <div class="dash-grid" id="dashGrid"></div>
      </div>
    </div>
    <div class="dash-pager" id="dashPager"></div>
  </div>

</div>

<!-- ══ PANEL CARI ══ -->
<div id="panelCari" style="display:none">
  <div class="card">
    <div class="card-title">🔍 Cari Tagihan Siswa</div>
    <div class="search-steps">
      <div class="search-step active" id="step1"><div class="search-step-num">1</div><span>Filter Kelas</span></div>
      <div class="search-step"        id="step2"><div class="search-step-num">2</div><span>Pilih Siswa</span></div>
      <div class="search-step"        id="step3"><div class="search-step-num">3</div><span>Periode</span></div>
    </div>
    <form method="GET" action="index.php" id="cariForm">
      <input type="hidden" name="page"     value="pembayaran">
      <input type="hidden" name="siswa_id" id="hidSiswaId" value="<?= $siswaId ?>">
      <div class="filter-row">
        <div class="form-group" style="margin-bottom:0">
          <label>🏫 Kelas</label>
          <select name="filter_kelas" id="selKelas" onchange="filterSiswa()">
            <option value="">– Semua Kelas –</option>
            <?php foreach($kelasList as $k): ?>
              <option value="<?= e($k) ?>" <?= $filterKelas===$k?'selected':'' ?>><?= e($k) ?></option>
            <?php endforeach ?>
          </select>
        </div>
        <div class="form-group" style="margin-bottom:0">
          <label>📚 Jurusan</label>
          <select name="filter_jurusan" id="selJurusan" onchange="filterSiswa()">
            <option value="">– Semua Jurusan –</option>
            <?php foreach($jurusanList as $j): ?>
              <option value="<?= e($j) ?>" <?= $filterJurusan===$j?'selected':'' ?>><?= e($j) ?></option>
            <?php endforeach ?>
          </select>
        </div>
      </div>
      <div class="form-group">
        <label>👤 Cari Siswa <span style="font-size:11px;color:var(--text3);font-weight:400">(ketik nama atau NIS)</span></label>
        <div class="selected-chip <?= $siswaId ? 'show' : '' ?>" id="selectedChip">
          <div class="selected-chip-ava" id="chipAva">–</div>
          <div class="selected-chip-info">
            <div class="selected-chip-nama" id="chipNama">–</div>
            <div class="selected-chip-meta" id="chipMeta">–</div>
          </div>
          <button type="button" class="selected-chip-remove" onclick="clearSiswa()">✕</button>
        </div>
        <div class="ac-wrap" id="acWrap" <?= $siswaId ? 'style="display:none"' : '' ?>>
          <div class="ac-input-group">
            <span class="ac-icon">🔎</span>
            <input type="text" id="acInput" placeholder="Ketik nama atau NIS siswa..."
                   autocomplete="off" spellcheck="false" value="<?= e($filterCari) ?>"
                   oninput="onAcInput(this.value)" onkeydown="onAcKeydown(event)" onfocus="onAcFocus()">
            <button type="button" class="ac-clear" id="acClear" onclick="clearAcInput()">×</button>
          </div>
          <div class="ac-dropdown" id="acDropdown">
            <div class="ac-dropdown-header">
              <span id="acDropLabel">Hasil Pencarian</span>
              <span class="ac-count-badge" id="acCountBadge">0</span>
            </div>
            <div class="ac-list" id="acList"></div>
          </div>
        </div>
        <div style="font-size:11px;color:var(--text3);margin-top:5px" id="acHint">
          Filter kelas/jurusan di atas untuk mempersempit hasil
        </div>
      </div>
      <div class="form-row" style="align-items:end">
        <div class="form-group">
          <label>📅 Bulan</label>
          <select name="bulan">
            <?php for($b=1;$b<=12;$b++): ?>
              <option value="<?= $b ?>" <?= $bulan===$b?'selected':'' ?>><?= bulanIndo($b) ?></option>
            <?php endfor ?>
          </select>
        </div>
        <div class="form-group">
          <label>📆 Tahun</label>
          <select name="tahun">
            <?php for($y=date('Y');$y>=2020;$y--): ?>
              <option value="<?= $y ?>" <?= $tahun===$y?'selected':'' ?>><?= $y ?></option>
            <?php endfor ?>
          </select>
        </div>
      </div>
      <button type="submit" class="btn btn-primary" id="btnCari" <?= $siswaId?'':'disabled' ?>>🔍 Cari Tagihan</button>
      <?php if($siswaId): ?><a href="index.php?page=pembayaran" class="btn btn-outline" style="margin-left:6px">↩ Reset</a><?php endif ?>
    </form>
  </div>

  <?php if($siswaId && empty($tagihanList)): ?>
  <div class="card" style="border:2px dashed var(--border);text-align:center;padding:40px">
    <div style="font-size:48px;margin-bottom:14px">📋</div>
    <h3 style="font-size:17px;margin-bottom:8px">Tagihan belum dibuat</h3>
    <p style="color:var(--text2);margin-bottom:22px;font-size:14px">Buat tagihan untuk periode <?= bulanIndo($bulan).' '.$tahun ?></p>
    <a href="index.php?page=tagihan"><button class="btn btn-primary" type="button">📋 Ke Halaman Tagihan</button></a>
  </div>

  <?php elseif(!empty($tagihanList)):
    $metodeIcon  = ['tunai'=>'💵','transfer'=>'🏦','qris'=>'📱','dana'=>'💙','gopay'=>'💚','ovo'=>'💜','shopeepay'=>'🧡','linkaja'=>'❤️','credit_card'=>'💳','bank_transfer'=>'🏦','echannel'=>'🏦','permata'=>'🏦','bca'=>'🏦','bni'=>'🏦','bri'=>'🏦','cstore'=>'🏪','midtrans'=>'💳'];
    $metodeColor = ['tunai'=>'metode-tunai','transfer'=>'metode-transfer','qris'=>'metode-qris','dana'=>'metode-transfer','gopay'=>'metode-qris','ovo'=>'metode-qris','shopeepay'=>'metode-tunai','linkaja'=>'metode-tunai','credit_card'=>'metode-transfer','bank_transfer'=>'metode-transfer','echannel'=>'metode-tunai','permata'=>'metode-transfer','bca'=>'metode-transfer','bni'=>'metode-tunai','bri'=>'metode-transfer','cstore'=>'metode-qris','midtrans'=>'metode-qris'];
    foreach($tagihanList as $t):
      $stBayar = $pdo->prepare("SELECT p.*, a.nama_lengkap as nama_admin FROM pembayaran p LEFT JOIN admin a ON p.admin_id=a.id WHERE p.tagihan_id=? ORDER BY COALESCE(p.tanggal_bayar, p.created_at) DESC");
      $stBayar->execute([$t['id']]);
      $riwayatBayar = $stBayar->fetchAll();
      $bayar        = array_sum(array_column($riwayatBayar,'jumlah_bayar'));
      $sisa         = $t['nominal'] - $bayar;
      $badgeMap2    = ['lunas'=>'badge-success','cicilan'=>'badge-warning'];
      $badgeClass   = $badgeMap2[$t['status']] ?? 'badge-danger';
      $statusLabel  = ['lunas'=>'✅ Lunas','cicilan'=>'🔄 Cicilan'][$t['status']] ?? '⏳ Belum Bayar';
  ?>
  <div class="card">
    <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:20px;flex-wrap:wrap;gap:10px">
      <div style="display:flex;align-items:center;gap:12px">
        <?php
          $fotoT = $t['foto_siswa'] ?? '';
          $hasFotoT = $fotoT && file_exists($fotoSiswaAbs.$fotoT);
        ?>
        <?php if($hasFotoT): ?>
        <img src="<?= e($fotoSiswaUrl.$fotoT) ?>"
             style="width:48px;height:48px;border-radius:14px;object-fit:cover;border:2px solid var(--border);flex-shrink:0"
             onerror="this.style.display='none';this.nextElementSibling.style.display='flex'">
        <div style="width:48px;height:48px;border-radius:14px;background:linear-gradient(135deg,#7C3AED,#A855F7);display:none;align-items:center;justify-content:center;font-size:20px;font-weight:700;color:#fff;flex-shrink:0">
          <?= mb_strtoupper(mb_substr($t['nama'],0,1)) ?>
        </div>
        <?php else: ?>
        <div style="width:48px;height:48px;border-radius:14px;background:linear-gradient(135deg,#7C3AED,#A855F7);display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:700;color:#fff;flex-shrink:0">
          <?= mb_strtoupper(mb_substr($t['nama'],0,1)) ?>
        </div>
        <?php endif ?>
        <div>
          <div style="font-size:17px;font-weight:700"><?= e($t['nama']) ?></div>
          <div style="font-size:12px;color:var(--text2);margin-top:2px"><?= e($t['nis']) ?> · <?= e($t['kelas'].' '.$t['jurusan']) ?> · <?= bulanIndo($t['bulan']).' '.$t['tahun'] ?></div>
        </div>
      </div>
      <div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap">
        <span class="badge <?= $badgeClass ?>" style="font-size:13px;padding:6px 16px"><?= $statusLabel ?></span>
        <?php if(!empty($riwayatBayar)): ?>
        <a href="index.php?page=kwitansi&tagihan_id=<?= $t['id'] ?>" target="_blank" class="btn btn-outline btn-sm" style="font-size:12px">🖨️ Cetak Kwitansi</a>
        <?php endif ?>
      </div>
    </div>

    <div class="info-grid" style="margin-bottom:20px">
      <div class="info-box" style="background:#F3E8FF">
        <div class="info-box-label">Nominal</div>
        <div class="info-box-val" style="color:#7C3AED"><?= rupiah($t['nominal']) ?></div>
      </div>
      <div class="info-box" style="background:#D1FAE5">
        <div class="info-box-label">Sudah Bayar</div>
        <div class="info-box-val" style="color:#059669"><?= rupiah($bayar) ?></div>
      </div>
      <div class="info-box" style="background:<?= $sisa>0?'#FFE4EE':'#D1FAE5' ?>">
        <div class="info-box-label"><?= $sisa>0?'Sisa':'Lunas' ?></div>
        <div class="info-box-val" style="color:<?= $sisa>0?'#E11D48':'#059669' ?>"><?= rupiah(max(0,$sisa)) ?></div>
      </div>
    </div>

    <?php if(!empty($riwayatBayar)): ?>
    <div style="margin-bottom:20px">
      <div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px;flex-wrap:wrap">
        <div style="font-weight:700;font-size:13.5px;color:var(--text)">
          📜 Riwayat Pembayaran
          <span style="background:var(--surface2);border-radius:99px;padding:1px 8px;font-size:11px;margin-left:4px;color:var(--text2)"><?= count($riwayatBayar) ?> transaksi</span>
        </div>
        <div class="view-toggle">
          <button id="rw-btn-list-<?= $t['id'] ?>" class="active" onclick="riwayatSwitchView('<?= $t['id'] ?>','list')">
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg>
            <span class="toggle-label">List</span>
          </button>
          <button id="rw-btn-grid-<?= $t['id'] ?>" onclick="riwayatSwitchView('<?= $t['id'] ?>','grid')">
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="8" height="8" rx="1.5"/><rect x="13" y="3" width="8" height="8" rx="1.5"/><rect x="3" y="13" width="8" height="8" rx="1.5"/><rect x="13" y="13" width="8" height="8" rx="1.5"/></svg>
            <span class="toggle-label">Kartu</span>
          </button>
        </div>
      </div>

      <div class="riwayat-list" id="rw-list-<?= $t['id'] ?>">
        <?php foreach($riwayatBayar as $r):
          $hasBukti  = !empty($r['bukti_bayar']);
          $isPdf     = $hasBukti && strtolower(pathinfo($r['bukti_bayar'],PATHINFO_EXTENSION))==='pdf';
          $buktiPath = $uploadUrl.$r['bukti_bayar'];
          $mid       = 'bukti_'.$r['id'];
          $midEdit   = 'editBukti_'.$r['id'];
          $mIco      = $metodeIcon[$r['metode_bayar']] ?? '💳';
          $mClr      = $metodeColor[$r['metode_bayar']] ?? 'metode-tunai';
          $tglTampil = !empty($r['tanggal_bayar']) ? $r['tanggal_bayar'] : $r['created_at'];
        ?>
        <div style="background:var(--surface2);border-radius:12px;padding:12px 14px">
          <div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap">
            <div style="width:36px;height:36px;border-radius:10px;background:var(--surface);display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0"><?= $mIco ?></div>
            <div style="flex:1;min-width:140px">
              <div style="font-weight:700;font-size:13px"><?= rupiah($r['jumlah_bayar']) ?></div>
              <div style="font-size:11.5px;color:var(--text2);margin-top:1px">
                <?= ucfirst($r['metode_bayar']) ?>
                <?= !empty($r['no_rekening']) ? ' · <span style="font-family:monospace">'.e($r['no_rekening']).'</span>' : '' ?>
                <?= !empty($r['keterangan'])  ? ' · '.e($r['keterangan']) : '' ?>
              </div>
              <div style="font-size:11px;color:var(--text3);margin-top:2px">
                <?= date('d M Y H:i', strtotime($tglTampil)) ?>
                <?= !empty($r['nama_admin']) ? ' · <span style="color:var(--candy-purple)">'.e($r['nama_admin']).'</span>' : '' ?>
              </div>
            </div>
            <div style="display:flex;align-items:center;gap:5px;flex-shrink:0;flex-wrap:wrap">
              <?php if($hasBukti): ?>
                <button class="btn btn-outline btn-sm" onclick="openModal('<?= $mid ?>')"><?= $isPdf?'📄':'🖼️' ?> Lihat</button>
                <button class="btn btn-sm" style="background:#EDE9FE;color:#6D28D9;border:none" onclick="openModal('<?= $midEdit ?>')">✏️ Ganti</button>
                <form method="POST" style="display:inline" onsubmit="return confirm('Hapus bukti?')">
                  <input type="hidden" name="action" value="hapus_bukti">
                  <input type="hidden" name="pembayaran_id" value="<?= $r['id'] ?>">
                  <input type="hidden" name="_siswa_id" value="<?= $siswaId ?>">
                  <input type="hidden" name="_bulan" value="<?= $bulan ?>">
                  <input type="hidden" name="_tahun" value="<?= $tahun ?>">
                  <button class="btn btn-danger btn-sm" type="submit">🗑️</button>
                </form>
              <?php else: ?>
                <button class="btn btn-sm" style="background:#FEF3C7;color:#92400E;border:none" onclick="openModal('<?= $midEdit ?>')">📎 Upload Bukti</button>
              <?php endif ?>
              <a href="index.php?page=kwitansi&id=<?= $r['id'] ?>" target="_blank" class="btn btn-sm" style="background:#EFF6FF;color:#1E40AF;border:none">🖨️</a>
            </div>
          </div>
          <?php if($hasBukti && !$isPdf): ?>
          <div style="margin-top:10px">
            <img src="<?= e($buktiPath) ?>" alt="bukti" style="height:70px;border-radius:8px;object-fit:cover;border:2px solid var(--border);cursor:pointer" onclick="openModal('<?= $mid ?>')" onerror="this.style.display='none'">
          </div>
          <?php endif ?>
        </div>
        <?php endforeach ?>
      </div>

      <div class="riwayat-grid" id="rw-grid-<?= $t['id'] ?>">
        <?php foreach($riwayatBayar as $idx=>$r):
          $hasBukti  = !empty($r['bukti_bayar']);
          $isPdf     = $hasBukti && strtolower(pathinfo($r['bukti_bayar'],PATHINFO_EXTENSION))==='pdf';
          $buktiPath = $uploadUrl.$r['bukti_bayar'];
          $mid       = 'bukti_'.$r['id'];
          $midEdit   = 'editBukti_'.$r['id'];
          $mIco      = $metodeIcon[$r['metode_bayar']] ?? '💳';
          $mClr      = $metodeColor[$r['metode_bayar']] ?? 'metode-tunai';
          $tglTampil = !empty($r['tanggal_bayar']) ? $r['tanggal_bayar'] : $r['created_at'];
          $barColor  = ['tunai'=>'#F59E0B','transfer'=>'#3B82F6','qris'=>'#8B5CF6'][$r['metode_bayar']] ?? '#94A3B8';
        ?>
        <div class="riwayat-card" style="animation-delay:<?= $idx*30 ?>ms">
          <div class="riwayat-card-bar" style="background:<?= $barColor ?>"></div>
          <div class="riwayat-card-body">
            <div class="riwayat-card-top">
              <div class="riwayat-card-ico"><?= $mIco ?></div>
              <div>
                <div class="riwayat-card-amount"><?= rupiah($r['jumlah_bayar']) ?></div>
                <span class="<?= $mClr ?>" style="font-size:10.5px;font-weight:600;border-radius:6px;padding:1px 7px;display:inline-block;margin-top:2px"><?= ucfirst($r['metode_bayar']) ?></span>
              </div>
            </div>
            <hr class="riwayat-card-hr">
            <div class="riwayat-card-rows">
              <div class="riwayat-card-row">
                <span class="riwayat-card-label">Waktu</span>
                <span style="font-size:11.5px;color:var(--text2)"><?= date('d M Y H:i', strtotime($tglTampil)) ?></span>
              </div>
              <?php if(!empty($r['nama_admin'])): ?>
              <div class="riwayat-card-row">
                <span class="riwayat-card-label">Admin</span>
                <span style="font-size:11.5px;color:var(--candy-purple);font-weight:600"><?= e($r['nama_admin']) ?></span>
              </div>
              <?php endif ?>
              <?php if($hasBukti && !$isPdf): ?>
              <img src="<?= e($buktiPath) ?>" class="riwayat-card-thumb" onclick="openModal('<?= $mid ?>')" onerror="this.style.display='none'" alt="bukti">
              <?php endif ?>
            </div>
          </div>
          <div class="riwayat-card-footer">
            <?php if($hasBukti): ?>
              <button class="btn btn-outline btn-sm" onclick="openModal('<?= $mid ?>')" style="font-size:11px"><?= $isPdf?'📄':'🖼️' ?> Lihat</button>
              <button class="btn btn-sm" style="background:#EDE9FE;color:#6D28D9;border:none;font-size:11px" onclick="openModal('<?= $midEdit ?>')">✏️</button>
            <?php else: ?>
              <button class="btn btn-sm" style="background:#FEF3C7;color:#92400E;border:none;font-size:11px;flex:1" onclick="openModal('<?= $midEdit ?>')">📎 Upload</button>
            <?php endif ?>
            <a href="index.php?page=kwitansi&id=<?= $r['id'] ?>" target="_blank" class="btn btn-sm" style="background:#EFF6FF;color:#1E40AF;border:none;font-size:11px">🖨️</a>
          </div>
        </div>
        <?php endforeach ?>
      </div>

      <?php foreach($riwayatBayar as $r):
        $hasBukti  = !empty($r['bukti_bayar']);
        $isPdf     = $hasBukti && strtolower(pathinfo($r['bukti_bayar'],PATHINFO_EXTENSION))==='pdf';
        $buktiPath = $uploadUrl.$r['bukti_bayar'];
        $mid       = 'bukti_'.$r['id'];
        $midEdit   = 'editBukti_'.$r['id'];
        $mIco      = $metodeIcon[$r['metode_bayar']] ?? '💳';
        $tglTampil = !empty($r['tanggal_bayar']) ? $r['tanggal_bayar'] : $r['created_at'];
      ?>
      <?php if($hasBukti): ?>
      <div class="modal-overlay" id="<?= $mid ?>" onclick="if(event.target===this)this.classList.remove('open')">
        <div class="modal" style="max-width:640px">
          <div class="modal-header">
            <h3><?= $isPdf?'📄':'🖼️' ?> Bukti — <?= rupiah($r['jumlah_bayar']) ?></h3>
            <button class="modal-close" onclick="closeModal('<?= $mid ?>')">×</button>
          </div>
          <div class="modal-body" style="padding:16px;text-align:center">
            <?php if($isPdf): ?>
              <div style="background:var(--surface2);border-radius:12px;padding:30px;margin-bottom:12px">
                <div style="font-size:48px;margin-bottom:10px">📄</div>
                <div style="font-size:14px;font-weight:600"><?= e($r['bukti_bayar']) ?></div>
              </div>
              <a href="<?= e($buktiPath) ?>" target="_blank" class="btn btn-primary">⬇️ Buka / Unduh PDF</a>
            <?php else: ?>
              <img src="<?= e($buktiPath) ?>" alt="Bukti" style="max-width:100%;max-height:65vh;border-radius:12px;object-fit:contain;border:2px solid var(--border)" onerror="this.style.display='none'">
              <div style="margin-top:12px;display:flex;gap:8px;justify-content:center;flex-wrap:wrap">
                <a href="<?= e($buktiPath) ?>" target="_blank" class="btn btn-outline btn-sm">⬇️ Unduh</a>
              </div>
            <?php endif ?>
            <div style="margin-top:14px;background:var(--surface2);border-radius:10px;padding:10px 14px;text-align:left;font-size:12px;color:var(--text2)">
              📅 <?= date('d M Y H:i', strtotime($tglTampil)) ?> &nbsp;·&nbsp; <?= $mIco ?> <?= ucfirst($r['metode_bayar']) ?>
            </div>
          </div>
        </div>
      </div>
      <?php endif ?>
      <div class="modal-overlay" id="<?= $midEdit ?>" onclick="if(event.target===this)this.classList.remove('open')">
        <div class="modal" style="max-width:480px">
          <div class="modal-header">
            <h3><?= $hasBukti ? '✏️ Ganti Bukti' : '📎 Upload Bukti' ?></h3>
            <button class="modal-close" onclick="closeModal('<?= $midEdit ?>')">×</button>
          </div>
          <form method="POST" enctype="multipart/form-data">
            <input type="hidden" name="action" value="edit_bukti">
            <input type="hidden" name="pembayaran_id" value="<?= $r['id'] ?>">
            <input type="hidden" name="_siswa_id" value="<?= $siswaId ?>">
            <input type="hidden" name="_bulan" value="<?= $bulan ?>">
            <input type="hidden" name="_tahun" value="<?= $tahun ?>">
            <div class="modal-body">
              <div class="form-group" style="margin-bottom:0">
                <label>Pilih File Bukti</label>
                <div class="bukti-zone" onclick="document.getElementById('gantiInput_<?= $r['id'] ?>').click()">
                  <div id="gantiPreview_<?= $r['id'] ?>" class="bukti-preview-inner">
                    <div style="font-size:28px;margin-bottom:6px">📎</div>
                    <div style="font-size:12px;font-weight:600;color:var(--text2)">Klik untuk pilih file</div>
                    <div style="font-size:11px;color:var(--text3);margin-top:2px">JPG, PNG, WEBP, PDF — maks 5MB</div>
                  </div>
                  <input type="file" id="gantiInput_<?= $r['id'] ?>" name="bukti_bayar" accept="image/jpeg,image/png,image/webp,application/pdf" style="display:none" onchange="prevBukti(this,'gantiPreview_<?= $r['id'] ?>','')">
                </div>
              </div>
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-outline" onclick="closeModal('<?= $midEdit ?>')">Batal</button>
              <button type="submit" class="btn btn-primary">💾 Simpan</button>
            </div>
          </form>
        </div>
      </div>
      <?php endforeach ?>
    </div>
    <?php endif ?>

    <?php if($t['status'] !== 'lunas'): ?>
    <div style="border-top:1px solid var(--border);padding-top:20px">
      <div style="font-weight:700;font-size:14px;margin-bottom:16px">💳 Form Pembayaran Baru</div>
      <form method="POST" enctype="multipart/form-data">
        <input type="hidden" name="action" value="bayar">
        <input type="hidden" name="tagihan_id" value="<?= $t['id'] ?>">
        <input type="hidden" name="_siswa_id" value="<?= $siswaId ?>">
        <input type="hidden" name="_bulan" value="<?= $t['bulan'] ?>">
        <input type="hidden" name="_tahun" value="<?= $t['tahun'] ?>">
        <div class="form-row">
          <div class="form-group">
            <label>Jumlah Bayar (Rp)</label>
            <input type="number" name="jumlah_bayar" value="<?= max(0,$sisa) ?>" min="1" max="<?= max(0,$sisa) ?>" required>
          </div>
          <div class="form-group">
            <label>Metode</label>
            <select name="metode_bayar" id="metode_<?= $t['id'] ?>" onchange="toggleRekening(<?= $t['id'] ?>,this.value)">
              <option value="tunai">💵 Tunai</option>
              <option value="transfer">🏦 Transfer</option>
              <option value="qris">📱 QRIS</option>
              <option value="dana">💙 DANA</option>
              <option value="gopay">💚 GoPay</option>
              <option value="ovo">💜 OVO</option>
              <option value="shopeepay">🧡 ShopeePay</option>
              <option value="linkaja">❤️ LinkAja</option>
            </select>
          </div>
        </div>
        <div class="form-group" id="rekDiv_<?= $t['id'] ?>" style="display:none">
          <label>No. Rekening / Pengirim</label>
          <input type="text" name="no_rekening" placeholder="Nomor rekening atau nama pengirim">
        </div>
        <div class="form-row">
          <div class="form-group">
            <label>Keterangan</label>
            <input type="text" name="keterangan" placeholder="Keterangan (opsional)">
          </div>
          <div class="form-group">
            <label>📅 Tanggal Bayar</label>
            <input type="datetime-local" name="tanggal_bayar" id="inputTglBayar_<?= $t['id'] ?>" value="<?= date('Y-m-d\TH:i') ?>" max="<?= date('Y-m-d\TH:i') ?>">
          </div>
        </div>
        <div class="form-group">
          <label>📎 Bukti (opsional)</label>
          <div class="bukti-zone" onclick="document.getElementById('buktiInput_<?= $t['id'] ?>').click()">
            <div id="buktiPreview_<?= $t['id'] ?>" class="bukti-preview-inner">
              <div style="font-size:30px;margin-bottom:6px">📎</div>
              <div style="font-size:13px;font-weight:600;color:var(--text2)">Klik atau seret file bukti</div>
              <div style="font-size:11px;color:var(--text3);margin-top:4px">JPG, PNG, WEBP, PDF — maks 5MB</div>
            </div>
            <input type="file" id="buktiInput_<?= $t['id'] ?>" name="bukti_bayar" accept="image/jpeg,image/png,image/webp,application/pdf" style="display:none" onchange="prevBukti(this,'buktiPreview_<?= $t['id'] ?>','buktiZone_<?= $t['id'] ?>')">
          </div>
        </div>
        <button type="submit" class="btn btn-success" style="min-width:180px">💳 Proses Pembayaran</button>
      </form>
    </div>
    <?php else: ?>
    <div style="text-align:center;padding:20px;background:#D1FAE5;border-radius:12px">
      <div style="font-size:32px;margin-bottom:8px">🎉</div>
      <div style="font-weight:700;color:#065F46">Tagihan ini sudah lunas!</div>
      <div style="margin-top:12px">
        <a href="index.php?page=kwitansi&tagihan_id=<?= $t['id'] ?>" target="_blank" class="btn btn-outline btn-sm">🖨️ Cetak Kwitansi</a>
      </div>
    </div>
    <?php endif ?>
  </div>
  <?php endforeach; endif ?>
</div>

<script>
/* Tab */
(function(){ switchMainTab('<?= $defaultTab ?>'); })();
function switchMainTab(tab) {
  var isAll = tab === 'all';
  document.getElementById('panelAll').style.display  = isAll  ? '' : 'none';
  document.getElementById('panelCari').style.display = !isAll ? '' : 'none';
  document.getElementById('mainTabAll').classList.toggle('active',  isAll);
  document.getElementById('mainTabCari').classList.toggle('active', !isAll);
}

/* ══ Dashboard ══ */
(function(){
  var BLN = ['','Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','November','Desember'];
  var IDR = function(n){ return 'Rp\u202F'+Number(n).toLocaleString('id-ID'); };
  var PER_PAGE_OPTIONS = [10,15,25,50,100];
  var perPage = 15, page = 1, statusTab = 'semua';
  var dashView = localStorage.getItem('dash_view') || 'list';
  var DATA = <?= $allTagihanJson ?>;
  var filtered = DATA.slice();

  var SC = {
    lunas:       { bar:'#10B981', badge:'#D1FAE5', text:'#065F46' },
    cicilan:     { bar:'#F59E0B', badge:'#FEF3C7', text:'#92400E' },
    belum_bayar: { bar:'#EF4444', badge:'#FFE4EE', text:'#9F1239' },
  };
  var MB = {
    tunai        :{ bg:'#FEF3C7', color:'#92400E', icon:'💵' },
    transfer     :{ bg:'#DBEAFE', color:'#1E40AF', icon:'🏦' },
    qris         :{ bg:'#EDE9FE', color:'#6D28D9', icon:'📱' },
    dana         :{ bg:'#DBEAFE', color:'#1251B5', icon:'💙' },
    gopay        :{ bg:'#CCFBF1', color:'#0369A1', icon:'💚' },
    ovo          :{ bg:'#EDE9FE', color:'#4C3494', icon:'💜' },
    shopeepay    :{ bg:'#FFE4E4', color:'#C0392B', icon:'🧡' },
    linkaja      :{ bg:'#FFE4E4', color:'#B91C1C', icon:'❤️' },
    credit_card  :{ bg:'#DBEAFE', color:'#1E40AF', icon:'💳' },
    bank_transfer:{ bg:'#DBEAFE', color:'#1E40AF', icon:'🏦' },
    echannel     :{ bg:'#FEF3C7', color:'#92400E', icon:'🏦' },
    permata      :{ bg:'#DBEAFE', color:'#1E40AF', icon:'🏦' },
    bca          :{ bg:'#DBEAFE', color:'#006CB7', icon:'🏦' },
    bni          :{ bg:'#FEF3C7', color:'#92400E', icon:'🏦' },
    bri          :{ bg:'#DBEAFE', color:'#00529C', icon:'🏦' },
    cstore       :{ bg:'#D1FAE5', color:'#065F46', icon:'🏪' },
    midtrans     :{ bg:'#EDE9FE', color:'#5B21B6', icon:'💳' },
  };

  window.setStatusTab = function(s){
    statusTab = s;
    ['semua','lunas','cicilan','belum'].forEach(function(k){
      var el=document.getElementById('stab-'+k); if(el) el.classList.toggle('active',k===s);
    });
    page=1; dashFilter();
  };

  window.dashSwitchView = function(mode){
    dashView = mode; localStorage.setItem('dash_view',mode);
    var isList = mode==='list';
    document.getElementById('dashViewList').style.display = isList?'':'none';
    document.getElementById('dashViewGrid').style.display = isList?'none':'';
    document.getElementById('dashBtnList').classList.toggle('active', isList);
    document.getElementById('dashBtnGrid').classList.toggle('active',!isList);
    renderContent();
  };
  (function(){ dashSwitchView(dashView); })();

  window.dashFilter = function(){
    var q   = (document.getElementById('dashSrch').value||'').toLowerCase().trim();
    var bln = document.getElementById('dashBulan').value||'';
    var thn = document.getElementById('dashTahun').value||'';
    var met = document.getElementById('dashMetode').value||'';
    var srt = document.getElementById('dashSort').value||'tgl_desc';
    filtered = DATA.filter(function(d){
      if(statusTab==='lunas'   && d.status!=='lunas')       return false;
      if(statusTab==='cicilan' && d.status!=='cicilan')     return false;
      if(statusTab==='belum'   && d.status!=='belum_bayar') return false;
      if(bln && d.bulan!=bln) return false;
      if(thn && d.tahun!=thn) return false;
      if(met && d.metode!==met) return false;
      if(q && !(d.nama.toLowerCase().includes(q)||d.nis.toLowerCase().includes(q)||d.kelas.toLowerCase().includes(q))) return false;
      return true;
    });
    filtered.sort(function(a,b){
      if(srt==='tgl_desc')     return (b.tgl||'0').localeCompare(a.tgl||'0');
      if(srt==='tgl_asc')      return (a.tgl||'9').localeCompare(b.tgl||'9');
      if(srt==='nominal_desc') return b.nominal-a.nominal;
      if(srt==='nominal_asc')  return a.nominal-b.nominal;
      if(srt==='nama_asc')     return a.nama.localeCompare(b.nama,'id');
      return 0;
    });
    page=1; renderAll();
  };

  function renderAll(){ renderStats(); renderContent(); renderPager(); }
  function renderContent(){ dashView==='grid'?renderGrid():renderTable(); }

  /* ── Stats ── */
  function renderStats(){
    var total=DATA.length;
    var lunas=DATA.filter(function(d){return d.status==='lunas';}).length;
    var ccl  =DATA.filter(function(d){return d.status==='cicilan';}).length;
    var belum=DATA.filter(function(d){return d.status==='belum_bayar';}).length;
    var tkp  =DATA.reduce(function(s,d){return s+d.dibayar;},0);
    var pct  =total?Math.round(lunas/total*100):0;
    var items=[
      {ico:'📋',bg:'#EEF2FF',ic:'#6366F1',lbl:'Total Tagihan',val:total,sub:'seluruh periode',emoji:'📋'},
      {ico:'✅',bg:'#ECFDF5',ic:'#059669',lbl:'Lunas',val:lunas,sub:pct+'% dari total',emoji:'💚'},
      {ico:'🔄',bg:'#FEF3C7',ic:'#D97706',lbl:'Cicilan',val:ccl,sub:'pembayaran parsial',emoji:'🔄'},
      {ico:'⏳',bg:'#FFF1F2',ic:'#E11D48',lbl:'Belum Bayar',val:belum,sub:'perlu tindak lanjut',emoji:'⏳'},
      {ico:'💰',bg:'#FFFBEB',ic:'#D97706',lbl:'Terkumpul',val:IDR(tkp),sub:'semua transaksi',emoji:'💵',small:true},
    ];
    document.getElementById('dashStats').innerHTML = items.map(function(it){
      return '<div class="pay-stat" style="border-left:4px solid '+it.ic+'">'
        +'<div class="pay-stat-icon" style="background:'+it.bg+';font-size:18px">'+it.ico+'</div>'
        +'<div class="pay-stat-label">'+it.lbl+'</div>'
        +'<div class="pay-stat-val" style="color:'+it.ic+(it.small?';font-size:16px':'')+'">'+(it.val)+'</div>'
        +'<div class="pay-stat-sub">'+it.sub+'</div>'
        +'<div class="pay-stat-bg">'+it.emoji+'</div>'
      +'</div>';
    }).join('');
  }

  function esc(s){ return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }

  /* ── Table ── */
  function renderTable(){
    var start=(page-1)*perPage, slice=filtered.slice(start,start+perPage);
    var sb={lunas:'badge-success',cicilan:'badge-warning',belum_bayar:'badge-danger'};
    var sl={lunas:'✅ Lunas',cicilan:'🔄 Cicilan',belum_bayar:'⏳ Belum'};
    var mb={tunai:'badge-metode-tunai',transfer:'badge-metode-transfer',qris:'badge-metode-qris',dana:'badge-metode-transfer',gopay:'badge-metode-qris',ovo:'badge-metode-qris',shopeepay:'badge-metode-tunai',linkaja:'badge-metode-tunai',credit_card:'badge-metode-transfer',bank_transfer:'badge-metode-transfer',echannel:'badge-metode-tunai',permata:'badge-metode-transfer',bca:'badge-metode-transfer',bni:'badge-metode-tunai',bri:'badge-metode-transfer',cstore:'badge-metode-qris',midtrans:'badge-metode-qris'};
    if(!slice.length){
      document.getElementById('dashTbody').innerHTML='<tr><td colspan="7" style="padding:40px;text-align:center;color:var(--text3)">Tidak ada data cocok dengan filter</td></tr>';
      return;
    }
    document.getElementById('dashTbody').innerHTML = slice.map(function(d){
      var dc=d.dibayar>=d.nominal?'#059669':d.dibayar>0?'#D97706':'#E11D48';
      var avaHtml = d.foto
        ? '<img src="'+esc(d.foto)+'" style="width:32px;height:32px;border-radius:9px;object-fit:cover;border:2px solid #E2E8F0;flex-shrink:0" onerror="this.style.display=\'none\';this.nextElementSibling.style.display=\'flex\'">'
          +'<div class="siswa-ava" style="display:none">'+esc(d.nama.charAt(0))+'</div>'
        : '<div class="siswa-ava">'+esc(d.nama.charAt(0))+'</div>';
      return '<tr>'
        +'<td><div style="display:flex;align-items:center;gap:9px">'
          +avaHtml
          +'<div><div style="font-weight:600;font-size:13px">'+esc(d.nama)+'</div>'
          +'<div style="font-size:11px;color:var(--text3)">'+esc(d.nis)+' · '+esc(d.kelas)+' '+esc(d.jurusan)+'</div></div>'
        +'</div></td>'
        +'<td style="font-size:12.5px;white-space:nowrap">'+BLN[d.bulan]+' '+d.tahun+'</td>'
        +'<td style="font-family:monospace;font-size:12.5px;white-space:nowrap">'+IDR(d.nominal)+'</td>'
        +'<td style="font-family:monospace;font-size:12.5px;color:'+dc+';white-space:nowrap">'+IDR(d.dibayar)+'</td>'
        +'<td>'+(d.metode?'<span class="badge '+(mb[d.metode]||'')+'">'+esc(d.metode)+'</span>':'<span style="color:var(--text3)">–</span>')+'</td>'
        +'<td><span class="badge '+(sb[d.status]||'')+'">'+(sl[d.status]||esc(d.status))+'</span></td>'
        +'<td style="text-align:right"><a href="index.php?page=pembayaran&siswa_id='+d.siswaId+'&bulan='+d.bulan+'&tahun='+d.tahun+'" class="btn btn-sm btn-outline" style="font-size:11px;white-space:nowrap" onclick="switchMainTab(\'cari\')">Bayar →</a></td>'
      +'</tr>';
    }).join('');
    var sc=document.querySelector('.dash-tbl-scroll'); if(sc) sc.scrollTop=0;
  }

  /* ── Grid ── */
  function renderGrid(){
    var start=(page-1)*perPage, slice=filtered.slice(start,start+perPage);
    var grid=document.getElementById('dashGrid');
    if(!slice.length){ grid.innerHTML='<div style="grid-column:1/-1;padding:40px;text-align:center;color:var(--text3)">Tidak ada data cocok</div>'; return; }
    grid.innerHTML=slice.map(function(d,idx){
      var sc=SC[d.status]||SC['belum_bayar'];
      var mc=MB[d.metode]||null;
      var pct=d.nominal>0?Math.min(100,Math.round(d.dibayar/d.nominal*100)):0;
      var sisa=Math.max(0,d.nominal-d.dibayar);
      var sl={lunas:'✅ Lunas',cicilan:'🔄 Cicilan',belum_bayar:'⏳ Belum Bayar'}[d.status]||d.status;
      var pf=d.status==='lunas'?'#10B981':d.dibayar>0?'#F59E0B':'#E5E7EB';
      return '<div class="dash-card" style="animation-delay:'+(idx*25)+'ms">'
        +'<div class="dash-card-bar" style="background:'+sc.bar+'"></div>'
        +'<div class="dash-card-body">'
          +'<div class="dash-card-head">'
            +(d.foto
              ? '<img src="'+esc(d.foto)+'" style="width:38px;height:38px;border-radius:11px;object-fit:cover;border:2px solid #E2E8F0;flex-shrink:0" onerror="this.style.display=\'none\';this.nextElementSibling.style.display=\'flex\'">'
                +'<div class="dash-card-ava" style="display:none">'+esc(d.nama.charAt(0))+'</div>'
              : '<div class="dash-card-ava">'+esc(d.nama.charAt(0))+'</div>'
            )
            +'<div class="dash-card-info">'
              +'<div class="dash-card-nama">'+esc(d.nama)+'</div>'
              +'<div class="dash-card-meta">'+esc(d.nis)+' · '+esc(d.kelas)+' '+esc(d.jurusan)+'</div>'
            +'</div>'
            +'<div class="dash-card-periode">'+BLN[d.bulan]+' '+d.tahun+'</div>'
          +'</div>'
          +'<div>'
            +'<div style="display:flex;justify-content:space-between;font-size:11px;color:var(--text3);margin-bottom:4px"><span>Progress</span><span style="font-weight:600;color:var(--text)">'+pct+'%</span></div>'
            +'<div class="dash-card-progress-wrap"><div class="dash-card-progress-bar" style="width:'+pct+'%;background:'+pf+'"></div></div>'
          +'</div>'
          +'<div style="display:flex;flex-direction:column;gap:5px">'
            +'<div class="dash-card-row"><span class="dash-card-row-label">Nominal</span><span class="dash-card-row-val">'+IDR(d.nominal)+'</span></div>'
            +'<div class="dash-card-row"><span class="dash-card-row-label">Dibayar</span><span class="dash-card-row-val" style="color:'+(d.dibayar>=d.nominal?'#059669':d.dibayar>0?'#D97706':'#94A3B8')+'">'+IDR(d.dibayar)+'</span></div>'
            +(sisa>0?'<div class="dash-card-row"><span class="dash-card-row-label">Sisa</span><span class="dash-card-row-val" style="color:#E11D48">'+IDR(sisa)+'</span></div>':'')
          +'</div>'
          +'<div style="display:flex;align-items:center;justify-content:space-between;gap:6px;flex-wrap:wrap">'
            +'<span style="font-size:11px;font-weight:700;padding:3px 10px;border-radius:99px;background:'+sc.badge+';color:'+sc.text+'">'+sl+'</span>'
            +(mc?'<span style="font-size:10.5px;font-weight:600;padding:3px 9px;border-radius:99px;background:'+mc.bg+';color:'+mc.color+'">'+mc.icon+' '+esc(d.metode)+'</span>':'<span style="color:var(--text3);font-size:11px">–</span>')
          +'</div>'
        +'</div>'
        +'<div class="dash-card-footer">'
          +'<a href="index.php?page=pembayaran&siswa_id='+d.siswaId+'&bulan='+d.bulan+'&tahun='+d.tahun+'" class="btn btn-primary btn-sm" onclick="switchMainTab(\'cari\')">'+(d.status==='lunas'?'🖨️ Kwitansi':'💳 Bayar')+'</a>'
          +'<a href="index.php?page=pembayaran&siswa_id='+d.siswaId+'&bulan='+d.bulan+'&tahun='+d.tahun+'" class="btn btn-outline btn-sm" onclick="switchMainTab(\'cari\')">📋 Detail</a>'
        +'</div>'
      +'</div>';
    }).join('');
    var sc=document.querySelector('.dash-grid-scroll'); if(sc) sc.scrollTop=0;
  }

  /* ── Pager ── */
  function renderPager(){
    var total=filtered.length, pages=Math.ceil(total/perPage)||1;
    var start=total?(page-1)*perPage+1:0, end=Math.min(page*perPage,total);
    var ppOpts=PER_PAGE_OPTIONS.map(function(v){ return '<option value="'+v+'"'+(v===perPage?' selected':'')+'>'+v+'</option>'; }).join('');
    var btns='';
    btns+='<button class="dash-pager-btn" onclick="dashGoPage('+(page-1)+')" '+(page<=1?'disabled':'')+'><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg></button>';
    var pw=buildPW(page,pages,2), showF=pw[0]>1, showL=pw[pw.length-1]<pages;
    if(showF){ btns+='<button class="dash-pager-btn" onclick="dashGoPage(1)">1</button>'; if(pw[0]>2) btns+='<span class="dash-pager-dots">···</span>'; }
    pw.forEach(function(p){ btns+='<button class="dash-pager-btn'+(p===page?' active':'')+'" onclick="dashGoPage('+p+')">'+p+'</button>'; });
    if(showL){ if(pw[pw.length-1]<pages-1) btns+='<span class="dash-pager-dots">···</span>'; btns+='<button class="dash-pager-btn" onclick="dashGoPage('+pages+')">'+pages+'</button>'; }
    btns+='<button class="dash-pager-btn" onclick="dashGoPage('+(page+1)+')" '+(page>=pages?'disabled':'')+'><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></button>';
    document.getElementById('dashPager').innerHTML =
      '<span style="font-size:12.5px;color:var(--text2)">'+(total?'Menampilkan <strong>'+start+'&ndash;'+end+'</strong> dari <strong>'+total+'</strong>':'Tidak ada data')+'</span>'
      +'<div class="dash-pager-right">'
        +'<div class="dash-pp-wrap"><span>Tampil</span><select onchange="dashChangePerPage(+this.value)">'+ppOpts+'</select><span>/ hal</span></div>'
        +(pages>1?'<div class="dash-pager-btns">'+btns+'</div>':'')
      +'</div>';
  }
  function buildPW(cur,total,w){ var s=Math.max(1,cur-w),e=Math.min(total,cur+w); var arr=[]; for(var i=s;i<=e;i++) arr.push(i); return arr; }
  window.dashGoPage=function(p){ var pages=Math.ceil(filtered.length/perPage)||1; page=Math.max(1,Math.min(p,pages)); renderContent(); renderPager(); };
  window.dashChangePerPage=function(v){ perPage=v; page=1; renderContent(); renderPager(); };

  dashFilter();
})();

/* ── Autocomplete ── */
(function(){
  var ALL = <?= $siswasJson ?>;
  var acHl=-1, dropOpen=false;
  var acInput=document.getElementById('acInput');
  var acDropdown=document.getElementById('acDropdown');
  var acList=document.getElementById('acList');
  var acClear=document.getElementById('acClear');
  var acHint=document.getElementById('acHint');
  var acCountBadge=document.getElementById('acCountBadge');
  var acDropLabel=document.getElementById('acDropLabel');
  var hidSiswaId=document.getElementById('hidSiswaId');
  var chip=document.getElementById('selectedChip');
  var chipAva=document.getElementById('chipAva');
  var chipNama=document.getElementById('chipNama');
  var chipMeta=document.getElementById('chipMeta');
  var acWrap=document.getElementById('acWrap');
  var btnCari=document.getElementById('btnCari');
  var selKelas=document.getElementById('selKelas');
  var selJurusan=document.getElementById('selJurusan');

  var pre=parseInt(hidSiswaId.value)||0;
  if(pre){ var f=ALL.find(function(s){ return s.id===pre; }); if(f) applyChip(f); }
  updateSteps();

  function updateSteps(){
    var hf=selKelas.value||selJurusan.value, hs=!!hidSiswaId.value;
    document.getElementById('step1').className='search-step '+(hf?'done':'active');
    document.getElementById('step2').className='search-step '+(hs?'done':hf?'active':'');
    document.getElementById('step3').className='search-step '+(hs?'active':'');
  }
  function buildF(q){
    var k=(selKelas.value||'').toLowerCase(), j=(selJurusan.value||'').toLowerCase(), qn=(q||'').toLowerCase().trim();
    return ALL.filter(function(s){
      if(k && s.kelas.toLowerCase()!==k) return false;
      if(j && s.jurusan.toLowerCase()!==j) return false;
      if(qn && !s.nama.toLowerCase().includes(qn) && !s.nis.toLowerCase().includes(qn)) return false;
      return true;
    });
  }
  window.filterSiswa=function(){ clearAcInput(false); updateSteps(); var n=buildF('').length; if(acHint) acHint.textContent=n+' siswa tersedia'; };

  function renderDrop(res,q){
    acList.innerHTML=''; acCountBadge.textContent=res.length; acDropLabel.textContent=q?'Hasil untuk "'+q+'"':'Semua Siswa';
    if(!res.length){ acList.innerHTML='<div class="ac-empty">Siswa tidak ditemukan</div>'; return; }
    res.slice(0,50).forEach(function(s,idx){
      var div=document.createElement('div'); div.className='ac-item'; div.dataset.idx=idx;
      var nhl=eh(s.nama);
      if(q){ var re=new RegExp('('+er(q)+')','gi'); nhl=eh(s.nama).replace(re,'<mark>$1</mark>'); }
      div.innerHTML=(s.foto
        ? '<img src="'+s.foto+'" style="width:32px;height:32px;border-radius:9px;object-fit:cover;border:1.5px solid #E2E8F0;flex-shrink:0" onerror="this.style.display=\'none\';this.nextElementSibling.style.display=\'flex\'">'
          +'<div class="ac-item-ava" style="display:none">'+s.nama.charAt(0).toUpperCase()+'</div>'
        : '<div class="ac-item-ava">'+s.nama.charAt(0).toUpperCase()+'</div>'
      )+'<div class="ac-item-info"><div class="ac-item-nama">'+nhl+'</div><div class="ac-item-meta">'+eh(s.nis)+' · '+eh(s.kelas)+' '+eh(s.jurusan)+'</div></div><div class="ac-item-kelas">'+eh(s.kelas)+'</div>';
      div.addEventListener('mousedown',function(ev){ ev.preventDefault(); selectS(s); });
      acList.appendChild(div);
    });
  }
  function openDrop(res,q){ renderDrop(res,q); acDropdown.classList.add('open'); dropOpen=true; acHl=-1; }
  function closeDrop(){ acDropdown.classList.remove('open'); dropOpen=false; acHl=-1; }
  function selectS(s){ applyChip(s); closeDrop(); updateSteps(); }
  function applyChip(s){
    hidSiswaId.value=s.id;
    chip.classList.add('show');
    acWrap.style.display='none';
    if(s.foto){
      chipAva.innerHTML='<img src="'+s.foto+'" style="width:100%;height:100%;object-fit:cover;border-radius:10px" onerror="this.parentElement.textContent=\''+s.nama.charAt(0).toUpperCase()+'\'">';
    } else {
      chipAva.textContent=s.nama.charAt(0).toUpperCase();
    }
    chipNama.textContent=s.nama;
    chipMeta.textContent=s.nis+' · Kelas '+s.kelas+' '+s.jurusan;
    btnCari.disabled=false;
  }
  window.clearSiswa=function(){ hidSiswaId.value=''; chip.classList.remove('show'); acWrap.style.display=''; acInput.value=''; acClear.classList.remove('visible'); btnCari.disabled=true; updateSteps(); setTimeout(function(){ acInput.focus(); },50); };
  window.onAcInput=function(v){ acClear.classList.toggle('visible',v.length>0); openDrop(buildF(v),v.trim()); };
  window.onAcFocus=function(){ openDrop(buildF(acInput.value),acInput.value.trim()); };
  window.onAcKeydown=function(e){
    if(!dropOpen) return;
    var items=acList.querySelectorAll('.ac-item');
    if(e.key==='ArrowDown'){ e.preventDefault(); acHl=Math.min(acHl+1,items.length-1); items.forEach(function(it,i){ it.classList.toggle('highlighted',i===acHl); }); }
    else if(e.key==='ArrowUp'){ e.preventDefault(); acHl=Math.max(acHl-1,0); items.forEach(function(it,i){ it.classList.toggle('highlighted',i===acHl); }); }
    else if(e.key==='Enter'){ e.preventDefault(); var hl=acList.querySelector('.ac-item.highlighted'); if(hl){ var r=buildF(acInput.value); var s=r[parseInt(hl.dataset.idx)]; if(s) selectS(s); } }
    else if(e.key==='Escape') closeDrop();
  };
  window.clearAcInput=function(focus){ if(focus===undefined)focus=true; acInput.value=''; acClear.classList.remove('visible'); closeDrop(); if(focus) acInput.focus(); };
  document.addEventListener('mousedown',function(ev){ if(acWrap&&!acWrap.contains(ev.target)) closeDrop(); });
  function eh(s){ return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); }
  function er(s){ return s.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'); }
  var ic=buildF('').length; if(acHint) acHint.textContent=ic+' siswa tersedia – ketik nama atau NIS untuk mencari';
})();

/* ── Riwayat view toggle ── */
(function(){
  document.querySelectorAll('[id^="rw-list-"]').forEach(function(el){
    var tid=el.id.replace('rw-list-','');
    applyRwView(tid,localStorage.getItem('rw_view_'+tid)||'list');
  });
})();
function applyRwView(tid,mode){
  var l=document.getElementById('rw-list-'+tid), g=document.getElementById('rw-grid-'+tid);
  var bl=document.getElementById('rw-btn-list-'+tid), bg=document.getElementById('rw-btn-grid-'+tid);
  if(!l||!g) return;
  var isList=mode==='list';
  l.style.display=isList?'flex':'none'; g.style.display=isList?'none':'grid';
  if(bl) bl.classList.toggle('active', isList);
  if(bg) bg.classList.toggle('active',!isList);
}
window.riwayatSwitchView=function(tid,mode){ localStorage.setItem('rw_view_'+tid,mode); applyRwView(tid,mode); };

/* ── Helpers ── */
function toggleRekening(id,val){
  var el=document.getElementById('rekDiv_'+id); if(el) el.style.display=val==='transfer'?'block':'none';
}
function prevBukti(input,previewId,zoneId){
  if(!input.files||!input.files[0]) return;
  var file=input.files[0], prev=document.getElementById(previewId);
  if(file.type==='application/pdf'){
    prev.innerHTML='<div style="font-size:34px;margin-bottom:6px">📄</div><div style="font-size:12px;font-weight:700;color:#059669">'+file.name+'</div>';
  } else {
    var reader=new FileReader();
    reader.onload=function(e){ prev.innerHTML='<img src="'+e.target.result+'" alt="preview"><div style="font-size:11px;font-weight:700;color:#059669;margin-top:4px">'+file.name+'</div>'; };
    reader.readAsDataURL(file);
  }
  if(zoneId){ var z=document.getElementById(zoneId); if(z){ z.style.borderColor='#34D399'; z.style.background='#F0FDF4'; } }
}
(function(){
  function padZ(n){ return String(n).padStart(2,'0'); }
  function nowLocal(){ var d=new Date(); return d.getFullYear()+'-'+padZ(d.getMonth()+1)+'-'+padZ(d.getDate())+'T'+padZ(d.getHours())+':'+padZ(d.getMinutes()); }
  function refreshTgl(){ var now=nowLocal(); document.querySelectorAll('[id^="inputTglBayar_"]').forEach(function(el){ if(!el.dataset.userEdited){ el.value=now; el.max=now; } }); }
  document.addEventListener('change',function(e){ if(e.target&&e.target.id&&e.target.id.startsWith('inputTglBayar_')) e.target.dataset.userEdited='1'; });
  refreshTgl(); setInterval(refreshTgl,60000);
})();
</script>

<?php require_once 'layout/footer.php'; ?>