<?php date_default_timezone_set('Asia/Jakarta'); ?>
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>AbOn BHB</title>

  <!-- TailwindCSS -->
  <script src="https://cdn.tailwindcss.com"></script>
  <!-- html2canvas & jsPDF -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>

  <style>
  :root{
    /* Palet pastel hijau ala iOS */
    --d1:#e9f9f0;  /* hijau muda sangat soft */
    --d2:#d2f2e1;
    --d3:#bfe7d1;
    --d4:#a8dbc2;
    --d5:#93cfb3;
  }

  body{
    min-height:100vh;
    color:#0f172a;
    background:
      radial-gradient(1200px 600px at 10% 10%, rgba(255,255,255,.9), transparent 60%),
      radial-gradient(1000px 800px at 90% 15%, rgba(226,244,235,.9), transparent 60%),
      radial-gradient(900px 700px at 50% 85%, rgba(214,238,227,.9), transparent 60%),
      linear-gradient(145deg, var(--d1), var(--d2), var(--d3), var(--d4), var(--d5));
    background-attachment:fixed;
    animation:softHue 24s ease-in-out infinite alternate;
  }

  @keyframes softHue{
    0%  { filter:hue-rotate(0deg) brightness(1); }
    50% { filter:hue-rotate(-8deg) brightness(1.03); }
    100%{ filter:hue-rotate(6deg) brightness(1.05); }
  }

  .glass{
    background:rgba(255,255,255,.78);
    backdrop-filter:blur(16px);
    -webkit-backdrop-filter:blur(16px);
    border:1px solid rgba(148, 201, 171, .45);
    box-shadow:
      0 18px 40px rgba(15, 23, 42, .10),
      0 0 0 1px rgba(255,255,255,.6);
  }

  /* Tombol utama bernuansa hijau pastel */
  #btnIn{
    background-image:linear-gradient(135deg,#34d399,#6ee7b7,#a7f3d0);
    box-shadow:0 14px 30px rgba(16,185,129,.35);
  }
  #btnIn:hover{
    filter:brightness(1.03);
  }

  /* Tombol kamera & flip */
  #btnRetake{
    background:#22c55e;
    box-shadow:0 8px 20px rgba(34,197,94,.35);
  }
  #btnRetake:hover{ filter:brightness(1.05); }

  #btnFlipCanvas{
    background:#10b981;
    box-shadow:0 8px 20px rgba(16,185,129,.35);
  }
  #btnFlipCanvas:hover{ filter:brightness(1.05); }

  /* Tombol modal kamera */
  #btnCapture{
    background:#22c55e;
    box-shadow:0 10px 24px rgba(34,197,94,.4);
  }
  #btnCapture:hover{ filter:brightness(1.06); }

  #btnCloseCam{
    background:#0f172a;
  }

  /* Tombol tanda tangan */
  #sigClear{
    background:#e5f7ed;
  }
  #sigCancel{
    background:#f97373;
  }
  #sigSave{
    background:#16a34a;
    box-shadow:0 8px 20px rgba(22,163,74,.4);
  }

  /* Tombol simpan gambar / PDF / WA */
  #btnImg{
    background:#10b981;
    box-shadow:0 10px 22px rgba(16,185,129,.4);
  }
  #btnPdf{
    background:#059669;
    box-shadow:0 10px 22px rgba(5,150,105,.4);
  }
  #waSend{
    background:#22c55e;
    box-shadow:0 10px 22px rgba(34,197,94,.4);
  }

  /* Tombol riwayat & print */
  #btnLoadMonth{
    background:#0f766e;
  }
  #btnPrint{
    background:#15803d;
  }

  /* Tabel riwayat: lebih iOS-ish, soft */
  #historyTable{
    background:rgba(255,255,255,.9);
    border-radius:1rem;
    border:1px solid rgba(148,201,171,.55);
  }
  #historyTable thead tr{
    background:linear-gradient(135deg,#e0f2f1,#e3f9ed);
  }
  #historyTable th{
    font-weight:600;
    color:#0f172a;
  }

  /* Cetak sederhana (biar tetap hitam putih rapi saat print) */
  @media print{
    body{background:#fff !important;}
    .no-print{display:none !important;}
    .print-wrap{box-shadow:none !important;border:none !important;background:#fff !important;}
    .print-title{margin:0 0 8px 0;}
    table{border-collapse:collapse;width:100%}
    th,td{border:1px solid #000;padding:6px 8px;font-size:12px}
    th{background:#f0f0f0}
    footer{display:none}
    .ttd-img{display:none !important;}
    .ttd-print{display:inline !important;}
  }
  .ttd-print{display:none;}
</style>

</head>

<body>
<div class="max-w-5xl mx-auto p-4 sm:p-6">
  <!-- HEADER -->
  <header class="glass rounded-3xl p-5 sm:p-7 shadow-xl flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 no-print">
    <div>
      <h1 class="text-2xl sm:text-3xl font-extrabold tracking-tight">🌈🎶 AbOn — Masuk </h1>
      <p id="todayStr" class="text-sm text-slate-700"></p>
      <div class="text-xs mt-2 bg-white/70 rounded-xl p-2">
        🤳 <b>Wajib senyum</b>, tanpa masker, foto jelas (not mirror). ✍️ Setelah foto, <b>tanda tangan langsung</b> di layar.
      </div>
    </div>
    <div class="bg-white/80 rounded-2xl shadow-inner px-4 py-3 text-center">
      <div class="text-[11px] uppercase tracking-wider text-slate-500">Waktu Sekarang</div>
      <div id="digitalClock" class="font-mono text-2xl sm:text-3xl font-bold tracking-widest">00:00:00</div>
    </div>
  </header>

  <!-- ALERT -->
  <div id="alert" class="hidden mt-4 p-3 rounded-2xl no-print"></div>

  <section class="mt-6 grid lg:grid-cols-5 gap-4 no-print">
    <!-- LEFT -->
    <div class="lg:col-span-2 space-y-4">
      <!-- Nama -->
      <div class="glass rounded-3xl p-4 shadow-lg space-y-3">
        <label class="block text-sm font-semibold mb-1">👤 Nama Pegawai</label>
        <select id="name" class="w-full rounded-2xl border border-slate-300 p-2">
          <option value="">-- Pilih Nama --</option>
          <option>Bu Annisa</option>
          <option>Bu Dian</option>
          <option>Mrs Linda</option>
          <option>Miss Natasya</option>
        </select>
        <div id="nameMotivation" class="hidden rounded-2xl px-3 py-2 text-sm font-medium bg-gradient-to-r from-amber-100 via-fuchsia-100 to-sky-100 border border-white/60 shadow-inner"></div>
      </div>

      <!-- Foto & Kontrol -->
      <div class="glass rounded-3xl p-4 shadow-lg space-y-3">
        <label class="block text-sm font-semibold">🤳 Foto Wajah</label>
        <div class="flex flex-wrap gap-2">
          <button id="btnRetake" class="rounded-xl bg-indigo-600 text-white px-3 py-2 text-sm">📸 Ambil/ Ulangi</button>
          <button id="btnFlipCanvas" class="rounded-xl bg-fuchsia-600 text-white px-3 py-2 text-sm">🔁 Balik Horizontal</button>
        </div>
        <canvas id="preview" class="w-full rounded-2xl shadow hidden"></canvas>
        <p class="text-xs text-slate-700">Tips: posisikan wajah di tengah, pencahayaan cukup, jangan miring ekstrem.</p>
      </div>

      <!-- Tombol Masuk -->
      <div class="glass rounded-3xl p-4 shadow-lg space-y-3">
        <button id="btnIn" class="w-full rounded-2xl bg-gradient-to-r from-indigo-500 via-fuchsia-500 to-amber-500 text-white py-3 font-semibold shadow-lg">
          ✅ Absen Masuk
        </button>
        <p class="text-xs text-slate-700">Tombol aktif bila <b>nama terpilih</b>, <b>foto</b> & <b>TTD</b> tersedia.</p>
      </div>
    </div>

    <!-- RIGHT -->
    <div class="lg:col-span-3 space-y-4">
      <div class="glass rounded-3xl p-4 shadow-lg">
        <p class="text-sm">💬 Pesan Semangat Hari Ini</p>
        <p id="motivation" class="text-lg font-bold"></p>
      </div>

      <!-- Ringkasan -->
      <div id="receiptWrap" class="glass rounded-3xl p-4 shadow-lg space-y-3">
        <h2 class="text-xl font-extrabold">🧾 Ringkasan Absen</h2>
        <div id="receipt" class="grid grid-cols-1 sm:grid-cols-12 gap-y-1 text-sm bg-white/70 rounded-2xl p-3">
          <div class="sm:col-span-5 font-semibold">Nama Pegawai</div><div class="sm:col-span-7" id="rName"></div>
          <div class="sm:col-span-5 font-semibold">Tanggal</div><div class="sm:col-span-7" id="rDate"></div>
          <div class="sm:col-span-5 font-semibold">Waktu Absen</div><div class="sm:col-span-7" id="rTime"></div>
          <div class="sm:col-span-5 font-semibold">Keterlambatan</div><div class="sm:col-span-7" id="rLate"></div>
          <div class="sm:col-span-5 font-semibold">Model HP</div><div class="sm:col-span-7 break-words" id="rDev"></div>
        </div>
        <img id="rPhoto" class="w-full max-h-72 object-contain rounded-2xl border hidden bg-white/60" alt="Foto Absen"/>
        <div class="flex gap-2 items-center">
          <span class="text-sm text-slate-700">Tanda Tangan:</span>
          <img id="sigPreview" class="h-10 ttd-img rounded bg-white/70 px-2 py-1 border hidden" alt="TTD"/>
        </div>
        <div class="flex flex-wrap gap-2 no-print">
          <button id="btnImg" class="rounded-2xl bg-fuchsia-600 hover:bg-fuchsia-700 text-white px-4 py-2 font-semibold shadow">🖼️ Simpan Gambar</button>
          <button id="btnPdf" class="rounded-2xl bg-sky-600 hover:bg-sky-700 text-white px-4 py-2 font-semibold shadow">📑 Simpan PDF</button>
       
        </div>
      </div>
    </div>
  </section>

  <!-- RIWAYAT PUBLIK -->
  <section class="mt-10">
    <div class="glass rounded-3xl p-4 sm:p-5 shadow-xl print-wrap">
      <div class="flex items-center justify-between mb-3 no-print">
        <h2 class="text-xl font-extrabold">📚 Riwayat</h2>
        <div class="text-xs text-slate-600 flex items-center gap-2">
          <label for="filterMonth">Bulan:</label>
          <input id="filterMonth" type="month" class="border border-slate-300 rounded-xl px-2 py-1 text-sm" />
          
        </div>
      </div>
<button id="btnLoadMonth" class="rounded-xl bg-slate-800 text-white px-3 py-1 text-sm">Muat</button>
          <button id="btnPrint" class="rounded-xl bg-emerald-600 text-white px-3 py-1 text-sm">Print</button>

      <h3 id="listTitle" class="print-title text-base font-semibold mb-2">Daftar Absensi</h3>

      <div class="no-print mt-3 mb-4 border-t border-dashed border-slate-300 pt-3">
        <h4 class="font-semibold text-sm mb-2">📊 Analisis Kerajinan Bulan Ini</h4>
        <div class="flex flex-col lg:flex-row gap-4">
          <div class="lg:w-1/3 space-y-2">
            <label for="filterName" class="block text-xs text-slate-600 mb-1">Pilih Pegawai / Tutor:</label>
            <select id="filterName" class="border border-slate-300 rounded-xl px-2 py-1 text-sm w-full">
              <option value="">-- pilih nama --</option>
            </select>
            <div id="kerajinanSummary" class="text-sm mt-2"></div>
          </div>
          <div class="lg:w-2/3 space-y-3">
            <div class="flex items-center justify-between text-[11px] text-slate-600">
              <span>Grafik Batang Kerajinan per Pegawai (bulan terpilih)</span>
              <span class="flex items-center gap-2">
                <span class="inline-flex items-center gap-1"><span class="w-3 h-3 rounded-full bg-emerald-400"></span><span>&ge; 95%</span></span>
                <span class="inline-flex items-center gap-1"><span class="w-3 h-3 rounded-full bg-amber-400"></span><span>85–94%</span></span>
                <span class="inline-flex items-center gap-1"><span class="w-3 h-3 rounded-full bg-rose-400"></span><span>&lt; 85%</span></span>
              </span>
            </div>
            <div class="bg-white/80 rounded-2xl border border-slate-200 p-2">
              <canvas id="kerajinanChart" class="w-full h-40"></canvas>
            </div>
            <div class="bg-white/80 rounded-2xl border border-slate-200 p-2">
              <div class="flex items-center justify-between text-[11px] text-slate-600 mb-1">
                <span>🏅 Top 5 Pegawai Paling Rajin</span>
              </div>
              <table class="w-full text-xs">
                <thead>
                  <tr class="text-left">
                    <th class="py-1 pr-2">Nama</th>
                    <th class="py-1 pr-2">Kerajinan</th>
                    <th class="py-1 pr-2">Hari</th>
                    <th class="py-1">Terlambat</th>
                  </tr>
                </thead>
                <tbody id="top5Body"></tbody>
              </table>
            </div>
          </div>
        </div>
      </div>

      <div class="overflow-x-auto">
        <table id="historyTable" class="w-full text-sm bg-white/80 rounded-2xl border border-white/60">
          <thead class="bg-white">
            <tr class="text-left">
              <th class="px-3 py-2 border-b">No</th>
              <th class="px-3 py-2 border-b">Tanggal</th>
              <th class="px-3 py-2 border-b">Waktu</th>
              <th class="px-3 py-2 border-b">Nama</th>
              <th class="px-3 py-2 border-b">Terlambat</th>
              <th class="px-3 py-2 border-b">Perangkat</th>
              <th class="px-3 py-2 border-b">TTD</th>
            </tr>
          </thead>
          <tbody id="historyBody"></tbody>
        </table>
      </div>
      <div id="historyEmpty" class="hidden text-sm text-slate-700 mt-2">Belum ada data untuk bulan ini.</div>
    </div>
  </section>

  <footer class="mt-8 text-center text-xs text-slate-700">© <span id="year"></span> AbOn BHB</footer>
</div>

<!-- CAMERA MODAL -->
<div id="camModal" class="fixed inset-0 z-[70] bg-black/50 hidden items-center justify-center p-4 no-print">
  <div class="relative w-full max-w-2xl rounded-3xl bg-white p-5 shadow-2xl">
    <div class="flex flex-col sm:flex-row gap-5">
      <div class="flex-1">
        <video id="camVideo" autoplay playsinline class="w-full rounded-2xl bg-black aspect-[4/3] object-cover"></video>
        <div class="flex gap-2 mt-3">
          <button id="btnCapture" class="rounded-xl bg-pink-600 text-white px-4 py-2 font-semibold shadow">😁 Ambil Foto</button>
          <button id="btnCloseCam" class="rounded-xl bg-slate-700 text-white px-4 py-2 font-semibold shadow">Tutup</button>
        </div>
      </div>
      <div class="sm:w-64">
        <h3 class="text-xl font-extrabold">WAJIB SENYUM 😁</h3>
        <p class="text-sm text-slate-700 mt-2">Setelah foto, kamu akan diminta <b>tanda tangan langsung</b> di layar.</p>
      </div>
    </div>
  </div>
</div>

<!-- SIGNATURE MODAL (tanda tangan langsung) -->
<div id="sigModal" class="fixed inset-0 z-[80] bg-black/50 hidden items-center justify-center p-4 no-print">
  <div class="relative w-full max-w-xl rounded-3xl bg-white p-5 shadow-2xl">
    <h3 class="text-lg font-extrabold mb-2">✍️ Tanda Tangan</h3>
    <p class="text-sm text-slate-700 mb-3">Tulis tanda tanganmu di bawah ini (gunakan jari/stylus/mouse). Latar belakang transparan.</p>
    <div class="rounded-2xl border border-slate-300 bg-[rgba(255,255,255,0.0)]">
      <canvas id="sigCanvas" class="w-full h-60 block"></canvas>
    </div>
    <div class="flex gap-2 mt-3 justify-between">
      <div class="flex gap-2">
        <button id="sigClear" class="rounded-xl bg-slate-200 text-slate-900 px-4 py-2 font-semibold shadow">Hapus</button>
        <label class="inline-flex items-center gap-2 text-sm">
          Warna garis
          <input id="sigColor" type="color" value="#0f172a" class="border rounded" />
        </label>
        <label class="inline-flex items-center gap-2 text-sm">
          Ketebalan
          <input id="sigWidth" type="range" min="1" max="8" value="3" />
        </label>
      </div>
      <div class="flex gap-2">
        <button id="sigCancel" class="rounded-xl bg-rose-600 text-white px-4 py-2 font-semibold shadow">Batal</button>
        <button id="sigSave" class="rounded-xl bg-emerald-600 text-white px-4 py-2 font-semibold shadow">Simpan TTD</button>
      </div>
    </div>
  </div>
</div>

<script>
/* ========= Konstanta API ========= */
const API_URL = 'absensi_api.php';

/* ========= Util ========= */
const $=s=>document.querySelector(s);
function fmt2(n){return n.toString().padStart(2,'0');}
function toTimeStr(d){return `${fmt2(d.getHours())}:${fmt2(d.getMinutes())}:${fmt2(d.getSeconds())}`;}
function toDateStrID(d){const days=['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'];const months=['Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','November','Desember'];return `${days[d.getDay()]}, ${fmt2(d.getDate())} ${months[d.getMonth()]} ${d.getFullYear()}`;}
function ymd(d){return `${d.getFullYear()}-${fmt2(d.getMonth()+1)}-${fmt2(d.getDate())}`;}
function minutesDiff(a,b){return Math.round((a-b)/60000);}

/* clock & header text */
(function initHeader(){
  const yr=$('#year'), today=$('#todayStr'), clk=$('#digitalClock');
  if(yr) yr.textContent=new Date().getFullYear();
  if(today) today.textContent=toDateStrID(new Date());
  if(clk){
    clk.textContent=toTimeStr(new Date());
    setInterval(()=>{ clk.textContent=toTimeStr(new Date()); },1000);
  }
})();
const MOTIVATIONS=['Istirahat yang baik, semangat menjemput pekan! 🌞','Senin mantap! Mulai kecil, konsisten besar. 💪','Selasa buktikan kualitasmu! 🚀','Rabu fokus & rapi, progres pasti. ✨','Kamis jangan ragu, lanjut maju. 🔧','Jumat tutup pekan dengan bangga. 🏁','Sabtu produktif seperlunya, seimbang selalu. ⚖️'];
const motEl=$('#motivation'); if(motEl){ motEl.textContent=MOTIVATIONS[new Date().getDay()]; }

function showAlert(msg,type='info'){
  const el=$('#alert'); if(!el) return;
  const styles={info:'bg-blue-50 text-blue-800 border border-blue-200',success:'bg-emerald-50 text-emerald-800 border-emerald-200',error:'bg-rose-50 text-rose-800 border-rose-200'};
  el.className=`mt-4 p-3 rounded-2xl ${styles[type]}`;
  el.textContent=msg;el.classList.remove('hidden');
  setTimeout(()=>el.classList.add('hidden'),4500);
}

/* ========= Jam Masuk ========= */
const CHECKIN={'Bu Annisa':'08:00','Bu Dian':'08:00','Mrs Linda':'07:15','Miss Natasya':'07:15'};
function computeLateStr(name, now){
  const ci=CHECKIN[name]; if(!ci) return '-';
  const [h,m]=ci.split(':').map(Number);
  const sch=new Date(now.getFullYear(),now.getMonth(),now.getDate(),h,m,0);
  const diff=minutesDiff(now,sch);
  return diff>0?`${diff} menit`:'0';
}

/* ========= TTS ========= */
function pickMaleIDVoice(){
  const voices=window.speechSynthesis.getVoices();
  let cand=voices.filter(v=>/id-ID|Indones/i.test(v.lang||'')); 
  let male=cand.find(v=>/male|laki|budi|arif|Id-ID/i.test(v.name||'')); 
  if(male) return male;
  let googleID=cand.find(v=>/Google|Bahasa Indonesia/i.test(v.name||'')); 
  return googleID||cand[0]||voices[0]||null;
}
function speak(text){
  if(!('speechSynthesis'in window))return;
  const u=new SpeechSynthesisUtterance(text);
  const setVoice=()=>{const v=pickMaleIDVoice(); if(v) u.voice=v; u.lang=(v&&v.lang)||'id-ID'; u.rate=1.0; u.pitch=0.9; speechSynthesis.cancel(); speechSynthesis.speak(u);};
  const vs=speechSynthesis.getVoices(); if(!vs||!vs.length) speechSynthesis.onvoiceschanged=()=>setVoice(); else setVoice();
}
function nicknameLine(name){
  switch(name){
    case'Bu Annisa':return'Bu Annisa, si klawu glowing!';
    case'Bu Dian':return'Bu Dian, ratu laundry!';
    case'Mrs Linda':return'Bunda Paud Linda, rambut kuncir siap tempur!';
    case'Miss Natasya':return'Miss Natasya, calon pengantin baru—pasangannya siapa nih?';
    default:return name;
  }
}

/* ========= Deteksi Device ========= */
function parseBrandModelFromUA(uaRaw){
  const ua=uaRaw||navigator.userAgent||""; let dev=""; const m=ua.match(/Android [\d.]+; ([^;)]*?)(?: Build|\))/i); if(m&&m[1]) dev=m[1].trim();
  if(/iPhone/i.test(ua)) return {brand:"Apple", model:"iPhone"};
  return {brand:"Android", model:dev||"Device"};
}
async function getDeviceInfo(){
  let ip="N/A"; try{ ip=(await (await fetch('https://api.ipify.org?format=json')).json()).ip; }catch(e){}
  const p=parseBrandModelFromUA(navigator.userAgent||'');
  const pretty=`${navigator.userAgent} | ${navigator.platform} | IP:${ip}`;
  return { pretty, model: `${p.brand} ${p.model}`.trim() };
}

/* ========= Kamera ========= */
let stream=null, lastPhotoDataUrl='', signatureDataUrl='';
const camModal=$('#camModal'), videoEl=$('#camVideo'), btnRetake=$('#btnRetake'), btnCapture=$('#btnCapture'), btnCloseCam=$('#btnCloseCam');
function camOpen(){ if(!camModal) return; camModal.classList.remove('hidden'); camModal.classList.add('flex'); }
async function openCam(){
  camOpen();
  try{
    if(stream) stream.getTracks().forEach(t=>t.stop());
    stream=await navigator.mediaDevices.getUserMedia({ video:{ facingMode:'user' }, audio:false });
    if(videoEl) videoEl.srcObject=stream;
  }catch(e){ showAlert('Tidak bisa akses kamera: '+e.message,'error'); }
}
function closeCam(){
  if(!camModal) return;
  camModal.classList.add('hidden'); camModal.classList.remove('flex');
  if(stream){ stream.getTracks().forEach(t=>t.stop()); stream=null; }
}
if(btnRetake) btnRetake.addEventListener('click', openCam);
if(btnCloseCam) btnCloseCam.addEventListener('click', closeCam);

/* ========= Modal Tanda Tangan (kanvas) ========= */
const sigModal = $('#sigModal');
const sigCanvas = $('#sigCanvas');
const sigClear = $('#sigClear');
const sigCancel = $('#sigCancel');
const sigSave = $('#sigSave');
const sigColor = $('#sigColor');
const sigWidth = $('#sigWidth');

let sigCtx, drawing=false, lastX=0, lastY=0;

function resizeSigCanvas(){
  // Skala besar agar halus, tapi tetap responsif
  const rect = sigCanvas.getBoundingClientRect();
  const ratio = Math.min(window.devicePixelRatio || 1, 2);
  sigCanvas.width = Math.floor(rect.width * ratio);
  sigCanvas.height = Math.floor(rect.height * ratio);
  sigCtx = sigCanvas.getContext('2d');
  // Latar transparan (tidak diisi apapun)
  sigCtx.lineCap = 'round';
  sigCtx.lineJoin = 'round';
  sigCtx.strokeStyle = sigColor.value || '#0f172a';
  sigCtx.lineWidth = Number(sigWidth.value) || 3;
  sigCtx.clearRect(0,0,sigCanvas.width,sigCanvas.height);
}
function openSigModal(){
  sigModal.classList.remove('hidden'); sigModal.classList.add('flex');
  resizeSigCanvas();
}
function closeSigModal(){
  sigModal.classList.add('hidden'); sigModal.classList.remove('flex');
}
function startDraw(x,y){ drawing=true; lastX=x; lastY=y; }
function moveDraw(x,y){
  if(!drawing) return;
  sigCtx.strokeStyle = sigColor.value || '#0f172a';
  sigCtx.lineWidth = Number(sigWidth.value) || 3;
  sigCtx.beginPath();
  sigCtx.moveTo(lastX, lastY);
  sigCtx.lineTo(x, y);
  sigCtx.stroke();
  lastX=x; lastY=y;
}
function endDraw(){ drawing=false; }

function clientXY(e){
  if(e.touches && e.touches.length){ const t=e.touches[0]; return {x:t.clientX, y:t.clientY}; }
  return {x:e.clientX, y:e.clientY};
}
function toCanvasXY(e){
  const {x,y}=clientXY(e);
  const rect = sigCanvas.getBoundingClientRect();
  const ratioX = sigCanvas.width / rect.width;
  const ratioY = sigCanvas.height / rect.height;
  return {cx: (x-rect.left)*ratioX, cy: (y-rect.top)*ratioY};
}

// events mouse
sigCanvas.addEventListener('mousedown', e=>{ const {cx,cy}=toCanvasXY(e); startDraw(cx,cy); });
window.addEventListener('mousemove', e=>{ if(!drawing) return; const {cx,cy}=toCanvasXY(e); moveDraw(cx,cy); });
window.addEventListener('mouseup', endDraw);
// events touch
sigCanvas.addEventListener('touchstart', e=>{ const {cx,cy}=toCanvasXY(e); startDraw(cx,cy); e.preventDefault(); }, {passive:false});
sigCanvas.addEventListener('touchmove', e=>{ const {cx,cy}=toCanvasXY(e); moveDraw(cx,cy); e.preventDefault(); }, {passive:false});
sigCanvas.addEventListener('touchend', endDraw);

window.addEventListener('resize', ()=>{ if(!sigModal.classList.contains('hidden')) resizeSigCanvas(); });
if(sigClear) sigClear.addEventListener('click', ()=>{ resizeSigCanvas(); });
if(sigCancel) sigCancel.addEventListener('click', ()=>{ closeSigModal(); signatureDataUrl=''; showAlert('Tanda tangan dibatalkan.','error'); });

if(sigSave) sigSave.addEventListener('click', ()=>{
  // Ambil PNG transparan
  signatureDataUrl = sigCanvas.toDataURL('image/png');
  // Overlay ke foto pratinjau
  const c=$('#preview'); if(!c){ closeSigModal(); return; }
  const ctx=c.getContext('2d');
  const sigImg=new Image();
  sigImg.onload=()=>{
    const margin=24;
    const sigW=Math.min(sigImg.width, Math.floor(c.width*0.35));
    const ratio=sigW/sigImg.width;
    const sigH=sigImg.height*ratio;
    const x=c.width - sigW - margin;
    const y=c.height - sigH - margin;
    ctx.fillStyle='rgba(255,255,255,.55)';
    ctx.fillRect(x-10, y-6, sigW+20, sigH+12); // background baca
    ctx.drawImage(sigImg, x, y, sigW, sigH);
    lastPhotoDataUrl=c.toDataURL('image/jpeg',0.92);
    const sigPrev=$('#sigPreview'); if(sigPrev){ sigPrev.src=signatureDataUrl; sigPrev.classList.remove('hidden'); }
    closeSigModal();
    showAlert('TTD tersimpan & ditempel ke foto.','success');
  };
  sigImg.src=signatureDataUrl;
});

/* ========= Alur Foto -> Signature ========= */
if(btnCapture) btnCapture.addEventListener('click', ()=>{
  const v=videoEl, c=$('#preview'); if(!v||!c) return;
  const ctx=c.getContext('2d');
  c.width=v.videoWidth||1280; c.height=v.videoHeight||960;
  ctx.setTransform(1,0,0,1,0,0);
  ctx.drawImage(v,0,0,c.width,c.height);
  c.classList.remove('hidden');
  lastPhotoDataUrl=c.toDataURL('image/jpeg',0.92);
  // buka modal tanda tangan
  openSigModal();
  // tutup kamera supaya hemat baterai
  closeCam();
});

/* ========= Balik pratinjau ========= */
const flipBtn=$('#btnFlipCanvas');
if(flipBtn) flipBtn.addEventListener('click', ()=>{
  const c=$('#preview'); if(!c||c.classList.contains('hidden')) return;
  const ctx=c.getContext('2d'); const img=new Image();
  img.onload=()=>{
    ctx.clearRect(0,0,c.width,c.height);
    ctx.translate(c.width,0); ctx.scale(-1,1);
    ctx.drawImage(img,0,0,c.width,c.height);
    ctx.setTransform(1,0,0,1,0,0);
    // Jika sudah ada TTD, tempel lagi di kanan bawah
    if(signatureDataUrl){
      const sig=new Image(); sig.onload=()=>{
        const margin=24;
        const sigW=Math.min(sig.width, Math.floor(c.width*0.35));
        const ratio=sigW/sig.width;
        const sigH=sig.height*ratio;
        const x=c.width - sigW - margin;
        const y=c.height - sigH - margin;
        ctx.fillStyle='rgba(255,255,255,.55)';
        ctx.fillRect(x-10, y-6, sigW+20, sigH+12);
        ctx.drawImage(sig, x, y, sigW, sigH);
        lastPhotoDataUrl=c.toDataURL('image/jpeg',0.92);
      };
      sig.src=signatureDataUrl;
    }else{
      lastPhotoDataUrl=c.toDataURL('image/jpeg',0.92);
    }
  };
  img.src=c.toDataURL('image/jpeg',0.92);
});

/* ========= Nama -> Quip + TTS (24 kalimat per pegawai) ========= */
const QUIP = {
  'Bu Annisa': [
    "Bu Annisa, klawu-nya udah siap wangi, sekarang giliran semangatnya yang wangi juga 😄",
    "Hari ini misi kita: bikin ruangan secerah senyum Bu Annisa yang selalu glowing ✨",
    "Kalau lelah, ingat: senyum Bu Annisa bisa nge-charge satu PKBM penuh ⚡",
    "Checklist pagi: ngopi, klawu rapi, dan senyum manis ala Bu Annisa 😌",
    "Yang paling konsisten itu: klawu wangi dan semangat Bu Annisa yang nggak ada obatnya 😎",
    "Kalau ada penghargaan 'Glow Up of The Day', pasti jatuh ke Bu Annisa duluan 💅",
    "Hari ini jangan lupa: wangi dulu, baru ngantor, biar aura positifnya nyebar kemana-mana 🌈",
    "Kalau klawu bisa bicara, pasti dia bilang: ‘Terima kasih sudah dirawat sepenuh hati, Bu’ 🫶",
    "Senyum Bu Annisa itu kayak soft filter Instagram, bikin suasana auto lembut 💖",
    "Target hari ini: kerja rapi, klawu rapi, hati pun ikut rapi, ya Bu ✨",
    "Kalau capek, tarik napas pelan, senyum tipis, ingat: banyak yang terbantu dari kerja tulus Bu Annisa 🤍",
    "Hari ini cocok buat sambil selipin doa di sela-sela kerja: semoga semua urusan dimudahkan 🙏",
    "Meja boleh penuh kerjaan, tapi jangan lupa hati tetap lapang ya Bu 😊",
    "Aura Bu Annisa hari ini: 80% wangi, 20% gemesin, 100% produktif 💪",
    "Biar lembur pun, yang penting hati tetap ringan dan niatnya tetap lillahita'ala 🤍",
    "Jangan lupa selipin candaan kecil hari ini, biar klawu dan tim sama-sama happy 😄",
    "Kalau mood mulai turun, coba ingat hasil kerja Bu Annisa yang sudah bantu banyak orang 🌟",
    "Senyum Bunda hari ini bisa jadi obat buat yang lagi down di kantor, jangan pelit senyum ya 😁",
    "Hari ini cocok buat upgrade: klawu makin rapi, sistem makin tertib, hati makin tenang ✨",
    "Setiap klik dan coretan administrasi itu jadi bagian dari pahala jariah juga loh, Bu 🤍",
    "Kalau ada yang tanya semangat itu bentuknya apa, jawab saja: “mirip Bu Annisa pagi-pagi” 🌞",
    "Kerja boleh serius, tapi jangan lupa selipin sedikit gaje biar nggak tegang terus 😜",
    "Hari ini klawu senyum, admin senyum, dan tentu saja Bu Annisa yang paling manis senyumnya 💐",
    "Tandai hari ini sebagai hari produktif versi Bu Annisa: pelan-pelan tapi pasti beres satu-satu ✅"
  ],
  'Bu Dian': [
    "Bu Dian, plastik laundry-nya taruh dulu, sekarang fokus absen dulu baru ngaspal kerjaan 😆",
    "Hari ini misinya: bukan cuma baju yang kinclong, tapi juga laporan yang cling tanpa noda 🧺✨",
    "Kalau ada lomba lipat kerjaan tercepat, Bu Dian pasti juara satu tanpa babak tambahan 🥇",
    "Jangan lupa senyum, Bu, biar suasana kantor nggak kalah harum sama pewangi laundry 😌",
    "Tiap ketik di HP atau laptop, bayangin aja lagi nimbang pahala juga, bukan cuma nimbang cucian 🤍",
    "Hari ini cocok buat moto: 'Kerjaan rapi, hidup pun lebih tertata' 📦",
    "Laundry boleh banyak, tapi semangat Bu Dian selalu lebih banyak lagi 💪",
    "Kalau capek, bayangin semua yang terbantu oleh tangan-tangan sibuk Bu Dian di balik layar 🌟",
    "Plastik boleh berkeresek-keresek, tapi hati tetap harus anteng dan adem ya Bu 😄",
    "Hari ini, mari buktikan kalau multitasking bukan mitos—apalagi buat Bu Dian 😎",
    "Jangan lupa selipin candaan receh ke rekan kerja, biar beban berasa tinggal setengah 😁",
    "Kerjaan yang rapi itu kayak baju yang baru disetrika, enak dipandang dan bikin lega 👕",
    "Kalau lagi mumet, tarik napas, senyum, terus bilang: 'Bismillah, satu-satu dulu' ✨",
    "Walau tangan sibuk, semoga hati tetap tenang dan pikiran tetap jernih ya Bu 🤍",
    "Hari ini cocok buat sambil pasang playlist favorit biar kerja berasa dance tipis-tipis 🎶",
    "Ingat, Bu: istirahat sebentar itu bukan malas, tapi bagian dari strategi biar tetap kuat 💆‍♀️",
    "Kalau ada yang bisa bikin cucian dan kerjaan kelar sekaligus, itu pasti Bu Dian 😄",
    "Jangan remehkan satu tugas kecil, semuanya kumpul jadi gunung pahala juga nantinya 🌼",
    "Hari ini semangatnya jangan cuma 2x lipat, tapi 3x lipat kayak promo laundry kilat 😜",
    "Kalau hati mulai riweh, coba pelan-pelan beresin satu hal yang bisa selesai duluan ✅",
    "Setumpuk kerjaan bisa kelar, apalagi cuma setumpuk baju—Bu Dian mah santai 😎",
    "Senyum Bu Dian hari ini bisa jadi iklan layanan masyarakat: 'Kerja boleh banyak, bahagia jangan lupa' 📢",
    "Hari ini cocok buat nyicil hal-hal kecil yang sering ketunda, pelan tapi jalan ✨",
    "Yang penting bukan seberapa capeknya hari ini, tapi seberapa tulus niatnya, ya Bu 🤍"
  ],
  'Mrs Linda': [
    "Bunda Paud Linda, rambut kuncir siap tempur, hati lembut siap memeluk dunia kecil mereka 🌈",
    "Hari ini misi: bikin suasana belajar hangat, kayak pelukan Bunda ke anak-anak PAUD 🤗",
    "Kalau tawa anak-anak terdengar, berarti Bunda Linda lagi berhasil bikin hari mereka bahagia 😄",
    "Rambut kuncir boleh sederhana, tapi sabarnya nggak ada tandingan ✨",
    "Hari ini cocok buat banyak pujian kecil ke anak-anak, biar percaya diri mereka naik pelan-pelan 🌱",
    "Setiap nyanyi lagu anak, diam-diam Bunda juga lagi nanam kenangan manis di hati mereka 🎶",
    "Kalau dunia punya pahlawan tanpa jubah, salah satunya ya Bunda Paud kayak Mrs Linda 💖",
    "Capek sedikit nggak apa-apa, nanti terbayar kalau lihat mereka berani, mandiri, dan ramah 🤍",
    "Hari ini mungkin penuh rewel, tapi di balik itu ada hati kecil yang lagi belajar merasa aman 😊",
    "Kalau kelas ramai, anggap saja itu tanda anak-anak merasa nyaman sama Bundanya 😄",
    "Satu pelukan, satu senyum, satu pujian—semua itu bisa jadi cerita besar buat mereka nanti 🌟",
    "Hari ini cocok buat ajarin mereka antri, berbagi, dan bilang terima kasih dengan ceria 🙌",
    "Jangan lupa, Bunda: yang Bunda bentuk bukan cuma kemampuan, tapi juga karakter mereka 💫",
    "Di balik noda krayon di meja, ada kreativitas yang lagi tumbuh dan mekar 🌼",
    "Kalau ada yang nangis, Bunda Linda tahu: kadang mereka cuma butuh ditemani sebentar 💕",
    "Hari ini adalah kesempatan lagi untuk jadi 'rumah kedua' buat mereka yang kecil-kecil itu 🏠",
    "Suara lembut Bunda mungkin terdengar biasa, tapi di telinga mereka rasanya menenangkan 🫶",
    "Kalau lelah, ingat bahwa nanti mereka besar sambil cerita: 'Aku punya Bunda Paud yang baik banget' 🥹",
    "Hari ini cocok buat bikin satu momen lucu yang bisa dikenang seminggu penuh 😆",
    "Setiap coretan di buku gambar mereka adalah langkah kecil menuju percaya diri 😊",
    "Bunda Linda, senyum Bunda bisa jadi alasan mereka mau datang lagi besok ke kelas 💛",
    "Walaupun gajinya mungkin nggak sefantastis CEO, tapi pahala dan jejaknya lebih panjang dari itu 🤍",
    "Hari ini jangan lupa doa: semoga semua anak diberi masa kecil yang bahagia dan aman ✨",
    "Satu hari lagi mendampingi mereka tumbuh—terima kasih sudah kuat sejauh ini, Bunda 💐"
  ],
  'Miss Natasya': [
    "Miss Natasya, calon pengantin baru—tapi hari ini tetap calon guru paling sabar dulu ya 😆",
    "Hari ini misi: bukan cuma ngajar materi, tapi juga ngasih ketenangan lewat senyum Miss 😊",
    "Kalau murid-murid heboh, anggap saja itu latihan sabar sebelum menghadapi hebohnya panitia nikahan 😜",
    "Hari ini cocok buat gaya ala guru kece: tegas, lembut, dan sedikit julid manja yang sehat 😎",
    "Ingat, Miss: setiap penjelasan yang sabar bisa jadi 'klik' di kepala mereka suatu hari nanti 💡",
    "Kalau ada yang nanya ulang-ulang, tarik napas sebentar, lalu jawab lagi dengan versi lebih simpel 🤍",
    "Hari ini bagus buat latihan: suara tetap lembut, tapi tetap berwibawa di depan kelas 💼",
    "Calon pengantin boleh sibuk, tapi calon guru favorit tetap nomor satu di hati muridnya 💖",
    "Kalau murid mulai ngantuk, saatnya keluarkan jurus humor receh ala Miss Natasya 😂",
    "Hari ini mungkin capek, tapi di situ juga banyak pahala sabar yang dikumpulin pelan-pelan 🌱",
    "Setiap tugas yang dikumpulkan adalah bukti bahwa Miss nggak lelah mengingatkan dan membimbing ✨",
    "Kalau hati mulai penuh, coba tulis satu hal yang bikin Miss bersyukur hari ini 🤍",
    "Jangan lupa, Miss: murid-murid mungkin lupa materi, tapi mereka jarang lupa guru yang baik 💛",
    "Hari ini cocok buat latihan ngomong pelan tapi ngena, biar kelas tetap kondusif 😌",
    "Kalau lagi pusing, ingat: suatu hari murid-murid ini akan bilang, 'Syukurlah dulu diajar Miss Natasya' 🥹",
    "Suara Miss hari ini bisa jadi bedanya kelas biasa dengan kelas yang bikin mereka semangat 🎤",
    "Calon pengantin yang sabar di kelas, insyaAllah lebih siap sabar dalam rumah tangga juga 😄",
    "Jangan lupa senyum ke cermin sebelum berangkat, biar mood ngajarnya ikut cerah 🌞",
    "Hari ini bagus untuk kasih apresiasi kecil ke murid yang berusaha, meski nilainya belum tinggi 🌟",
    "Kalau lagi overthinking, jeda sebentar, tarik napas, lalu fokus ke satu tugas di depan mata ✅",
    "Ingat, Miss: guru yang baik itu bukan yang sempurna, tapi yang mau terus belajar bareng murid 🤝",
    "Hari ini bisa jadi hari biasa, tapi bisa juga jadi hari yang murid ingat selamanya karena sikap Miss 💫",
    "Senyum Miss bisa bikin kelas yang sumpek jadi sedikit lebih lega dan hangat 😊",
    "Terima kasih sudah hadir hari ini, walau capek dan banyak hal di kepala—itu bentuk cinta juga 💐"
  ]
};

const nameSel = $('#name');
if(nameSel) nameSel.addEventListener('change', ()=>{
  const name = nameSel.value;
  const el = $('#nameMotivation'); 
  if(!el) return;

  if(!name){
    el.classList.add('hidden');
    el.textContent = '';
    return;
  }

  let text = "Semangat ya!";
  const arr = QUIP[name];
  if (arr && arr.length){
    const d = new Date();
    // index berdasarkan tanggal (biar tiap hari bisa beda tapi rapi)
    const idx = (d.getFullYear() + d.getMonth() + d.getDate()) % arr.length;
    text = arr[idx];
  }

  el.textContent = text;
  el.classList.remove('hidden');
  speak(`${name}, ${nicknameLine(name)}`);
});


/* ========= Absen Masuk ========= */
let deviceModel='', devicePretty='';
async function finalizeIn(){
  const name=$('#name')?.value?.trim()||'';
  if(!name) return showAlert('Pilih nama dulu ya.','error');
  if(!lastPhotoDataUrl) return showAlert('Ambil foto dulu ya.','error');
  if(!signatureDataUrl) return showAlert('Selesaikan tanda tangan lalu klik "Simpan TTD".','error');

  if(!deviceModel){
    const info=await getDeviceInfo();
    devicePretty=info.pretty; deviceModel=info.model;
  }

  const now=new Date();
  const lateStr = computeLateStr(name, now);
  const rName=$('#rName'), rDate=$('#rDate'), rTime=$('#rTime'), rLate=$('#rLate'), rDev=$('#rDev'), img=$('#rPhoto');
  if(rName) rName.textContent=name;
  if(rDate) rDate.textContent=toDateStrID(now);
  if(rTime) rTime.textContent=toTimeStr(now);
  if(rLate) rLate.textContent=lateStr;
  if(rDev) rDev.textContent=deviceModel;
  if(img){ img.src=lastPhotoDataUrl; img.classList.remove('hidden'); }

  try{
    const res = await fetch(API_URL, {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      body: JSON.stringify({
        action: 'save_checkin',
        name,
        date_key: ymd(now),
        time_str: toTimeStr(now),
        late_minutes: lateStr === '0' ? 0 : parseInt(lateStr,10) || 0,
        device_model: deviceModel,
        ua: navigator.userAgent || '',
        photo_b64: lastPhotoDataUrl,      // disimpan hanya utk Miss Natasya
        signature_b64: signatureDataUrl   // disimpan utk semua
      })
    }).then(r=>r.json());

    if(!res.ok){ showAlert(res.error||'Gagal menyimpan ke server.','error'); return; }
    showAlert('✅ Absen masuk terekam di server.','success');

    const m = $('#filterMonth')?.value || defaultMonthValue();
    await loadHistoryByMonth(m);
  }catch(e){
    showAlert('Gagal konek server: '+e.message,'error');
  }

  const waText=encodeURIComponent([
    'ABSENSI MASUK',
    `Nama Pegawai : ${name}`,
    `Tanggal : ${toDateStrID(now)}`,
    `Waktu Absen : ${toTimeStr(now)}`,
    `Keterlambatan : ${lateStr}`,
    `Model HP : ${deviceModel}`,
  ].join('\n'));
  const waBtn=$('#waSend'); if(waBtn) waBtn.href=`https://wa.me/6285700090006?text=${waText}`;
}
const btnIn=$('#btnIn'); if(btnIn) btnIn.addEventListener('click', finalizeIn);

/* ========= Simpan Gambar / PDF ========= */
const btnImg=$('#btnImg'), btnPdf=$('#btnPdf');
if(btnImg) btnImg.addEventListener('click', async ()=>{
  const node=$('#receiptWrap'); if(!node) return;
  const canvas=await html2canvas(node,{scale:2,backgroundColor:null});
  const a=document.createElement('a');
  a.download=`absen_masuk_${Date.now()}.png`;
  a.href=canvas.toDataURL('image/png');
  a.click();
});
if(btnPdf) btnPdf.addEventListener('click', async ()=>{
  const { jsPDF }=window.jspdf;
  const node=$('#receiptWrap'); if(!node) return;
  const canvas=await html2canvas(node,{scale:2,backgroundColor:'#ffffff'});
  const imgData=canvas.toDataURL('image/jpeg',0.95);
  const pdf=new jsPDF({orientation:'p',unit:'pt',format:'a4'});
  const pageW=pdf.internal.pageSize.getWidth(), pageH=pdf.internal.pageSize.getHeight();
  const ratio=Math.min(pageW/canvas.width, pageH/canvas.height);
  const w=canvas.width*ratio, h=canvas.height*ratio;
  const x=(pageW-w)/2, y=(pageH-h)/2;
  pdf.addImage(imgData,'JPEG',x,y,w,h);
  pdf.save(`absen_masuk_${Date.now()}.pdf`);
});

/* ========= Riwayat per-bulan ========= */
function defaultMonthValue(){
  const d=new Date();
  return `${d.getFullYear()}-${fmt2(d.getMonth()+1)}`;
}

let LAST_ROWS = [];
let LAST_STATS = [];

/* ========= Kerajinan (Analisis Kedisiplinan) ========= */
function computeKerajinanStats(rows){
  const map = {};
  rows.forEach(r=>{
    const name = r.name || '';
    if(!name) return;
    if(!map[name]) map[name] = { name, days:0, late:0 };
    map[name].days += 1;
    map[name].late += (r.late_minutes || 0);
  });
  const stats = Object.values(map).map(s=>{
    let score = 100;
    if(s.days > 0){
      score = 100 - (s.late / s.days);
    }
    if(score < 0) score = 0;
    if(score > 100) score = 100;
    s.score = parseFloat(score.toFixed(2));
    return s;
  });
  stats.sort((a,b)=>b.score - a.score);
  return stats;
}

function teksApresiasiKerajinan(score){
  const s = parseFloat(score);
  if(s >= 95) return "🌟 Sangat disiplin! Pertahankan ya!";
  if(s >= 85) return "👍 Bagus! Terus tingkatkan kedisiplinannya.";
  if(s >= 70) return "⏳ Cukup, tapi perlu lebih konsisten hadir tepat waktu.";
  return "⚠️ Harap meningkatkan kedisiplinan. Tetap semangat!";
}

function updateKerajinanDropdown(stats){
  const sel = document.getElementById('filterName');
  if(!sel) return;
  const current = sel.value;
  sel.innerHTML = '<option value="">-- pilih nama --</option>';
  stats.forEach(s=>{
    const opt = document.createElement('option');
    opt.value = s.name;
    opt.textContent = s.name;
    sel.appendChild(opt);
  });
  if(current){
    sel.value = current;
  }
  if(!sel.value && stats.length > 0){
    sel.value = stats[0].name;
  }
}

function updateKerajinanSummary(){
  const sel = document.getElementById('filterName');
  const box = document.getElementById('kerajinanSummary');
  if(!sel || !box){
    return;
  }
  const name = sel.value;
  if(!name){
    box.innerHTML = '<span class="text-xs text-slate-500">Pilih nama pegawai/tutor untuk melihat tingkat kerajinan pribadi.</span>';
    return;
  }
  const stat = (LAST_STATS || []).find(s=>s.name === name);
  if(!stat){
    box.innerHTML = `<span class="text-xs text-slate-500">Belum ada data absensi bulan ini untuk <b>${name}</b>.</span>`;
    return;
  }
  let cls = 'bg-rose-50 text-rose-800 border-rose-200';
  if(stat.score >= 95) cls = 'bg-emerald-50 text-emerald-800 border-emerald-200';
  else if(stat.score >= 85) cls = 'bg-amber-50 text-amber-800 border-amber-200';
  const pesan = teksApresiasiKerajinan(stat.score);
  box.innerHTML = `
    <div class="mt-2 p-3 rounded-xl border text-sm ${cls}">
      <div><b>${stat.name}</b></div>
      <div class="mt-1">Tingkat kerajinan bulan ini: <b>${stat.score}%</b></div>
      <div class="text-xs mt-1">Total hari absen: ${stat.days} • Total terlambat: ${stat.late} menit</div>
      <div class="mt-2">${pesan}</div>
    </div>
  `;
}

function drawKerajinanChart(stats){
  const canvas = document.getElementById('kerajinanChart');
  if(!canvas) return;
  const ctx = canvas.getContext('2d');
  if(!ctx){
    return;
  }
  const rect = canvas.getBoundingClientRect();
  const dpr = window.devicePixelRatio || 1;
  canvas.width = rect.width * dpr;
  canvas.height = rect.height * dpr;
  ctx.setTransform(1,0,0,1,0,0);
  ctx.scale(dpr, dpr);
  const width = rect.width;
  const height = rect.height;
  ctx.clearRect(0,0,width,height);

  if(!stats || stats.length === 0){
    ctx.fillStyle = '#94a3b8';
    ctx.font = '12px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI"';
    ctx.fillText('Belum ada data kerajinan untuk bulan ini.', 10, 20);
    return;
  }

  const paddingLeft = 40;
  const paddingRight = 10;
  const paddingTop = 10;
  const paddingBottom = 40;
  const maxScore = 100;
  const areaWidth = width - paddingLeft - paddingRight;
  const areaHeight = height - paddingTop - paddingBottom;
  const barSpace = stats.length > 0 ? areaWidth / stats.length : 0;
  const barWidth = Math.max(12, barSpace * 0.5);

  stats.forEach((s, idx)=>{
    const x = paddingLeft + idx * barSpace + (barSpace - barWidth)/2;
    const h = (s.score / maxScore) * areaHeight;
    const y = paddingTop + (areaHeight - h);
    let color = '#f97373';
    if(s.score >= 95) color = '#22c55e';
    else if(s.score >= 85) color = '#facc15';

    ctx.fillStyle = color;
    if(typeof ctx.roundRect === 'function'){
      ctx.beginPath();
      ctx.roundRect(x, y, barWidth, h, 4);
      ctx.fill();
    }else{
      ctx.fillRect(x, y, barWidth, h);
    }

    ctx.fillStyle = '#0f172a';
    ctx.font = '10px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI"';
    ctx.textAlign = 'center';
    ctx.fillText(Math.round(s.score) + '%', x + barWidth/2, y - 4);

    const label = s.name.length > 8 ? s.name.slice(0,7) + '…' : s.name;
    ctx.save();
    ctx.translate(x + barWidth/2, height - paddingBottom + 10);
    ctx.rotate(-Math.PI / 4);
    ctx.fillText(label, 0, 0);
    ctx.restore();
  });

  ctx.strokeStyle = '#cbd5f5';
  ctx.lineWidth = 1;
  ctx.beginPath();
  ctx.moveTo(paddingLeft, paddingTop);
  ctx.lineTo(paddingLeft, height - paddingBottom);
  ctx.lineTo(width - paddingRight, height - paddingBottom);
  ctx.stroke();
}

function renderTop5(stats){
  const tbody = document.getElementById('top5Body');
  if(!tbody) return;
  tbody.innerHTML = '';
  if(!stats || stats.length === 0){
    tbody.innerHTML = '<tr><td colspan="4" class="py-1 text-slate-500">Belum ada data.</td></tr>';
    return;
  }
  const top = stats.slice(0,5);
  top.forEach((s, idx)=>{
    let badgeClass = 'bg-rose-50 text-rose-800';
    if(s.score >= 95) badgeClass = 'bg-emerald-50 text-emerald-800';
    else if(s.score >= 85) badgeClass = 'bg-amber-50 text-amber-800';
    tbody.insertAdjacentHTML('beforeend', `
      <tr>
        <td class="py-1 pr-2 text-slate-800">${idx+1}. ${s.name}</td>
        <td class="py-1 pr-2">
          <span class="inline-flex items-center px-2 py-0.5 rounded-full text-[11px] ${badgeClass}">
            ${s.score}% 
          </span>
        </td>
        <td class="py-1 pr-2 text-slate-700">${s.days} hari</td>
        <td class="py-1 text-slate-700">${s.late} menit</td>
      </tr>
    `);
  });
}

async function loadHistoryByMonth(yyyyMM){
  const title = document.getElementById('listTitle');
  const tbody = document.getElementById('historyBody');
  const empty = document.getElementById('historyEmpty');
  if(tbody) tbody.innerHTML='';

  try{
    const res = await fetch(API_URL, {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      body: JSON.stringify({ action:'list_by_month', month: yyyyMM })
    }).then(r=>r.json());

    if(!res.ok){ if(empty){ empty.classList.remove('hidden'); empty.textContent = res.error || 'Gagal memuat riwayat.'; } return; }
    const rows = res.data || [];
    if(rows.length===0){ if(empty){ empty.classList.remove('hidden'); empty.textContent='Belum ada data untuk bulan ini.'; } return; }
    if(empty) empty.classList.add('hidden');

    LAST_ROWS = rows;
    LAST_STATS = computeKerajinanStats(rows);
    updateKerajinanDropdown(LAST_STATS);
    drawKerajinanChart(LAST_STATS);
    updateKerajinanSummary();
    renderTop5(LAST_STATS);


    rows.sort((a,b)=>(b.ts||0)-(a.ts||0));
    if(title) title.textContent = `Daftar Absensi — ${yyyyMM}`;
    let no=1;
    rows.forEach(r=>{
      const tr=document.createElement('tr');
      const ttdCell = r.signature_path
        ? `<span class="ttd-print">Ada</span><img src="${r.signature_path}" alt="TTD" class="ttd-img h-6 inline-block align-middle rounded bg-white/80 px-1 py-0.5 border ml-1" />`
        : `<span class="ttd-print">-</span>-`;
      tr.innerHTML = `
        <td class="px-3 py-2 border-b">${no++}</td>
        <td class="px-3 py-2 border-b">${r.date_key}</td>
        <td class="px-3 py-2 border-b">${r.time_str}</td>
        <td class="px-3 py-2 border-b">${r.name}</td>
        <td class="px-3 py-2 border-b">${r.late_minutes||0}</td>
        <td class="px-3 py-2 border-b">${r.device_model||'-'}</td>
        <td class="px-3 py-2 border-b">${ttdCell}</td>
      `;
      if(tbody) tbody.appendChild(tr);
    });
  }catch(e){
    if(empty){ empty.classList.remove('hidden'); empty.textContent = 'Gagal memuat riwayat.'; }
  }
}


const btnLoadMonth=document.getElementById('btnLoadMonth');
if(btnLoadMonth) btnLoadMonth.addEventListener('click', ()=>{
  const m=document.getElementById('filterMonth')?.value;
  if(!m) return showAlert('Pilih bulan dulu.','error');
  loadHistoryByMonth(m);
});

const filterNameEl=document.getElementById('filterName');
if(filterNameEl){
  filterNameEl.addEventListener('change', ()=>{
    updateKerajinanSummary();
  });
}

const btnPrint=document.getElementById('btnPrint');
if(btnPrint) btnPrint.addEventListener('click', ()=>window.print());

/* ========= onload ========= */
window.addEventListener('load', ()=>{
  const mCtrl=document.getElementById('filterMonth');
  if(mCtrl) mCtrl.value = defaultMonthValue();
  loadHistoryByMonth(defaultMonthValue());
  openCam();
});
</script>
</body>
</html>
