(() => {
  const mount = document.getElementById("appMenu");
  if (!mount) return;

  const base = (window.MENU_BASE) ? window.MENU_BASE : ".."; // porque dashboard está en /pages
  const page = document.body.dataset.page || "";

  const userRaw = sessionStorage.getItem("fp_user");
  let user = null;
  try {
    user = userRaw ? JSON.parse(userRaw) : null;
  } catch (e) {
    user = null;
  }

  function normalizeRole(rol) {
    rol = String(rol || "").toLowerCase().trim().replaceAll("_", " ").replace(/\s+/g, "-");
    if (["admin", "administrador"].includes(rol)) return "administrador";
    if (rol === "digitador") return "digitador";
    if (["digitador-terreno", "terreno"].includes(rol)) return "digitador-terreno";
    if (["monitor", "lectura", "solo-lectura", "readonly", "read-only"].includes(rol)) return "monitor";
    if (rol === "supervisor") return "digitador"; // compatibilidad antigua
    return "digitador";
  }

  const rol = normalizeRole(user?.rol || user?.rol_funcionario || "");
  const isAdmin = rol === "administrador";
  const isMonitor = rol === "monitor";

  const allPages = [
    "dashboard",
    "busqueda",
    "instrumentos",
    "familias",
    "vivienda",
    "usuarios", // Personas
    "reportes",
    "geolocalizacion",
    "geolocalizacion-comunitaria",
    "configuracion",
  ];

  const rolePages = {
    administrador: allPages,
    // Rol existente: mantiene Dashboard, Personas, Reportes y Geolocalización + se suma Familias.
    digitador: ["dashboard", "usuarios", "familias", "reportes", "geolocalizacion", "geolocalizacion-comunitaria"],
    // Rol nuevo: trabajo en terreno, sin Personas ni Configuración.
    "digitador-terreno": ["dashboard", "busqueda", "instrumentos", "familias", "vivienda", "reportes", "geolocalizacion", "geolocalizacion-comunitaria"],
    // Rol nuevo: todo menos Configuración, pero solo lectura.
    monitor: ["dashboard", "busqueda", "instrumentos", "familias", "vivienda", "usuarios", "reportes", "geolocalizacion", "geolocalizacion-comunitaria"],
  };

  const allowedPages = rolePages[rol] || ["dashboard"];

  // Guard simple: si no hay sesión, vuelve a login
  if (!user) {
    window.location.href = `${base}/index.html`;
    return;
  }

  // Control visual y de navegación por rol.
  if (!allowedPages.includes(page)) {
    document.querySelector("main")?.remove();

    const goDashboard = () => { window.location.href = `${base}/pages/dashboard.html`; };
    const message = page === "configuracion"
      ? "La configuración solo está disponible para el rol administrador."
      : `Tu rol (${roleLabel(rol)}) no tiene acceso a este módulo.`;

    if (window.Swal) {
      Swal.fire({
        icon: "warning",
        title: "Acceso restringido",
        text: message,
        confirmButtonText: "Ir al dashboard",
        allowOutsideClick: false,
      }).then(goDashboard);
    } else {
      alert(message);
      goDashboard();
    }
    return;
  }

  const menuItems = [
    { id: "dashboard", icon: "bi-speedometer2", label: "Dashboard", href: `${base}/pages/dashboard.html` },
    { id: "instrumentos", icon: "bi-file-earmark-text", label: "Instrumentos", href: `${base}/pages/instrumentos.html`},
    { id: "busqueda", icon: "bi-search", label: "Búsqueda", href: `${base}/pages/busqueda.html` },
    { id: "familias", icon: "bi-people", label: "Familias", href: `${base}/pages/familias.html` },
    { id: "vivienda", icon: "bi-house", label: "Vivienda", href: `${base}/pages/vivienda.html` },
    { id: "usuarios", icon: "bi-person", label: "Personas", href: `${base}/pages/personas.html` },
    { id: "reportes", icon: "bi-bar-chart", label: "Reportes", href: `${base}/pages/reportes.html` },
    { id: "geolocalizacion", icon: "bi-geo-alt", label: "Geolocalización", href: `${base}/pages/geolocalizacion.html` },
    { id: "geolocalizacion-comunitaria", icon: "bi-map", label: "Geo Comunitaria", href: `${base}/pages/geolocalizacion-comunitaria.html` },
    { id: "configuracion", icon: "bi-gear", label: "Configuración", href: `${base}/pages/configuracion.html` }
  ];

  const visibleMenuItems = menuItems.filter(it => allowedPages.includes(it.id));

  const navLinks = visibleMenuItems.map(it => `
    <a class="nav-link fp-nav ${it.id === page ? "active" : ""}" href="${it.href}" data-nav="${it.id}">
      <i class="bi ${it.icon}"></i>
      <span>${it.label}</span>
    </a>
  `).join("");

  if (isMonitor) {
    document.body.classList.add("fp-monitor-readonly");
    installMonitorReadOnlyGuard();
  }

  mount.innerHTML = `
    <!-- Topbar -->
    <header class="topbar">
      <div class="container-fluid d-flex align-items-center justify-content-between gap-2 py-2">
        <div class="d-flex align-items-center gap-2">
          <button class="btn btn-icon d-none d-lg-inline-flex" id="btnSidebarToggle" type="button" title="Ocultar menú lateral" aria-label="Ocultar menú lateral">
            <i class="bi bi-list"></i>
          </button>
          <button class="btn btn-icon d-lg-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#fpOffcanvas" title="Abrir menú" aria-label="Abrir menú">
            <i class="bi bi-list"></i>
          </button>
          <div class="brand">
            <div class="brand-title">Familia Panquehue</div>
            <div class="brand-sub">Barrido Territorial</div>
          </div>
        </div>

        <div class="d-flex align-items-center gap-2">
          ${isMonitor ? `<span class="badge rounded-pill text-bg-warning d-none d-md-inline-flex align-items-center gap-1"><i class="bi bi-eye"></i> Solo lectura</span>` : ""}
          <div class="userpill">
            <i class="bi bi-person-circle"></i>
            <div class="d-none d-sm-block">
              <div class="u-name">${escapeHtml(user.nombre || "Usuario")}</div>
              <div class="u-role">${escapeHtml(roleLabel(rol))}</div>
            </div>
          </div>

          <button class="btn btn-outline-danger btn-sm" id="btnLogout">
            <i class="bi bi-box-arrow-right"></i>
            <span class="d-none d-sm-inline">Salir</span>
          </button>
        </div>
      </div>
    </header>

    <!-- Sidebar (desktop) -->
    <aside class="fp-sidebar d-none d-lg-flex">
      <div class="fp-side-inner">
        <div class="fp-side-logos">
          <img src="${base}/img/logo-muni.png" alt="Municipalidad" />
          <img src="${base}/img/logo-cesfam.png" alt="CESFAM" />
        </div>

        <nav class="fp-navlist">
          ${navLinks}
        </nav>

        <div class="fp-side-foot small text-muted">
          Desarrollado por Rodolfo Reyes · ${new Date().getFullYear()}
        </div>
      </div>
    </aside>

    <!-- Offcanvas (mobile/tablet) -->
    <div class="offcanvas offcanvas-start" tabindex="-1" id="fpOffcanvas">
      <div class="offcanvas-header">
        <div>
          <div class="fw-bold">Familia Panquehue</div>
          <div class="small text-muted">Menú</div>
        </div>
        <button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
      </div>

      <div class="offcanvas-body">
        <div class="fp-side-logos mb-3">
          <img src="${base}/img/logo-muni.png" alt="Municipalidad" />
          <img src="${base}/img/logo-cesfam.png" alt="CESFAM" />
        </div>

        ${isMonitor ? `<div class="alert alert-warning py-2 small"><i class="bi bi-eye"></i> Rol monitor: solo lectura.</div>` : ""}

        <nav class="fp-navlist">
          ${navLinks}
        </nav>

        <hr>
        <button class="btn btn-outline-danger w-100" id="btnLogoutMobile">
          <i class="bi bi-box-arrow-right"></i> Salir
        </button>
      </div>
    </div>
  `;

  const doLogout = async () => {
    const res = await Swal.fire({
      icon: "warning",
      title: "¿Cerrar sesión?",
      text: "¿Deseas salir de la plataforma?",
      showCancelButton: true,
      confirmButtonText: "Sí, salir",
      cancelButtonText: "Cancelar",
      reverseButtons: true,
      allowOutsideClick: false,
    });

    if (!res.isConfirmed) return;

    try {
      await fetch(`${base}/php/auth/logout.php`, {
        method: "POST",
        credentials: "same-origin",
        cache: "no-store",
      }).catch(() => null);
    } finally {
      sessionStorage.removeItem("fp_user");
      window.location.href = `${base}/index.html`;
    }
  };

  document.getElementById("btnLogout")?.addEventListener("click", doLogout);
  document.getElementById("btnLogoutMobile")?.addEventListener("click", doLogout);

  const sidebarToggle = document.getElementById("btnSidebarToggle");
  const SIDEBAR_KEY = "fp_sidebar_collapsed";

  function applySidebarState() {
    const collapsed = localStorage.getItem(SIDEBAR_KEY) === "1";
    document.body.classList.toggle("sidebar-collapsed", collapsed);

    if (sidebarToggle) {
      sidebarToggle.title = collapsed ? "Mostrar menú lateral" : "Ocultar menú lateral";
      sidebarToggle.setAttribute("aria-label", sidebarToggle.title);
      sidebarToggle.innerHTML = collapsed
        ? '<i class="bi bi-layout-sidebar-inset"></i>'
        : '<i class="bi bi-list"></i>';
    }

    setTimeout(() => {
      window.dispatchEvent(new Event("resize"));
      document.dispatchEvent(new CustomEvent("fp:sidebar-toggle", { detail: { collapsed } }));
    }, 180);
  }

  sidebarToggle?.addEventListener("click", () => {
    const next = localStorage.getItem(SIDEBAR_KEY) === "1" ? "0" : "1";
    localStorage.setItem(SIDEBAR_KEY, next);
    applySidebarState();
  });

  applySidebarState();

  function roleLabel(value) {
    return ({
      administrador: "administrador",
      digitador: "digitador",
      "digitador-terreno": "digitador-terreno",
      monitor: "monitor",
    })[value] || "digitador";
  }

  function escapeHtml(str) {
    return String(str)
      .replaceAll("&", "&amp;")
      .replaceAll("<", "&lt;")
      .replaceAll(">", "&gt;")
      .replaceAll('"', "&quot;")
      .replaceAll("'", "&#039;");
  }

  function installMonitorReadOnlyGuard() {
    const writeButtonSelectors = [
      "#btnNuevaPersona",
      "#btnImportEstratificacion",
      "#btnImportPadron",
      "#btnImportPercapita",
      "#btnResetDemo",
      "#btnGuardar",
      "#btnEliminar",
      "#btnNuevo",
      "#btnGenCodigo",
      "#btnAddIntegrante",
      "#btnAddFamilia",
      "#btnCapturarGPS",
      "#btnGPS",
      "#btnUsarUbicacion",
      "#btnLimpiarTodo",
      "#btnQuitarFamilia",
      "#btnGuardarApgar",
      "#btnGuardarLT",
      "#btnGuardarCV",
      "#btnGuardarGen",
      "#btnAddLT",
      "#btnAddRel",
      "#btnLimpiarApgar",
      "#btnLimpiarLT",
      "#btnLimpiarCV",
      "#btnLimpiarGen",
      "#btnProcesarImportEstratificacion",
      "#btnProcesarImportPadron",
      "#btnProcesarImportPercapita",
      "#btnNuevoPunto",
      "#btnGuardarPunto",
      "#btnEliminarPunto",
      "#btnUsarCentroMapa",
      "#btnUsarMiUbicacion",
      "#btnLimpiarFormulario",
      "button[data-act^='edit']",
      "button[data-act^='del']",
      "button[data-act*='delete']",
      "button[data-act*='remove']",
      "button[data-edit]",
      "button[data-del]",
      "button.x[data-i]",
    ];

    const style = document.createElement("style");
    style.textContent = `
      body.fp-monitor-readonly ${writeButtonSelectors.join(", body.fp-monitor-readonly ")} {
        display: none !important;
      }
    `;
    document.head.appendChild(style);

    const isWriteAction = (el) => {
      const btn = el?.closest?.(writeButtonSelectors.join(","));
      if (btn) return true;
      const act = String(el?.closest?.("[data-act]")?.dataset?.act || "").toLowerCase();
      if (/^(edit|del|delete|remove|guardar|save|nuevo|new|add|import|procesar)/.test(act)) return true;
      return Boolean(el?.closest?.("button[data-edit],button[data-del],button.x[data-i]"));
    };

    document.addEventListener("click", (ev) => {
      if (!isWriteAction(ev.target)) return;
      ev.preventDefault();
      ev.stopPropagation();
      ev.stopImmediatePropagation();
      if (window.Swal) {
        Swal.fire({
          icon: "info",
          title: "Rol monitor: solo lectura",
          text: "Puedes buscar, filtrar, visualizar e imprimir reportes, pero no crear, modificar ni eliminar datos.",
          confirmButtonText: "Entendido"
        });
      }
    }, true);

    document.addEventListener("submit", (ev) => {
      ev.preventDefault();
      ev.stopPropagation();
      ev.stopImmediatePropagation();
      if (window.Swal) {
        Swal.fire("Solo lectura", "El rol monitor no puede guardar cambios.", "info");
      }
    }, true);
  }
})();
