// assets/js/global.js
import {
  requireSession,
  apiFetch,
  getQueryParam,
  brandDisplayName,
  showFlash
} from "../app.js";

//
// --- TEXT (BAHASA INDONESIA SAJA) ---
// (tidak ada fitur switch bahasa, tidak pakai localStorage "lang")
//
const TEXT = {
  dropdownTheme: "Tema",
  dropdownLogout: "Keluar",

  pageTitleGlobalSheets: "Global Sheets",
  brandDescPrefix: "Maping semua sumber spreadsheet brand ",

  formTitle: "Tambah Global Spreadsheet",
  fieldSheetName: "Sheet Rekening",
  fieldSheetNameHint: "contoh: BCA1_RINI",
  fieldSpreadsheetId: "Spreadsheet ID",
  fieldSpreadsheetReq: "wajib",
  fieldGid: "GID",
  fieldGidOpt: "boleh kosong",
  btnSave: "Simpan",
  btnClear: "Clear Form",

  // NEW: kategori
  catBankDepo: "BANK DEPO",
  catEwallet: "E-WALLET",
  catPulsa: "PULSA",
  catBankWd: "BANK WD",
  catHintPrefix: "Tab aktif: ",
  modalFieldCategory: "Kategori Table",
  tableTitlePrefix: "Tabel",

  tableName: "Nama",
  tableSid: "Spreadsheet ID",
  tableGid: "GID",
  tableAction: "Aksi",

  tableEmpty: "Belum ada sumber",
  tableEmptyCat: "Belum ada sumber pada kategori ini.",
  actionEdit: "Edit",
  actionDelete: "Hapus",

  modalTitleEdit: "Edit Sheet Mapping",
  modalCancel: "Batal",
  modalSave: "Simpan",
  modalFieldName: "Sheet Rekening",
  modalFieldSpreadsheetId: "Spreadsheet ID",
  modalFieldGid: "GID",
  modalFieldNameHint: "contoh: BCA1_RINI",

  menuDashboard: "Dashboard",
  menuGlobalSheets: "Global Sheets",
  menuBrandMeta: "Brand Meta",
  menuProfiles: "Profiles",
  submenuProfilesBank: "Edit Bank",
  submenuProfilesEwallet: "Edit Ewallet",
  submenuProfilesPulsa: "Edit Pulsa",
  submenuProfilesWD: "Edit Withdraw",

  menuProses: "Proses",
  depBank: "Catat Bank",
  depEwallet: "Catat Ewallet",
  depPulsa: "Catat Pulsa",
  depWD: "Catat Withdraw",

  // ✅ NEW: Notifikasi (RBAC)
  menuNotifikasi: "Notifikasi",
  notifBank: "Bank",
  notifEwallet: "Ewallet",

  menuUsers: "Users",

  menuLaporan: "Laporan",
  repPendingan: "Pendingan",
  repMistake: "Mistake",

  menuAutoWD: "Auto Withdraw",
  awdWithdraw: "Withdraw",

  menuAdmin: "Admin",
};

//
// --- STATE DASAR ---
//
const activeBrand   = (getQueryParam("brand") || "tiara").toLowerCase();
const activeChannel = ""; // halaman global gak sedang edit channel profile tertentu

// DEFAULT RBAC SCOPES (sama dengan brand.html)
// ✅ tambah notifikasi:false biar bisa dikasih akses / tidak
const DEFAULT_SCOPES = { brand:true, proses:true, laporan:true, autowd:false, users:false, notifikasi:false };

// memory daftar sheets (biar bisa buka modal tanpa fetch lagi)
let currentSheets = {};
// key yg lagi diedit di modal
let editingOriginalKey = null;

// Logo per brand
const brandLogoMap = {
  tiara: "assets/img/tiaratoto.png",
  tts:   "assets/img/totosakti.png",
  ttm:   "assets/img/totomantap.png",
};

//
// ---------------------------
// NEW: CATEGORY (LOCAL ONLY)
// ---------------------------
//
// NOTE:
// - Tidak mengubah endpoint/backend sama sekali
// - Kategori disimpan di localStorage per brand
//
const CATEGORIES = [
  { key:"bank_depo", label: TEXT.catBankDepo },
  { key:"ewallet",   label: TEXT.catEwallet },
  { key:"pulsa",     label: TEXT.catPulsa },
  { key:"bank_wd",   label: TEXT.catBankWd },
];
const DEFAULT_CATEGORY = "bank_depo";

function catMapStorageKey() {
  return `globalSheetsCategory:${activeBrand}`;
}
function activeCatStorageKey() {
  return `globalSheetsActiveCategory:${activeBrand}`;
}
function loadCategoryMap() {
  try {
    const raw = localStorage.getItem(catMapStorageKey());
    if (!raw) return {};
    const obj = JSON.parse(raw);
    return (obj && typeof obj === "object") ? obj : {};
  } catch (e) {
    return {};
  }
}
function saveCategoryMap(map) {
  try { localStorage.setItem(catMapStorageKey(), JSON.stringify(map || {})); } catch (e) {}
}
let categoryMap = loadCategoryMap();

let activeCategory = (()=>{
  try {
    const saved = localStorage.getItem(activeCatStorageKey());
    return saved || DEFAULT_CATEGORY;
  } catch (e) {
    return DEFAULT_CATEGORY;
  }
})();

function getCategoryLabel(catKey){
  const hit = CATEGORIES.find(c=>c.key===catKey);
  return hit ? hit.label : TEXT.catBankDepo;
}
function normalizeCategory(catKey){
  const ok = CATEGORIES.some(c=>c.key===catKey);
  return ok ? catKey : DEFAULT_CATEGORY;
}
function getSheetCategory(name){
  const row = (currentSheets && currentSheets[name]) ? currentSheets[name] : null;
  const fromServer = row && typeof row === "object" ? row.category : null;
  return normalizeCategory(fromServer || categoryMap[name] || DEFAULT_CATEGORY);
}
function setSheetCategory(name, catKey){
  if (!name) return;
  categoryMap[name] = normalizeCategory(catKey);
  saveCategoryMap(categoryMap);
}
function moveSheetCategory(oldName, newName, catKey){
  if (!newName) return;
  // set kategori untuk nama baru
  setSheetCategory(newName, catKey);
  // hapus mapping lama kalau rename
  if (oldName && oldName !== newName) {
    if (Object.prototype.hasOwnProperty.call(categoryMap, oldName)) {
      delete categoryMap[oldName];
      saveCategoryMap(categoryMap);
    }
  }
}
function removeSheetCategory(name){
  if (!name) return;
  if (Object.prototype.hasOwnProperty.call(categoryMap, name)) {
    delete categoryMap[name];
    saveCategoryMap(categoryMap);
  }
}
function setActiveCategory(catKey){
  activeCategory = normalizeCategory(catKey);
  try { localStorage.setItem(activeCatStorageKey(), activeCategory); } catch (e) {}
  renderCategoryTabs();
  renderTable();
}

function countByCategory(){
  const counts = {};
  CATEGORIES.forEach(c=>counts[c.key]=0);
  Object.keys(currentSheets || {}).forEach((name)=>{
    const c = getSheetCategory(name);
    if (counts[c] === undefined) counts[c] = 0;
    counts[c] += 1;
  });
  return counts;
}

//
// Kartu jam & tanggal (WIB) di atas menu sidebar
//
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 text-slate-800 dark:text-slate-100">-</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 text-slate-800 dark:text-slate-100">-</div>
          </div>
        </div>
      </div>
    `;
}

//
// brandMap untuk sidebar + RBAC scope
//
const brandMap = {
  tiara: {
    badge: "TIARATOTO",
    sections: [
      {
        label: TEXT.menuDashboard,
        items: [
          { text: TEXT.menuDashboard, href: `index.html?brand=tiara`, icon: "home", active: false },
        ],
      },
      {
        label: null,
        brandBadge: "TIARATOTO",
        scope: "brand",
        items: [
          { text: TEXT.menuGlobalSheets, href: `global.html?brand=tiara`, icon: "sheets", active: true },
          { text: TEXT.menuBrandMeta,   href: `brand.html?brand=tiara`,  icon: "brand",  active: false },
          {
            text: TEXT.menuProfiles,
            href: null, icon: "profile", active: false,
            submenu: [
              { text: TEXT.submenuProfilesBank,    channel: "bank"    },
              { text: TEXT.submenuProfilesEwallet, channel: "ewallet" },
              { text: TEXT.submenuProfilesPulsa,   channel: "pulsa"   },
              { text: TEXT.submenuProfilesWD,      channel: "wd"      },
            ],
          },
        ],
      },
      {
        label: TEXT.menuProses,
        scope: "proses",
        items: [
          { text: TEXT.depBank,    href: `bank.html?brand=tiara`,    icon: "chat", active: false },
          { text: TEXT.depEwallet, href: `ewallet.html?brand=tiara`, icon: "chat", active: false },
          { text: TEXT.depPulsa,   href: `pulsa.html?brand=tiara`,   icon: "chat", active: false },
          { text: TEXT.depWD,      href: `wd.html?brand=tiara`,      icon: "chat", active: false },
        ],
      },

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

      {
        label: TEXT.menuLaporan,
        scope: "laporan",
        items: [
          { text: TEXT.repPendingan, href: `pendingan.html?brand=tiara`, icon: "report", active: false },
          { text: TEXT.repMistake,   href: `mistake.html?brand=tiara`,   icon: "report", active: false },
        ],
      },
      {
        label: TEXT.menuAutoWD,
        scope: "autowd",
        items: [
          { text: TEXT.awdWithdraw, href: `withdraw-awd.html?brand=tiara`, icon: "zap", active: false },
        ],
      },
      {
        label: TEXT.menuAdmin,
        scope: "users",
        items: [
          { text: TEXT.menuUsers, href: `users.html?brand=tiara`, icon: "users", active: false },
        ],
      },
    ],
  },

  tts: {
    badge: "TOTOSAKTI",
    sections: [
      {
        label: TEXT.menuDashboard,
        items: [
          { text: TEXT.menuDashboard, href: `index.html?brand=tts`, icon: "home", active: false },
        ],
      },
      {
        label: null,
        brandBadge: "TOTOSAKTI",
        scope: "brand",
        items: [
          { text: TEXT.menuGlobalSheets, href: `global.html?brand=tts`, icon: "sheets", active: true },
          { text: TEXT.menuBrandMeta,   href: `brand.html?brand=tts`,  icon: "brand",  active: false },
          {
            text: TEXT.menuProfiles,
            href: null, icon: "profile", active: false,
            submenu: [
              { text: TEXT.submenuProfilesBank,    channel: "bank"    },
              { text: TEXT.submenuProfilesEwallet, channel: "ewallet" },
              { text: TEXT.submenuProfilesPulsa,   channel: "pulsa"   },
              { text: TEXT.submenuProfilesWD,      channel: "wd"      },
            ],
          },
        ],
      },
      {
        label: TEXT.menuProses,
        scope: "proses",
        items: [
          { text: TEXT.depBank,    href: `bank.html?brand=tts`,    icon: "chat", active: false },
          { text: TEXT.depEwallet, href: `ewallet.html?brand=tts`, icon: "chat", active: false },
          { text: TEXT.depPulsa,   href: `pulsa.html?brand=tts`,   icon: "chat", active: false },
          { text: TEXT.depWD,      href: `wd.html?brand=tts`,      icon: "chat", active: false },
        ],
      },

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

      {
        label: TEXT.menuLaporan,
        scope: "laporan",
        items: [
          { text: TEXT.repPendingan, href: `pendingan.html?brand=tts`, icon: "report", active: false },
          { text: TEXT.repMistake,   href: `mistake.html?brand=tts`,   icon: "report", active: false },
        ],
      },
      {
        label: TEXT.menuAutoWD,
        scope: "autowd",
        items: [
          { text: TEXT.awdWithdraw, href: `withdraw-awd.html?brand=tts`, icon: "zap", active: false },
        ],
      },
      {
        label: TEXT.menuAdmin,
        scope: "users",
        items: [
          { text: TEXT.menuUsers, href: `users.html?brand=tts`, icon: "users", active: false },
        ],
      },
    ],
  },

  ttm: {
    badge: "TOTOMANTAP",
    sections: [
      {
        label: TEXT.menuDashboard,
        items: [
          { text: TEXT.menuDashboard, href: `index.html?brand=ttm`, icon: "home", active: false },
        ],
      },
      {
        label: null,
        brandBadge: "TOTOMANTAP",
        scope: "brand",
        items: [
          { text: TEXT.menuGlobalSheets, href: `global.html?brand=ttm`, icon: "sheets", active: true },
          { text: TEXT.menuBrandMeta,   href: `brand.html?brand=ttm`,  icon: "brand",  active: false },
          {
            text: TEXT.menuProfiles,
            href: null, icon: "profile", active: false,
            submenu: [
              { text: TEXT.submenuProfilesBank,    channel: "bank"    },
              { text: TEXT.submenuProfilesEwallet, channel: "ewallet" },
              { text: TEXT.submenuProfilesPulsa,   channel: "pulsa"   },
              { text: TEXT.submenuProfilesWD,      channel: "wd"      },
            ],
          },
        ],
      },
      {
        label: TEXT.menuProses,
        scope: "proses",
        items: [
          { text: TEXT.depBank,    href: `bank.html?brand=ttm`,    icon: "chat", active: false },
          { text: TEXT.depEwallet, href: `ewallet.html?brand=ttm`, icon: "chat", active: false },
          { text: TEXT.depPulsa,   href: `pulsa.html?brand=ttm`,   icon: "chat", active: false },
          { text: TEXT.depWD,      href: `wd.html?brand=ttm`,      icon: "chat", active: false },
        ],
      },

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

      {
        label: TEXT.menuLaporan,
        scope: "laporan",
        items: [
          { text: TEXT.repPendingan, href: `pendingan.html?brand=ttm`, icon: "report", active: false },
          { text: TEXT.repMistake,   href: `mistake.html?brand=ttm`,   icon: "report", active: false },
        ],
      },
      {
        label: TEXT.menuAutoWD,
        scope: "autowd",
        items: [
          { text: TEXT.awdWithdraw, href: `withdraw-awd.html?brand=ttm`, icon: "zap", active: false },
        ],
      },
      {
        label: TEXT.menuAdmin,
        scope: "users",
        items: [
          { text: TEXT.menuUsers, href: `users.html?brand=ttm`, icon: "users", active: false },
        ],
      },
    ],
  },
};

// helper icon svg mini (TIDAK DIUBAH FITURNYA)
function iconSVG(name, highlight=false){
  const baseColor = highlight
    ? "text-blue-500 dark:text-blue-400"
    : "text-slate-500 dark:text-slate-400";

  if(name === "home"){
    return `
        <span class="${highlight ? "text-blue-500 dark:text-blue-400" : "text-slate-500 dark:text-slate-400"}">
          <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>
        </span>
      `;
  }

  if(name === "sheets"){
    return `
        <span class="${baseColor}">
          <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" ry="2"/>
            <line x1="3" y1="10" x2="21" y2="10"/>
            <line x1="9" y1="4" x2="9" y2="22"/>
          </svg>
        </span>
      `;
  }

  if(name === "brand"){
    return `
        <span class="${baseColor}">
          <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>
        </span>
      `;
  }

  if(name === "profile"){
    return `
        <span class="${baseColor}">
          <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>
        </span>
      `;
  }

  if (name === "chat") {
    return `
        <span class="${highlight ? "text-blue-500 dark:text-blue-400" : "text-slate-500 dark:text-slate-400"}">
          <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>
        </span>
      `;
  }

  if (name === "users") {
    return `
        <span class="${baseColor}">
          <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>
        </span>
      `;
  }

  if (name === "report") {
    return `
        <span class="${baseColor}">
          <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>
        </span>
      `;
  }

  if (name === "zap") {
    return `
        <span class="${baseColor}">
          <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>
        </span>
      `;
  }

  // ✅ NEW: icon Notifikasi
  if (name === "bank") {
    return `
      <span class="${baseColor}">
        <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>
      </span>
    `;
  }

  if (name === "wallet") {
    return `
      <span class="${baseColor}">
        <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>
      </span>
    `;
  }

  return "";
}

function renderSidebar(brandKey, prefix, activeChannel, opts = {}) {
  const isSuperadmin = !!opts.isSuperadmin;
  const scopes       = opts.scopes || DEFAULT_SCOPES;
  const cfg = brandMap[brandKey] || brandMap["tiara"];

  const parentActiveCls = "bg-blue-50 text-blue-600 border-blue-200 dark:bg-blue-950/40 dark:text-blue-400 dark:border-blue-800";
  const parentNormalCls = "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 allowByScope = isSuperadmin || !section.scope || (scopes && scopes[section.scope]);
    if (!allowByScope) return;

    const sectionTitle = section.label ? section.label.toUpperCase() : section.brandBadge;

    html += `
        <div class="mb-4">
          <div class="text-[11px] uppercase font-semibold text-slate-400 dark:text-slate-500 tracking-wide mb-2">
            ${sectionTitle}
          </div>
          <ul class="space-y-1">
      `;

    section.items.forEach(item=>{
      if (item.icon === "profile") {
        const highlightParent = !!item.active;
        const btnCls = highlightParent ? parentActiveCls : parentNormalCls;
        const openSub = highlightParent;

        html += `
            <li>
              <button
                id="profilesToggle${prefix}"
                class="w-full flex items-center justify-between px-3 py-2 rounded-md font-medium border ${btnCls}">
                <span class="flex items-center gap-2">
                  ${iconSVG(item.icon, highlightParent)}
                  <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"
                    class="transition-transform ${openSub ? "rotate-180" : ""}"
                    data-chevron>
                    <polyline points="6 9 12 15 18 9"/>
                  </svg>
                </span>
              </button>

              <ul id="profilesSub${prefix}" class="mt-1 ml-6 space-y-1 ${openSub ? "" : "hidden"}">
          `;

        (item.submenu || []).forEach(sub=>{
          const isActiveSub = (sub.channel === activeChannel);
          const subCls = isActiveSub ? parentActiveCls : parentNormalCls;
          html += `
              <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 ${subCls}">
                  <span class="w-2 h-2 rounded-full bg-current"></span>
                  <span>${sub.text}</span>
                </a>
              </li>
            `;
        });

        html += `
              </ul>
            </li>
          `;
      } else {
        const active = !!item.active;
        const linkCls = active ? parentActiveCls : parentNormalCls;

        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, active)}
                <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");
    }
  });
}

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 bulanTxt = bulanShort[parseInt(mm,10)-1] || mm;

  const tanggalStr = `${weekdayId}, ${dd} ${bulanTxt} ${yyyy}`;
  const waktuStr   = `${hh}:${mi}:${ss}`;

  const dateDesktop = document.getElementById("sidebarDateDesktop");
  const timeDesktop = document.getElementById("sidebarTimeDesktop");
  const dateMobile  = document.getElementById("sidebarDateMobile");
  const timeMobile  = document.getElementById("sidebarTimeMobile");

  if (dateDesktop) dateDesktop.textContent = tanggalStr;
  if (timeDesktop) timeDesktop.textContent = waktuStr;
  if (dateMobile)  dateMobile.textContent  = tanggalStr;
  if (timeMobile)  timeMobile.textContent  = waktuStr;
}

const brandBtn          = document.getElementById("brandBtn");
const brandDropdown     = document.getElementById("brandDropdown");
const menuBtn           = document.getElementById("userMenuBtn");
const userDropdown      = document.getElementById("userDropdown");
const themeToggleBtn    = document.getElementById("themeToggleBtn");
const hamburgerBtn      = document.getElementById("hamburgerBtn");
const mobileSidebar     = document.getElementById("mobileSidebar");
const closeSidebarBtn   = document.getElementById("closeSidebarBtn");
const sidebarOverlay    = document.getElementById("sidebarOverlay");
const logoutBtn         = document.getElementById("logoutBtn");

const globalForm        = document.getElementById("globalForm");
const fName             = document.getElementById("f_name");
const fSid              = document.getElementById("f_sid");
const fGid              = document.getElementById("f_gid");
const clearBtn          = document.getElementById("clearBtn");

const catTabsWrap       = document.getElementById("catTabs");
const activeCatHintEl   = document.getElementById("activeCatHint");
const activeCatLabelEl  = document.getElementById("activeCatLabel");
const activeCatCountEl  = document.getElementById("activeCatCount");
const tableTitlePrefixEl= document.getElementById("tableTitlePrefix");

const tbodyEl           = document.getElementById("sheetsRows");

const editOverlay       = document.getElementById("editOverlay");
const modalCloseBtn     = document.getElementById("modalCloseBtn");
const modalCancelBtn    = document.getElementById("modalCancelBtn");
const modalSaveBtn      = document.getElementById("modalSaveBtn");
const modalNameInput    = document.getElementById("modal_name");
const modalSidInput     = document.getElementById("modal_sid");
const modalGidInput     = document.getElementById("modal_gid");
const modalCatSelect    = document.getElementById("modal_cat");
const modalErrorBox     = document.getElementById("modalError");

if (themeToggleBtn) {
  themeToggleBtn.addEventListener("click", (e)=>{
    e.stopPropagation();
    const root = document.documentElement;
    const isDarkNow = root.classList.toggle("dark");
    localStorage.setItem("theme", isDarkNow ? "dark" : "light");
  });
}

if (brandBtn) {
  brandBtn.addEventListener("click", (e) => {
    e.stopPropagation();
    brandDropdown.classList.toggle("hidden");
    if (!userDropdown.classList.contains("hidden")) {
      userDropdown.classList.add("hidden");
    }
  });
}

if (menuBtn) {
  menuBtn.addEventListener("click", (e) => {
    e.stopPropagation();
    userDropdown.classList.toggle("hidden");
    if (!brandDropdown.classList.contains("hidden")) {
      brandDropdown.classList.add("hidden");
    }
  });
}

function openMobileSidebar() {
  mobileSidebar.classList.remove("-translate-x-full");
  sidebarOverlay.classList.remove("hidden");
}

function closeMobileSidebar() {
  mobileSidebar.classList.add("-translate-x-full");
  sidebarOverlay.classList.add("hidden");
}

if (hamburgerBtn) {
  hamburgerBtn.addEventListener("click", (e) => {
    e.stopPropagation();
    openMobileSidebar();
  });
}

if (closeSidebarBtn) {
  closeSidebarBtn.addEventListener("click", () => {
    closeMobileSidebar();
  });
}

if (sidebarOverlay) {
  sidebarOverlay.addEventListener("click", () => {
    closeMobileSidebar();
  });
}

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

  if (!userDropdown.classList.contains("hidden")) {
    if (!menuBtn.contains(e.target) && !userDropdown.contains(e.target)) {
      userDropdown.classList.add("hidden");
    }
  }
});

if (logoutBtn) {
  logoutBtn.addEventListener("click", async (e) => {
    e.preventDefault();
    await apiFetch("/api/logout", { method: "POST" });
    window.location = "login.html";
  });
}

function styleTabButton(btn, isActive){
  if (!btn) return;
  const activeCls = "bg-blue-50 text-blue-700 border-blue-300 dark:bg-blue-900/30 dark:text-blue-300 dark:border-blue-700";
  const normalCls = "bg-slate-50 text-slate-700 border-slate-300 hover:bg-slate-100 dark:bg-[#2a2a2a] dark:text-slate-200 dark:border-[#3f3f46] dark:hover:bg-[#3f3f46]";
  btn.className = `catTab inline-flex items-center gap-2 rounded-md border px-3 py-2 text-[12px] font-semibold ${isActive ? activeCls : normalCls}`;
  const badge = btn.querySelector("span[id^='tabCount']");
  if (badge) {
    badge.className = `text-[11px] font-semibold px-2 py-[1px] rounded-full border ${isActive
      ? "bg-white/60 dark:bg-black/20 border-blue-300 dark:border-blue-700 text-blue-700 dark:text-blue-300"
      : "bg-white/60 dark:bg-black/20 border-slate-300 dark:border-[#3f3f46] text-slate-700 dark:text-slate-200"
    }`;
  }
}

function renderCategoryTabs(){
  if (activeCatHintEl) {
    activeCatHintEl.textContent = TEXT.catHintPrefix + getCategoryLabel(activeCategory);
  }
  if (activeCatLabelEl) {
    activeCatLabelEl.textContent = getCategoryLabel(activeCategory);
  }
  if (tableTitlePrefixEl) {
    tableTitlePrefixEl.textContent = TEXT.tableTitlePrefix;
  }

  const counts = countByCategory();

  const cBankDepo = document.getElementById("tabCountBankDepo");
  const cEwallet  = document.getElementById("tabCountEwallet");
  const cPulsa    = document.getElementById("tabCountPulsa");
  const cBankWd   = document.getElementById("tabCountBankWd");
  if (cBankDepo) cBankDepo.textContent = String(counts.bank_depo || 0);
  if (cEwallet)  cEwallet.textContent  = String(counts.ewallet || 0);
  if (cPulsa)    cPulsa.textContent    = String(counts.pulsa || 0);
  if (cBankWd)   cBankWd.textContent   = String(counts.bank_wd || 0);

  if (catTabsWrap) {
    catTabsWrap.querySelectorAll("button[data-cat]").forEach((btn)=>{
      const c = btn.getAttribute("data-cat");
      styleTabButton(btn, normalizeCategory(c) === activeCategory);
    });
  }
}

function attachCategoryTabs(){
  if (!catTabsWrap) return;
  catTabsWrap.querySelectorAll("button[data-cat]").forEach((btn)=>{
    btn.addEventListener("click", ()=>{
      const cat = btn.getAttribute("data-cat") || DEFAULT_CATEGORY;
      setActiveCategory(cat);
    });
  });
}

function openEditModal(key){
  editingOriginalKey = key;
  const row = currentSheets[key] || {};
  modalNameInput.value = key || "";
  modalSidInput.value  = row.spreadsheet_id || "";
  modalGidInput.value  = (row.gid === null || row.gid === undefined) ? "" : String(row.gid);

  if (modalCatSelect) {
    modalCatSelect.value = getSheetCategory(key);
  }

  modalErrorBox.classList.add("hidden");
  modalErrorBox.textContent = "";
  editOverlay.classList.remove("hidden");
}

function closeEditModal(){
  editOverlay.classList.add("hidden");
  editingOriginalKey = null;
  modalSaveBtn.disabled = false;
  modalSaveBtn.classList.remove("opacity-50","cursor-not-allowed");
}

if (modalCloseBtn) modalCloseBtn.addEventListener("click", closeEditModal);
if (modalCancelBtn) modalCancelBtn.addEventListener("click", closeEditModal);

if (editOverlay) {
  editOverlay.addEventListener("click",(e)=>{
    if (e.target === editOverlay) closeEditModal();
  });
}

if (modalSaveBtn) {
  modalSaveBtn.addEventListener("click", async ()=>{
    modalSaveBtn.disabled = true;
    modalSaveBtn.classList.add("opacity-50","cursor-not-allowed");

    const newName = modalNameInput.value.trim();
    const newSid  = modalSidInput.value.trim();
    const newGid  = modalGidInput.value.trim();
    const newCat  = normalizeCategory(modalCatSelect ? modalCatSelect.value : DEFAULT_CATEGORY);

    if (!newName || !newSid) {
      modalErrorBox.textContent = "Nama sheet & Spreadsheet ID wajib diisi.";
      modalErrorBox.classList.remove("hidden");
      modalSaveBtn.disabled = false;
      modalSaveBtn.classList.remove("opacity-50","cursor-not-allowed");
      return;
    }

    const fd = new FormData();
    fd.set("act", "save");
    fd.set("name", newName);
    fd.set("spreadsheet_id", newSid);
    fd.set("gid", newGid);
    fd.set("original_name", editingOriginalKey || "");
    fd.set("category", newCat);

    const out = await apiFetch(`/api/global/${activeBrand}`, {
      method:"POST",
      body: fd
    });

    if (out.ok) {
      moveSheetCategory(editingOriginalKey, newName, newCat);
      closeEditModal();
      setActiveCategory(newCat);
      await loadData(out.message || "Berhasil disimpan.");
    } else {
      modalErrorBox.textContent = out.error || "Gagal simpan.";
      modalErrorBox.classList.remove("hidden");
      modalSaveBtn.disabled = false;
      modalSaveBtn.classList.remove("opacity-50","cursor-not-allowed");
    }
  });
}

function renderTable(){
  const entriesAll = Object.entries(currentSheets || {}).sort((a,b)=>a[0].localeCompare(b[0]));
  const entries = entriesAll.filter(([name]) => getSheetCategory(name) === activeCategory);

  if (activeCatCountEl) activeCatCountEl.textContent = String(entries.length);
  if (activeCatLabelEl) activeCatLabelEl.textContent = getCategoryLabel(activeCategory);

  if (entries.length === 0) {
    tbodyEl.innerHTML = `
        <tr class="border-b border-slate-200 dark:border-[#2a2a2a] odd:bg-white even:bg-slate-50 dark:odd:bg-[#1e1e1e] dark:even:bg-[#1a1a1a]">
          <td colspan="4" class="text-center text-slate-500 dark:text-slate-400 py-6 text-[13px] bg-white dark:bg-[#1e1e1e]">
            ${TEXT.tableEmptyCat}
          </td>
        </tr>`;
    return;
  }

  tbodyEl.innerHTML = entries.map(([name, row])=>{
    const sid = row.spreadsheet_id || "";
    const gid = (row.gid === null || row.gid === undefined) ? "" : String(row.gid);
    const sheetUrl = sid
      ? `https://docs.google.com/spreadsheets/d/${sid}/edit${gid ? `#gid=${gid}` : ""}`
      : "";
    const sidCell = sid
      ? `<a href="${sheetUrl}" target="_blank" rel="noopener" class="underline decoration-dotted hover:decoration-solid">${sid}</a>`
      : "";

    return `
        <tr class="border-b border-slate-200 dark:border-[#2a2a2a] odd:bg-white even:bg-slate-50 dark:odd:bg-[#1e1e1e] dark:even:bg-[#1a1a1a] align-top">
          <td class="p-3 text-[13px] text-slate-800 dark:text-slate-100 font-semibold break-words">${name}</td>
          <td class="p-3 text-[13px] text-slate-800 dark:text-slate-100 break-words">${sidCell}</td>
          <td class="p-3 text-[13px] text-slate-800 dark:text-slate-100 break-words">${gid}</td>
          <td class="p-3 text-[13px]">
            <div class="flex flex-wrap gap-2">
              <button data-edit="${name}"
                class="flex items-center gap-1 text-[12px] font-medium text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/30 border border-blue-300 dark:border-blue-700 rounded-md px-2 py-1">
                <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"
                  fill="none" stroke="currentColor" stroke-width="1.6"
                  stroke-linecap="round" stroke-linejoin="round"
                  viewBox="0 0 24 24">
                  <path d="M12 20h9"/>
                  <path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z"/>
                </svg>
                <span>${TEXT.actionEdit}</span>
              </button>

              <button data-del="${name}"
                class="flex items-center gap-1 text-[12px] font-medium text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/30 border border-red-300 dark:border-red-700 rounded-md px-2 py-1">
                <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"
                  fill="none" stroke="currentColor" stroke-width="1.6"
                  stroke-linecap="round" stroke-linejoin="round"
                  viewBox="0 0 24 24">
                  <polyline points="3 6 5 6 21 6"/>
                  <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/>
                  <path d="M10 11v6"/>
                  <path d="M14 11v6"/>
                  <path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/>
                </svg>
                <span>${TEXT.actionDelete}</span>
              </button>
            </div>
          </td>
        </tr>
      `;
  }).join("");

  tbodyEl.querySelectorAll("button[data-edit]").forEach((btn)=>{
    btn.addEventListener("click", ()=>{
      const rowKey = btn.getAttribute("data-edit");
      openEditModal(rowKey);
    });
  });

  tbodyEl.querySelectorAll("button[data-del]").forEach((btn)=>{
    btn.addEventListener("click", async ()=>{
      const delName = btn.getAttribute("data-del");
      const fd = new FormData();
      fd.set("act", "delete");
      fd.set("name", delName);

      const out = await apiFetch(`/api/global/${activeBrand}`, {
        method:"POST",
        body: fd
      });

      if (out.ok) {
        removeSheetCategory(delName);
        showFlash("ok", out.message || "Berhasil disimpan.");
        await loadData();
      } else {
        showFlash("err", out.error || "Gagal hapus.");
      }
    });
  });
}

async function loadData(flashMsg = "") {
  const data = await apiFetch(`/api/global/${activeBrand}`);
  if (!data.ok) {
    showFlash("err", data.error || "Gagal load data.");
    return;
  }

  currentSheets = data.sheets || {};

  const newMap = {};
  Object.entries(currentSheets).forEach(([name, row]) => {
    if (row && row.category) newMap[name] = normalizeCategory(row.category);
  });
  categoryMap = newMap;
  saveCategoryMap(categoryMap);

  fName.value = "";
  fSid.value  = "";
  fGid.value  = "";

  renderCategoryTabs();
  renderTable();

  if (flashMsg) showFlash("ok", flashMsg);
  else showFlash("", "");
}

if (globalForm) {
  globalForm.addEventListener("submit", async (e)=>{
    e.preventDefault();
    if (!fName.value.trim() || !fSid.value.trim()) {
      showFlash("err", "Nama sheet & Spreadsheet ID wajib diisi.");
      return;
    }

    const nameForCategory = fName.value.trim();
    const catForNew = activeCategory;

    const fd = new FormData(globalForm);
    fd.set("act", "save");
    fd.set("category", activeCategory);

    const out = await apiFetch(`/api/global/${activeBrand}`, {
      method:"POST",
      body: fd
    });

    if (out.ok) {
      setSheetCategory(nameForCategory, catForNew);

      fName.value = "";
      fSid.value  = "";
      fGid.value  = "";

      await loadData(out.message || "Berhasil disimpan.");
    } else {
      showFlash("err", out.error || "Gagal simpan.");
    }
  });
}

if (clearBtn) {
  clearBtn.addEventListener("click", ()=>{
    fName.value = "";
    fSid.value  = "";
    fGid.value  = "";
    showFlash("", "");
  });
}

function applyStaticTexts() {
  const elTheme = document.getElementById("ddThemeText");
  const elLogout = document.getElementById("ddLogoutText");
  if (elTheme) elTheme.textContent = TEXT.dropdownTheme;
  if (elLogout) elLogout.textContent = TEXT.dropdownLogout;

  const elPageTitle = document.getElementById("pageTitle");
  if (elPageTitle) elPageTitle.textContent = TEXT.pageTitleGlobalSheets;

  const descEl = document.getElementById("pageDesc");
  if (descEl) descEl.textContent = TEXT.brandDescPrefix + brandDisplayName(activeBrand) + ".";

  const formTitle = document.getElementById("formTitle");
  if (formTitle) formTitle.textContent = TEXT.formTitle;

  const lblSheetName = document.getElementById("lblSheetName");
  const lblSheetNameHint = document.getElementById("lblSheetNameHint");
  const lblSid = document.getElementById("lblSid");
  const lblSidReq = document.getElementById("lblSidReq");
  const lblGid = document.getElementById("lblGid");
  const lblGidOpt = document.getElementById("lblGidOpt");

  if (lblSheetName) lblSheetName.textContent = TEXT.fieldSheetName;
  if (lblSheetNameHint) lblSheetNameHint.textContent = TEXT.fieldSheetNameHint;
  if (lblSid) lblSid.textContent = TEXT.fieldSpreadsheetId;
  if (lblSidReq) lblSidReq.textContent = TEXT.fieldSpreadsheetReq;
  if (lblGid) lblGid.textContent = TEXT.fieldGid;
  if (lblGidOpt) lblGidOpt.textContent = TEXT.fieldGidOpt;

  const btnSaveText = document.getElementById("btnSaveText");
  const btnClearText = document.getElementById("btnClearText");
  if (btnSaveText) btnSaveText.textContent = TEXT.btnSave;
  if (btnClearText) btnClearText.textContent = TEXT.btnClear;

  const thName = document.getElementById("thName");
  const thSid = document.getElementById("thSid");
  const thGid = document.getElementById("thGid");
  const thAction = document.getElementById("thAction");
  if (thName) thName.textContent = TEXT.tableName;
  if (thSid) thSid.textContent = TEXT.tableSid;
  if (thGid) thGid.textContent = TEXT.tableGid;
  if (thAction) thAction.textContent = TEXT.tableAction;

  const tabLblBankDepo = document.getElementById("tabLblBankDepo");
  const tabLblEwallet  = document.getElementById("tabLblEwallet");
  const tabLblPulsa    = document.getElementById("tabLblPulsa");
  const tabLblBankWd   = document.getElementById("tabLblBankWd");
  if (tabLblBankDepo) tabLblBankDepo.textContent = TEXT.catBankDepo;
  if (tabLblEwallet)  tabLblEwallet.textContent  = TEXT.catEwallet;
  if (tabLblPulsa)    tabLblPulsa.textContent    = TEXT.catPulsa;
  if (tabLblBankWd)   tabLblBankWd.textContent   = TEXT.catBankWd;

  if (tableTitlePrefixEl) tableTitlePrefixEl.textContent = TEXT.tableTitlePrefix;

  const modalTitleText = document.getElementById("modalTitleText");
  const modalLblCategory = document.getElementById("modalLblCategory");
  const modalLblName = document.getElementById("modalLblName");
  const modalLblNameHint = document.getElementById("modalLblNameHint");
  const modalLblSid = document.getElementById("modalLblSid");
  const modalLblSidReq = document.getElementById("modalLblSidReq");
  const modalLblGid = document.getElementById("modalLblGid");
  const modalLblGidOpt = document.getElementById("modalLblGidOpt");
  const modalBtnCancelText = document.getElementById("modalBtnCancelText");
  const modalBtnSaveText = document.getElementById("modalBtnSaveText");

  if (modalTitleText) modalTitleText.textContent = TEXT.modalTitleEdit;
  if (modalLblCategory) modalLblCategory.textContent = TEXT.modalFieldCategory;
  if (modalLblName) modalLblName.textContent = TEXT.modalFieldName;
  if (modalLblNameHint) modalLblNameHint.textContent = TEXT.modalFieldNameHint;
  if (modalLblSid) modalLblSid.textContent = TEXT.modalFieldSpreadsheetId;
  if (modalLblSidReq) modalLblSidReq.textContent = TEXT.fieldSpreadsheetReq;
  if (modalLblGid) modalLblGid.textContent = TEXT.modalFieldGid;
  if (modalLblGidOpt) modalLblGidOpt.textContent = TEXT.fieldGidOpt;
  if (modalBtnCancelText) modalBtnCancelText.textContent = TEXT.modalCancel;
  if (modalBtnSaveText) modalBtnSaveText.textContent = TEXT.modalSave;
}

async function init() {
  const session = await requireSession();
  const usernameText = session.username || "admin";
  const isSuperadmin  = (session.role === "superadmin");

  // ✅ superadmin dapat semua scope termasuk notifikasi
  const userScopes    = isSuperadmin
    ? { brand:true, proses:true, laporan:true, autowd:true, users:true, notifikasi:true }
    : (session.scopes || DEFAULT_SCOPES);

  document.getElementById("topUser").textContent = usernameText;

  if (!isSuperadmin && !userScopes.brand) {
    showFlash("err", "Akses ditolak: Anda tidak memiliki scope 'brand'.");
    setTimeout(()=>{ window.location = `index.html?brand=${activeBrand}`; }, 1200);
    return;
  }

  const brandInfo = brandMap[activeBrand] || brandMap["tiara"];
  const brandNameBadge = brandInfo.badge;
  document.getElementById("brandLabel").textContent = brandNameBadge;
  document.getElementById("brandBadge").textContent = brandNameBadge;

  const logoSrc = brandLogoMap[activeBrand] || brandLogoMap.tiara;
  const desktopLogo = document.getElementById("desktopBrandLogo");
  const mobileLogo  = document.getElementById("mobileBrandLogo");
  if (desktopLogo) {
    desktopLogo.src = logoSrc;
    desktopLogo.alt = brandNameBadge;
  }
  if (mobileLogo) {
    mobileLogo.src = logoSrc;
    mobileLogo.alt = brandNameBadge;
  }

  applyStaticTexts();

  const sideHTMLDesktop = renderSidebar(activeBrand, "Desktop", activeChannel, { isSuperadmin, scopes: userScopes });
  const sideHTMLMobile  = renderSidebar(activeBrand, "Mobile",  activeChannel, { isSuperadmin, scopes: userScopes });
  document.getElementById("sideMenuDesktop").innerHTML = sideHTMLDesktop;
  document.getElementById("sideMenuMobile").innerHTML  = sideHTMLMobile;

  attachSidebarToggle("Desktop");
  attachSidebarToggle("Mobile");

  attachCategoryTabs();
  renderCategoryTabs();

  updateSidebarClock();
  setInterval(updateSidebarClock, 1000);

  await loadData();
}

init();