import { requireSession, panelApiFetch, apiFetch, getQueryParam } from "../app.js?v=20251104";
let SESSION = null;

/* ===== STATE & CONFIG ===== */
const activeBrand = (getQueryParam("brand") || "tiara").toLowerCase();
const REQUIRED_SCOPE_PAGE = "laporan";
const brandLogoMap = {
  tiara: "assets/img/tiaratoto.png",
  tts:  "assets/img/totosakti.png",
  ttm:  "assets/img/totomantap.png", // pastikan file ini ada
};
const brandBadgeText = { tiara:"TIARATOTO", tts:"TOTOSAKTI", ttm:"TOTOMANTAP" }[activeBrand] || "BRAND";
const brandHeaderText = { tiara:"TIARATOTO", tts:"TOTOSAKTI", ttm:"TOTOMANTAP" };

/* ===== RBAC utils (copied) ===== */
function normalizeScopes(src){
  if (Array.isArray(src)) return src.map(String).map(s=>s.trim().toLowerCase()).filter(Boolean);
  if (src && typeof src === "object") return Object.keys(src).filter(k => !!src[k]).map(k=>k.toLowerCase());
  if (typeof src === "string") return src.split(/[,\s]+/).map(s=>s.trim().toLowerCase()).filter(Boolean);
  return [];
}
function scopeForHref(href){
  if (!href) return null;
  if (href.includes("withdraw-awd")) return "auto_wd";
  if (href.includes("pendingan") || href.includes("mistake")) return "laporan";
  if (href.includes("global.html") || href.includes("brand.html") || href.includes("profile-edit.html")) return "brand";
  if (href.includes("bank.html") || href.includes("ewallet.html") || href.includes("pulsa.html") || href.includes("wd.html")) return "proses";

  // ✅ NEW: scope untuk menu Notifikasi
  if (href.includes("notifbank") || href.includes("notifewallet")) return "notifikasi";

  return null;
}
function hasScope(name, { isSuperadmin, scopes }){ if (isSuperadmin) return true; return scopes.includes((name||"").toLowerCase()); }

/* ===== DOM refs ===== */
const els = {
  desktopLogo: document.getElementById("desktopBrandLogo"),
  mobileLogo:  document.getElementById("mobileBrandLogo"),
  sideMenuDesktop: document.getElementById("sideMenuDesktop"),
  sideMenuMobile:  document.getElementById("sideMenuMobile"),
  brandLabel: document.getElementById("brandLabel"),
  brandDropdown: document.getElementById("brandDropdown"),
  brandBtn: document.getElementById("brandBtn"),
  userBtn: document.getElementById("userMenuBtn"),
  userDropdown: document.getElementById("userDropdown"),
  topUser: document.getElementById("topUser"),
  themeToggleBtn: document.getElementById("themeToggleBtn"),
  logoutBtn: document.getElementById("logoutBtn"),
  hamburgerBtn: document.getElementById("hamburgerBtn"),
  mobileSidebar: document.getElementById("mobileSidebar"),
  closeSidebarBtn: document.getElementById("closeSidebarBtn"),
  sidebarOverlay: document.getElementById("sidebarOverlay"),
  pageTitle: document.getElementById("pageTitle"),
  brandBadge: document.getElementById("brandBadge"),
  pageDesc: document.getElementById("pageDesc"),

  // toolbar
  tglBtn: document.getElementById("tglBtn"),
  tglBtnText: document.getElementById("tglBtnText"),
  tglCalHost: document.getElementById("tglCalHost"),

  btnPDP: document.getElementById("btnPDP"),
  btnPWD: document.getElementById("btnPWD"),
  btnPALL: document.getElementById("btnPALL"),
  countInfo: document.getElementById("countInfo"),

  // tables + totals
  tbodyPDP: document.getElementById("tbodyPDP"),
  tbodyPWD: document.getElementById("tbodyPWD"),
  leftInfoPDP: document.getElementById("leftInfoPDP"),
  leftInfoPWD: document.getElementById("leftInfoPWD"),
  sumPDP: document.getElementById("sumPDP"),
  sumPWD: document.getElementById("sumPWD"),

  // modal
  modal: document.getElementById("modal"),
  modalTitle: document.getElementById("modalTitle"),
  modalBody: document.getElementById("modalBody"),
  modalClose: document.getElementById("modalClose"),

  // forbidden
  forbiddenOverlay: document.getElementById("forbiddenOverlay"),
  forbiddenTitle: document.getElementById("forbiddenTitle"),
  forbiddenDesc: document.getElementById("forbiddenDesc"),
  goHomeBtnText: document.getElementById("goHomeBtnText"),
  brandPickerWrap: document.getElementById("brandPickerWrap"),
};

/* ===== icons + sidebar (active: Pendingan) ===== */
function iconSVG(name){
  if(name==="home") return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M3 12L12 3l9 9"/><path d="M9 21V12h6v9"/></svg>`;
  if(name==="sheets") return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="3" y1="10" x2="21" y2="10"/><line x1="9" y1="4" x2="9" y2="22"/></svg>`;
  if(name==="brand")  return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><circle cx="19" cy="12" r="3"/><circle cx="5" cy="12" r="3"/></svg>`;
  if(name==="profile")return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>`;
  if(name==="chat")   return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M21 15a4 4 0 0 1-4 4H7l-4 4V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z"/></svg>`;
  if(name==="users")  return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>`;
  if(name==="report") return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M9 3h6a2 2 0 0 1 2 2v16l-5-3-5 3V5a2 2 0 0 1 2-2z"/></svg>`;
  if(name==="zap")    return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><polyline points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>`;

  // ✅ NEW: icon Notifikasi
  if(name==="bank")   return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M3 10h18"/><path d="M5 10v10"/><path d="M9 10v10"/><path d="M15 10v10"/><path d="M19 10v10"/><path d="M4 20h16"/><path d="M12 3l9 5H3l9-5z"/></svg>`;
  if(name==="wallet") return `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v3"/><path d="M21 12h-7a2 2 0 0 0 0 4h7v-4z"/><circle cx="16" cy="14" r="1"/></svg>`;

  return "";
}

const brandMap = {
  tiara: {
    sections: [
      { label: "Dashboard", items: [{ text:"Dashboard", href:`index.html?brand=tiara`, icon:"home", active:false }] },
      {
        label: null,
        items: [
          { text:"Global Sheets", href:`global.html?brand=tiara`, icon:"sheets", active:false },
          { text:"Brand Meta",   href:`brand.html?brand=tiara`,  icon:"brand",  active:false },
          { text:"Profiles", href:null, icon:"profile", active:false, submenu: [
            { text:"Edit Bank",    channel:"bank" },
            { text:"Edit Ewallet", channel:"ewallet" },
            { text:"Edit Pulsa",   channel:"pulsa" },
            { text:"Edit Withdraw",channel:"wd" },
          ]},
        ],
      },
      { label: "Proses", items: [
        { text:"Catat Bank",     href:`bank.html?brand=tiara`,    icon:"chat", active:false },
        { text:"Catat Ewallet",  href:`ewallet.html?brand=tiara`, icon:"chat", active:false },
        { text:"Catat Pulsa",    href:`pulsa.html?brand=tiara`,   icon:"chat", active:false },
        { text:"Catat Withdraw", href:`wd.html?brand=tiara`,      icon:"chat", active:false },
      ]},

      // ✅ NEW: NOTIFIKASI (RBAC: scope "notifikasi")
      { label: "Notifikasi", items: [
        { text:"Bank",    href:`notifbank.html?brand=tiara`,    icon:"bank",   active:false },
        { text:"Ewallet", href:`notifewallet.html?brand=tiara`, icon:"wallet", active:false },
      ]},

      { label: "Laporan", items: [
        { text:"Pendingan", href:`pendingan.html?brand=tiara`, icon:"report", active:true },
        { text:"Mistake",   href:`mistake.html?brand=tiara`,   icon:"report", active:false },
      ]},
      { label: "Auto Withdraw", items: [
        { text:"Withdraw", href:`withdraw-awd.html?brand=tiara`, icon:"zap", active:false },
      ]},
      { label: "Admin", items: [
        { text:"Users", href:`users.html?brand=tiara`, icon:"users", active:false, requireSuperadmin:true },
      ]},
    ],
  },
  tts: {
    sections: [
      { label: "Dashboard", items: [{ text:"Dashboard", href:`index.html?brand=tts`, icon:"home", active:false }] },
      {
        label: null,
        items: [
          { text:"Global Sheets", href:`global.html?brand=tts`, icon:"sheets", active:false },
          { text:"Brand Meta",   href:`brand.html?brand=tts`,  icon:"brand",  active:false },
          { text:"Profiles", href:null, icon:"profile", active:false, submenu: [
            { text:"Edit Bank",    channel:"bank" },
            { text:"Edit Ewallet", channel:"ewallet" },
            { text:"Edit Pulsa",   channel:"pulsa" },
            { text:"Edit Withdraw",channel:"wd" },
          ]},
        ],
      },
      { label: "Proses", items: [
        { text:"Catat Bank",     href:`bank.html?brand=tts`,    icon:"chat", active:false },
        { text:"Catat Ewallet",  href:`ewallet.html?brand=tts`, icon:"chat", active:false },
        { text:"Catat Pulsa",    href:`pulsa.html?brand=tts`,   icon:"chat", active:false },
        { text:"Catat Withdraw", href:`wd.html?brand=tts`,      icon:"chat", active:false },
      ]},

      // ✅ NEW: NOTIFIKASI (RBAC: scope "notifikasi")
      { label: "Notifikasi", items: [
        { text:"Bank",    href:`notifbank.html?brand=tts`,    icon:"bank",   active:false },
        { text:"Ewallet", href:`notifewallet.html?brand=tts`, icon:"wallet", active:false },
      ]},

      { label: "Laporan", items: [
        { text:"Pendingan", href:`pendingan.html?brand=tts`, icon:"report", active:true },
        { text:"Mistake",   href:`mistake.html?brand=tts`,   icon:"report", active:false },
      ]},
      { label: "Auto Withdraw", items: [
        { text:"Withdraw", href:`withdraw-awd.html?brand=tts`, icon:"zap", active:false },
      ]},
      { label: "Admin", items: [
        { text:"Users", href:`users.html?brand=tts`, icon:"users", active:false, requireSuperadmin:true },
      ]},
    ],
  },
  ttm: {
    sections: [
      { label: "Dashboard", items: [{ text:"Dashboard", href:`index.html?brand=ttm`, icon:"home", active:false }] },
      {
        label: null,
        items: [
          { text:"Global Sheets", href:`global.html?brand=ttm`, icon:"sheets", active:false },
          { text:"Brand Meta",   href:`brand.html?brand=ttm`,  icon:"brand",  active:false },
          { text:"Profiles", href:null, icon:"profile", active:false, submenu: [
            { text:"Edit Bank",    channel:"bank" },
            { text:"Edit Ewallet", channel:"ewallet" },
            { text:"Edit Pulsa",   channel:"pulsa" },
            { text:"Edit Withdraw",channel:"wd" },
          ]},
        ],
      },
      { label: "Proses", items: [
        { text:"Catat Bank",     href:`bank.html?brand=ttm`,    icon:"chat", active:false },
        { text:"Catat Ewallet",  href:`ewallet.html?brand=ttm`, icon:"chat", active:false },
        { text:"Catat Pulsa",    href:`pulsa.html?brand=ttm`,   icon:"chat", active:false },
        { text:"Catat Withdraw", href:`wd.html?brand=ttm`,      icon:"chat", active:false },
      ]},

      // ✅ NEW: NOTIFIKASI (RBAC: scope "notifikasi")
      { label: "Notifikasi", items: [
        { text:"Bank",    href:`notifbank.html?brand=ttm`,    icon:"bank",   active:false },
        { text:"Ewallet", href:`notifewallet.html?brand=ttm`, icon:"wallet", active:false },
      ]},

      { label: "Laporan", items: [
        { text:"Pendingan", href:`pendingan.html?brand=ttm`, icon:"report", active:true },
        { text:"Mistake",   href:`mistake.html?brand=ttm`,   icon:"report", active:false },
      ]},
      { label: "Auto Withdraw", items: [
        { text:"Withdraw", href:`withdraw-awd.html?brand=ttm`, icon:"zap", active:false },
      ]},
      { label: "Admin", items: [
        { text:"Users", href:`users.html?brand=ttm`, icon:"users", active:false, requireSuperadmin:true },
      ]},
    ],
  },
};

function sidebarClockCard(prefix){return `
  <div class="mb-4">
    <div class="rounded-lg border border-slate-300 dark:border-[#3f3f46] bg-slate-50 dark:bg-[#2a2a2a] text-[12px] leading-tight text-slate-700 dark:text-slate-200 p-3">
      <div class="grid grid-cols-[max-content_1ch_1fr] items-baseline gap-x-2 gap-y-1">
        <div class="text-slate-500 dark:text-slate-400 font-medium">Tanggal</div><div class="text-slate-500 dark:text-slate-400">:</div><div id="sidebarDate${prefix}" class="font-semibold">-</div>
        <div class="text-slate-500 dark:text-slate-400 font-medium">Waktu</div><div class="text-slate-500 dark:text-slate-400">:</div><div id="sidebarTime${prefix}" class="font-semibold">-</div>
      </div>
    </div>
  </div>`}
function updateSidebarClock(){
  const now=new Date();
  const weekdayId=new Intl.DateTimeFormat('id-ID',{timeZone:'Asia/Jakarta',weekday:'long'}).format(now);
  const parts=new Intl.DateTimeFormat('en-US',{timeZone:'Asia/Jakarta',year:'numeric',month:'numeric',day:'2-digit',hour:'2-digit',minute:'2-digit',second:'2-digit',hour12:false}).formatToParts(now);
  let dd="",mm="",yyyy="",hh="",mi="",ss=""; parts.forEach(p=>{if(p.type==="day")dd=p.value;if(p.type==="month")mm=p.value;if(p.type==="year")yyyy=p.value;if(p.type==="hour")hh=p.value;if(p.type==="minute")mi=p.value;if(p.type==="second")ss=p.value;});
  const bulanShort=["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agu","Sep","Okt","Nov","Des"];
  const tanggalStr=`${weekdayId}, ${dd} ${bulanShort[parseInt(mm,10)-1]||mm} ${yyyy}`; const waktuStr=`${hh}:${mi}:${ss}`;
  ["Desktop","Mobile"].forEach(pref=>{ const d=document.getElementById("sidebarDate"+pref); const t=document.getElementById("sidebarTime"+pref); if(d) d.textContent=tanggalStr; if(t) t.textContent=waktuStr; });
}
function renderSidebar(brandKey,prefix,opts={}){

  const isSuperadmin=!!opts.isSuperadmin; const scopes=opts.scopes||[];
  const cfg=brandMap[brandKey]||brandMap.tiara;
  const parentActive="bg-blue-50 text-blue-600 border-blue-200 dark:bg-blue-950/40 dark:text-blue-400 dark:border-blue-800";
  const parentNormal="hover:bg-slate-100 hover:text-blue-600 border-transparent text-slate-700 dark:text-slate-200 dark:hover:bg-[#2a2a2a] dark:hover:text-blue-400";
  let html=sidebarClockCard(prefix);
  cfg.sections.forEach(section=>{
    const visible=(section.items||[]).filter(it=>{
      if(it.requireSuperadmin && !isSuperadmin) return false;
      if(it.icon==="profile") return hasScope("brand",{isSuperadmin,scopes});
      const need=scopeForHref(it.href); if(!need) return true; return hasScope(need,{isSuperadmin,scopes});
    });
    if(!visible.length) return;
    const title = (typeof section.label === "string" && section.label.length)
      ? section.label.toUpperCase()
      : (brandHeaderText[brandKey] || "BRAND");
    html+=`<div class="mb-4"><div class="text-[11px] uppercase font-semibold text-slate-400 dark:text-slate-500 tracking-wide mb-2">${title}</div><ul class="space-y-1">`;
    visible.forEach(item=>{
      if(item.icon==="profile"){
        html+=`
          <li>
            <button id="profilesToggle${prefix}" class="w-full flex items-center justify-between px-3 py-2 rounded-md font-medium border ${parentNormal}">
              <span class="flex items-center gap-2">${iconSVG(item.icon)}<span>${item.text}</span></span>
              <span class="text-slate-500 dark:text-slate-400"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" data-chevron class="transition-transform"><polyline points="6 9 12 15 18 9"/></svg></span>
            </button>
            <ul id="profilesSub${prefix}" class="mt-1 ml-6 space-y-1 hidden">
              ${(item.submenu||[]).map(sub=>`
                <li>
                  <a href="profile-edit.html?brand=${brandKey}&channel=${sub.channel}" class="flex items-center gap-2 px-3 py-2 rounded-md font-medium border text-[12px] leading-tight ${parentNormal}">
                    <span class="w-2 h-2 rounded-full bg-current"></span><span>${sub.text}</span>
                  </a>
                </li>`).join("")}
            </ul>
          </li>`;
      } else {
        const linkCls=item.active?parentActive:parentNormal;
        html+=`<li><a href="${item.href}" class="flex items-center gap-2 px-3 py-2 rounded-md font-medium border ${linkCls}">${iconSVG(item.icon)}<span>${item.text}</span></a></li>`;
      }
    });
    html+=`</ul></div>`;
  });
  return html;
}
function attachSidebarToggle(prefix){
  const btn=document.getElementById("profilesToggle"+prefix);
  const sub=document.getElementById("profilesSub"+prefix);
  if(!btn||!sub) return; btn.addEventListener("click",()=>{ sub.classList.toggle("hidden"); const chev=btn.querySelector("[data-chevron]"); if(chev) chev.classList.toggle("rotate-180"); });
}

/* ===== Static apply ===== */
function applyStatic(session){
  const logo=brandLogoMap[activeBrand]||brandLogoMap.tiara;
  const badge=brandBadgeText;
  els.desktopLogo.src=logo; els.desktopLogo.alt=badge;
  els.mobileLogo.src=logo;  els.mobileLogo.alt=badge;
  els.brandLabel.textContent=badge;
  els.brandBadge.textContent=badge;

  // teks statis (tanpa i18n)
  els.pageTitle.textContent = "Laporan Pendingan";
  els.pageDesc.textContent = "Laporan pendingan deposit & withdraw.";
  els.forbiddenTitle.textContent = "Akses Ditolak";
  els.forbiddenDesc.textContent = "Halaman ini memerlukan scope: laporan.";
  els.goHomeBtnText.textContent = "Ke Dashboard";

  els.brandBtn.addEventListener("click",(e)=>{ e.stopPropagation(); els.brandDropdown.classList.toggle("hidden"); if(!els.userDropdown.classList.contains("hidden")) els.userDropdown.classList.add("hidden"); });
  els.userBtn.addEventListener("click",(e)=>{ e.stopPropagation(); els.userDropdown.classList.toggle("hidden"); if(!els.brandDropdown.classList.contains("hidden")) els.brandDropdown.classList.add("hidden"); });
  els.themeToggleBtn.addEventListener("click",()=>{ const root=document.documentElement; const isDark=root.classList.toggle("dark"); localStorage.setItem("theme", isDark?"dark":"light"); });

  function openMobile(){ els.mobileSidebar.classList.remove("-translate-x-full"); els.sidebarOverlay.classList.remove("hidden"); }
  function closeMobile(){ els.mobileSidebar.classList.add("-translate-x-full"); els.sidebarOverlay.classList.add("hidden"); }
  els.hamburgerBtn.addEventListener("click",(e)=>{ e.stopPropagation(); openMobile(); });
  els.closeSidebarBtn.addEventListener("click", closeMobile);
  els.sidebarOverlay.addEventListener("click", closeMobile);

  document.addEventListener("click",(e)=>{
    if(!els.brandDropdown.classList.contains("hidden")){
      if(!document.getElementById("brandPickerWrap").contains(e.target)) els.brandDropdown.classList.add("hidden");
    }
    if(!els.userDropdown.classList.contains("hidden")){
      if(!els.userBtn.contains(e.target) && !els.userDropdown.contains(e.target)) els.userDropdown.classList.add("hidden");
    }
  });

  els.topUser.textContent = session?.username || "admin";
}
function applySidebar(isSuperadmin, scopes){
  els.sideMenuDesktop.innerHTML = renderSidebar(activeBrand,"Desktop",{isSuperadmin,scopes});
  els.sideMenuMobile.innerHTML  = renderSidebar(activeBrand,"Mobile",{isSuperadmin,scopes});
  attachSidebarToggle("Desktop"); attachSidebarToggle("Mobile");
  updateSidebarClock(); setInterval(updateSidebarClock,1000);
}
function showForbiddenOverlay(){ els.forbiddenOverlay.classList.remove("hidden"); }

/* ===== helpers ===== */
const bulanIndo=["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"];
function toRupiah(n){ return "Rp " + new Intl.NumberFormat('id-ID').format(Number(n||0)); }
function parseAmount(v){ const s=String(v||"").replace(/[^\d]/g,""); return s?parseInt(s,10):0; }
const STATE = { selectedDateDDMMYYYY:"" };

/* ===== data ===== */
let RAW_PDP=[], RAW_PWD=[];
let VIEW_PDP=[], VIEW_PWD=[];
let IS_LOADING = false;

/* ===== render ===== */
function renderTables(){
  const effectiveDate = STATE.selectedDateDDMMYYYY;

  // Loading state: spinner di tengah tabel
  if (IS_LOADING) {
    els.tbodyPDP.innerHTML = `
      <tr>
        <td colspan="5" class="px-3 py-8">
          <div class="flex items-center justify-center gap-3 text-[13px] text-slate-500 dark:text-slate-400">
            <div class="h-5 w-5 rounded-full border-2 border-slate-300 dark:border-slate-600 border-t-blue-500 dark:border-t-blue-400 animate-spin"></div>
            <span>Memuat pendingan…</span>
          </div>
        </td>
      </tr>`;
    els.tbodyPWD.innerHTML = `
      <tr>
        <td colspan="6" class="px-3 py-8">
          <div class="flex items-center justify-center gap-3 text-[13px] text-slate-500 dark:text-slate-400">
            <div class="h-5 w-5 rounded-full border-2 border-slate-300 dark:border-slate-600 border-t-blue-500 dark:border-t-blue-400 animate-spin"></div>
            <span>Memuat pendingan…</span>
          </div>
        </td>
      </tr>`;
    els.leftInfoPDP.textContent = "Memuat data deposit…";
    els.leftInfoPWD.textContent = "Memuat data withdraw…";
    // Biarkan countInfo tetap "Memuat…" dari fetchAndRender
    return;
  }

  VIEW_PDP = RAW_PDP.filter(row => !effectiveDate || row.tanggal === effectiveDate);
  VIEW_PWD = RAW_PWD.filter(row => !effectiveDate || row.tanggal === effectiveDate);

  const sumPDP = VIEW_PDP.reduce((a,b)=>a+parseAmount(b.nominal),0);
  const sumPWD = VIEW_PWD.reduce((a,b)=>a+parseAmount(b.nominal),0);
  els.sumPDP.textContent = toRupiah(sumPDP);
  els.sumPWD.textContent = toRupiah(sumPWD);

  els.countInfo.textContent = `Menampilkan ${VIEW_PDP.length + VIEW_PWD.length} data (DP: ${VIEW_PDP.length}, WD: ${VIEW_PWD.length})`;

  // Tabel Deposit: data / empty state
  if (VIEW_PDP.length === 0) {
    els.tbodyPDP.innerHTML = `
      <tr>
        <td colspan="5" class="px-3 py-8 text-center text-[13px] text-slate-400 dark:text-slate-500 italic">
          Pendingan belum tersedia
        </td>
      </tr>`;
  } else {
    els.tbodyPDP.innerHTML = VIEW_PDP.map(r=>`
      <tr class="border-b border-slate-100 dark:border-[#1f2933] hover:bg-slate-50/80 dark:hover:bg-[#18181b]">
        <td class="px-3 py-2 whitespace-nowrap">${r.tanggal}</td>
        <td class="px-3 py-2 whitespace-nowrap">${r.jam||"-"}</td>
        <td class="px-3 py-2 whitespace-nowrap">${r.nama||"-"}</td>
        <td class="px-3 py-2 whitespace-nowrap">${r.bank_sheet||"-"}</td>
        <td class="px-3 py-2 text-right tabular-nums font-semibold">${toRupiah(parseAmount(r.nominal))}</td>
      </tr>`).join("");
  }

  // Tabel Withdraw: data / empty state
  if (VIEW_PWD.length === 0) {
    els.tbodyPWD.innerHTML = `
      <tr>
        <td colspan="6" class="px-3 py-8 text-center text-[13px] text-slate-400 dark:text-slate-500 italic">
          Pendingan belum tersedia
        </td>
      </tr>`;
  } else {
    els.tbodyPWD.innerHTML = VIEW_PWD.map(r=>`
      <tr class="border-b border-slate-100 dark:border-[#1f2933] hover:bg-slate-50/80 dark:hover:bg-[#18181b]">
        <td class="px-3 py-2 whitespace-nowrap">${r.tanggal}</td>
        <td class="px-3 py-2 whitespace-nowrap">${r.bank_sheet||"-"}</td>
        <td class="px-3 py-2 whitespace-nowrap font-semibold">${r.op||"-"}</td>
        <td class="px-3 py-2 whitespace-nowrap">${r.user_id||"-"}</td>
        <td class="px-3 py-2">${r.nama_rek||"-"}</td>
        <td class="px-3 py-2 text-right tabular-nums font-semibold">${toRupiah(parseAmount(r.nominal))}</td>
      </tr>`).join("");
  }

  els.leftInfoPDP.textContent = `Deposit: ${VIEW_PDP.length} baris`;
  els.leftInfoPWD.textContent = `Withdraw: ${VIEW_PWD.length} baris`;
}

/* ===== Date helpers & Calendar (copy) ===== */
function ddmmyyyy(d){ const dd=String(d.getDate()).padStart(2,'0'); const mm=String(d.getMonth()+1).padStart(2,'0'); const yy=d.getFullYear(); return `${dd}/${mm}/${yy}`; }
function todayWIB_DDMMYYYY(){ const now=new Date(); return ddmmyyyy(new Date(now.getTime()+7*3600*1000)); }
/* mini calendar dropdown */
function mountCalendarDropdown(host, anchorBtn, onPick, initialDDMMYYYY = ""){
  const old=host.querySelector("[data-calwrap]"); if(old) old.remove();
  let cur = (()=>{ if(/^\d{2}\/\d{2}\/\d{4}$/.test(initialDDMMYYYY)){ const [dd,mm,yy]=initialDDMMYYYY.split("/").map(n=>parseInt(n,10)); return new Date(yy,mm-1,dd);} return new Date();})();
  let viewY=cur.getFullYear(), viewM=cur.getMonth();
  const wrap=document.createElement("div"); wrap.setAttribute("data-calwrap","1");
  wrap.className="absolute z-[90] mt-2 w-72 rounded-xl border border-slate-200 dark:border-[#2a2a2a] bg-white dark:bg-[#1e1e1e] shadow-2xl";
  wrap.style.left="0"; wrap.style.top="calc(100% + 6px)";
  wrap.innerHTML=`
    <div class="flex items-center justify-between px-3 py-2 border-b border-slate-200 dark:border-[#2a2a2a]">
      <button type="button" data-nav="-1" class="p-2 rounded-md border border-slate-300 dark:border-[#3f3f46] hover:bg-slate-100 dark:hover:bg-[#2a2a2a]">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
      </button>
      <div class="font-semibold text-[13px]" data-ttl></div>
      <button type="button" data-nav="1" class="p-2 rounded-md border border-slate-300 dark:border-[#3f3f46] hover:bg-slate-100 dark:hover:bg-[#2a2a2a]">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
      </button>
    </div>
    <div class="grid grid-cols-7 gap-1 p-3" data-grid>
      ${["Min","Sen","Sel","Rab","Kam","Jum","Sab"].map(s=>`<div class="text-[11px] text-slate-500 dark:text-slate-400 text-center">${s}</div>`).join("")}
    </div>
    <div class="flex items-center justify-between px-3 py-2 border-t border-slate-200 dark:border-[#2a2a2a]">
      <button type="button" data-act="clear" class="text-[12px] font-medium px-2 py-1 rounded-md border border-slate-300 dark:border-[#3f3f46] hover:bg-slate-100 dark:hover:bg-[#2a2a2a]">Hapus</button>
      <button type="button" data-act="today" class="text-[12px] font-medium px-2 py-1 rounded-md border border-slate-300 dark:border-[#3f3f46] hover:bg-slate-100 dark:hover:bg-[#2a2a2a]">Hari ini</button>
    </div>`;
  host.appendChild(wrap);
  const grid=wrap.querySelector("[data-grid]"); const ttl=wrap.querySelector("[data-ttl]");
  function ddmmyyyy2(d){ const dd=String(d.getDate()).padStart(2,"0"); const mm=String(d.getMonth()+1).padStart(2,"0"); const yy=d.getFullYear(); return `${dd}/${mm}/${yy}`; }
  function renderDays(){
    while(grid.children.length>7) grid.removeChild(grid.lastChild);
    const first=new Date(viewY,viewM,1); const startDow=first.getDay(); const daysPrev=new Date(viewY,viewM,0).getDate(); const daysCur=new Date(viewY,viewM+1,0).getDate();
    for(let i=startDow-1;i>=0;i--){ const d=daysPrev-i; const el=document.createElement("div"); el.className="text-[13px] h-8 rounded-md flex items-center justify-center select-none text-slate-400 dark:text-slate-500"; el.textContent=String(d); grid.appendChild(el); }
    for(let d=1; d<=daysCur; d++){ const el=document.createElement("div"); el.className="text-[13px] h-8 rounded-md flex items-center justify-center cursor-pointer select-none hover:bg-slate-100 dark:hover:bg-[#2a2a2a]"; el.textContent=String(d);
      const picked=(cur.getFullYear()===viewY && cur.getMonth()===viewM && cur.getDate()===d); if(picked) el.classList.add("bg-blue-600","text-white");
      el.addEventListener("click",()=>{ cur=new Date(viewY,viewM,d); onPick(ddmmyyyy2(cur)); close(); }); grid.appendChild(el); }
    const cells=grid.children.length; const pad=(cells%7===0)?0:(7-(cells%7)); for(let i=1;i<=pad;i++){ const el=document.createElement("div"); el.className="text-[13px] h-8 rounded-md flex items-center justify-center select-none text-slate-400 dark:text-slate-500"; el.textContent=String(i); grid.appendChild(el); }
    ttl.textContent = `${bulanIndo[viewM]} ${viewY}`;
  }
  function close(){ wrap.remove(); document.removeEventListener("click",outside); document.removeEventListener("keydown",esc); }
  function outside(e){ if(!wrap.contains(e.target) && e.target !== anchorBtn) close(); }
  function esc(e){ if(e.key==="Escape") close(); }
  wrap.querySelectorAll("[data-nav]").forEach(btn=>{ btn.addEventListener("click",()=>{ viewM += parseInt(btn.getAttribute("data-nav"),10); if(viewM<0){viewM=11;viewY--;} if(viewM>11){viewM=0;viewY++;} renderDays(); }); });
  wrap.querySelector("[data-act='clear']").addEventListener("click",()=>{ onPick(""); close(); });
  wrap.querySelector("[data-act='today']").addEventListener("click",()=>{ onPick(todayWIB_DDMMYYYY()); close(); });
  renderDays(); setTimeout(()=>{ document.addEventListener("click",outside); document.addEventListener("keydown",esc); },0);
}

/* ===== API ===== */
async function fetchAndRender(tgl){
  IS_LOADING = true;
  els.countInfo.textContent = "Memuat…";
  renderTables();

  try{
    const qs = tgl ? `&tanggal=${encodeURIComponent(tgl)}` : "";
    const resp = await panelApiFetch(`/api/report/pendingan/list?brand=${activeBrand}${qs}`);
    if (resp?.ok === false) {
      IS_LOADING = false;
      RAW_PDP=[]; RAW_PWD=[];
      renderTables();
      els.countInfo.textContent = `Gagal memuat (HTTP ${resp?._httpStatus || "?"})`;
      openModal("Gagal Memuat", String(resp?.error || "Unknown error"));
      return;
    }
    const dp = Array.isArray(resp?.dp) ? resp.dp : [];
    const wd = Array.isArray(resp?.wd) ? resp.wd : [];
    RAW_PDP = dp.map(x=>({ tanggal:x.tanggal, jam:x.jam, nama:x.nama, bank_sheet:x.bank_sheet, nominal:x.nominal }));
    RAW_PWD = wd.map(x=>({ tanggal:x.tanggal, bank_sheet:x.bank_sheet, op:x.op, user_id:x.user_id, nama_rek:x.nama_rek, nominal:x.nominal }));
    IS_LOADING = false;
    renderTables();
    // tidak ada lagi teks "Data siap."
  }catch(e){
    console.error(e);
    IS_LOADING = false;
    RAW_PDP=[]; RAW_PWD=[];
    renderTables();
    els.countInfo.textContent = "Gagal memuat data.";
  }
}

async function postPindahkan(jenis){
  const tgl = STATE.selectedDateDDMMYYYY || todayWIB_DDMMYYYY();
  const btns=[els.btnPDP,els.btnPWD,els.btnPALL].filter(Boolean);
  btns.forEach(b=>{ b.disabled=true; b.classList.add("opacity-60","pointer-events-none"); });
  try{
    const r = await panelApiFetch(`/api/report/pendingan/pindah`, {
      method:"POST",
      json:{ brand: activeBrand, tanggal: tgl, jenis },
      timeoutMs: 120_000,
    });
    if (r?.ok === false) { openModal("Gagal", String(r?.error || `HTTP ${r?._httpStatus||"?"}`)); return; }
    const text = r?.text || r?.message || (r?.busy ? "Sedang diproses oleh job lain…" : `OK. ${jenis.toUpperCase()} untuk ${tgl} diproses.`);
    openModal("Hasil", String(text));
    await fetchAndRender(tgl);
  } catch(e){
    openModal("Gagal", "Terjadi kesalahan saat pindahkan: " + (e?.message || e));
  } finally {
    btns.forEach(b=>{ b.disabled=false; b.classList.remove("opacity-60","pointer-events-none"); });
  }
}

/* ===== Modal ===== */
function openModal(title, body){ els.modalTitle.textContent=title||"Detail"; els.modalBody.textContent=body||"—"; els.modal.classList.remove("hidden"); els.modal.classList.add("flex"); }
function closeModal(){ els.modal.classList.add("hidden"); els.modal.classList.remove("flex"); }
els.modalClose.addEventListener("click", closeModal);
els.modal.addEventListener("click",(e)=>{ if(e.target===els.modal) closeModal(); });

/* ===== Boot ===== */
(async function init(){
  const session = await requireSession();
  SESSION=session;
  const isSuperadmin = (session?.role === "superadmin");
  const scopes = normalizeScopes(session?.scopes ?? session?.permissions ?? session?.perms ?? session?.scope_map);

  applySidebar(isSuperadmin, scopes);
  applyStatic(session);
  if (!hasScope(REQUIRED_SCOPE_PAGE, { isSuperadmin, scopes })) { showForbiddenOverlay(); return; }

  // Calendar toolbar (tanggal utama)
  function setToolbarDate(ddmmyyyyStr){
    STATE.selectedDateDDMMYYYY = ddmmyyyyStr || todayWIB_DDMMYYYY();
    els.tglBtnText.textContent = STATE.selectedDateDDMMYYYY || "hh/bb/tttt";
    fetchAndRender(STATE.selectedDateDDMMYYYY);
  }
  els.tglBtn.addEventListener("click",(e)=>{
    e.stopPropagation();
    mountCalendarDropdown(els.tglCalHost, els.tglBtn, (val)=> setToolbarDate(val || todayWIB_DDMMYYYY()), STATE.selectedDateDDMMYYYY || todayWIB_DDMMYYYY());
  });

  // Actions
  els.btnPDP.addEventListener("click", ()=>postPindahkan("dp"));
  els.btnPWD.addEventListener("click", ()=>postPindahkan("wd"));
  els.btnPALL.addEventListener("click",()=>postPindahkan("all"));

  // initial date (today WIB) & load
  setToolbarDate(todayWIB_DDMMYYYY());

  // Logout
  els.logoutBtn?.addEventListener("click", async ()=>{ try{ await apiFetch("/api/logout",{method:"POST"});}catch(_){} window.location="login.html"; });
})();